Changeset 40030 in project


Ignore:
Timestamp:
04/19/21 06:05:03 (5 months ago)
Author:
Diego
Message:

srfi-197: clean up wiki formatting

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/5/srfi-197

    r39964 r40030  
     1[[toc:]]
     2
    13== srfi-197: Pipeline Operators
     4
    25=== Abstract
    3 Many functional languages provide pipeline operators, like Clojure's -> or OCaml's |>. Pipelines are a simple, terse, and readable way to write deeply-nested expressions. This SRFI defines a family of chain and nest pipeline operators, which can rewrite nested expressions like {{(a b (c d (e f g)))}} as a sequence of operations: {{(chain g (e f _) (c d _) (a b _))}}.
    4 
    5 For more information see: [[https://srfi.schemers.org/srfi-197/|197: Pipeline Operators]]
     6
     7Many functional languages provide pipeline operators, like Clojure's {{->}} or
     8OCaml's {{|>}}. Pipelines are a simple, terse, and readable way to write
     9deeply-nested expressions. This SRFI defines a family of {{chain}} and {{nest}}
     10pipeline operators, which can rewrite nested expressions like {{(a b (c d (e f
     11g)))}} as a sequence of operations: {{(chain g (e f _) (c d _) (a b _))}}.
     12
     13For more information see:
     14[[https://srfi.schemers.org/srfi-197/|197: Pipeline Operators]]
     15
    616=== Rationale
    7 Deeply-nested expressions are a common problem in all functional languages, especially Lisps. Excessive nesting can result in deep indentation and parenthesis-matching
    8 errors.
     17
     18Deeply-nested expressions are a common problem in all functional languages,
     19especially Lisps. Excessive nesting can result in deep indentation and
     20parenthesis-matching errors.
    921
    1022<enscript highlight="scheme">
     
    1325</enscript>
    1426
    15 Additionally, some expressions sound more natural when written inside out, as a sequence of steps from start to finish.
     27Additionally, some expressions sound more natural when written inside out, as a
     28sequence of steps from start to finish.
    1629
    1730<enscript highlight="scheme">
     
    2033</enscript>
    2134
    22 Many functional languages solve this by introducing pipeline operators. This SRFI defines a chain operator inspired by Clojure's threading macros, but with _ as an
    23 argument placeholder, a notation also used in SRFI 156.
     35Many functional languages solve this by introducing pipeline operators. This
     36SRFI defines a {{chain}} operator inspired by Clojure's threading macros, but
     37with {{_}} as an argument placeholder, a notation also used in SRFI 156.
    2438
    2539<enscript highlight="scheme">
     
    4458</enscript>
    4559
    46 Scheme already provides an idiomatic way to chain expressions in let* and SRFI 2 {{and-let*}}, but the primary advantage of chain is terseness and the accompanying
    47 readability. This focus on readability and reduced nesting is similar in spirit to SRFI 156 and SRFI 26.
    48 
    49 Compared to an equivalent {{let*}} expression, chain removes two levels of parenthesis nesting, does not define any intermediate variables, and allows mixing single and
    50 multiple return values.
    51 
    52 To demonstrate the difference in verbosity, here is the let* equivalent of the recipe expression:
     60Scheme already provides an idiomatic way to chain expressions in {{let*}} and
     61SRFI 2 {{and-let*}}, but the primary advantage of {{chain}} is terseness and
     62the accompanying readability. This focus on readability and reduced nesting is
     63similar in spirit to SRFI 156 and SRFI 26.
     64
     65Compared to an equivalent {{let*}} expression, {{chain}} removes two levels of
     66parenthesis nesting, does not define any intermediate variables, and allows
     67mixing single and multiple return values.
     68
     69To demonstrate the difference in verbosity, here is the {{let*}} equivalent of the
     70recipe expression:
    5371
    5472<enscript highlight="scheme">
     
    6280</enscript>
    6381
    64 Like let*, chain guarantees evaluation order. In fact, {{(chain a (b _) (c _))}} expands to something like {{(let* ((x (b a)) (x (c x))) x)}}, not {{(c (b a))}}, and so chain is not suitable for pipelines containing syntax like if or let.
    65 
    66 For pipelines containing complex syntax, the nest and nest-reverse operators look like chain but are guaranteed to expand to nested forms, not let* forms. nest nests in the opposite direction of chain, so {{(nest (a _) (b _) c)}} expands to {{(a (b c))}}.
     82Like {{let*}}, chain guarantees evaluation order. In fact, {{(chain a (b _) (c
     83_))}} expands to something like {{(let* ((x (b a)) (x (c x))) x)}}, not {{(c (b
     84a))}}, and so {{chain}} is not suitable for pipelines containing syntax like
     85{{if}} or {{let}}.
     86
     87For pipelines containing complex syntax, the {{nest}} and {{nest-reverse}}
     88operators look like {{chain}} but are guaranteed to expand to nested forms, not
     89{{let*}} forms. {{nest}} nests in the opposite direction of {{chain}}, so
     90{{(nest (a _) (b _) c)}} expands to {{(a (b c))}}.
     91
    6792=== Specification
     93
    6894==== chain
    6995
    7096<procedure>(chain <initial-value> [<placeholder> [<ellipsis>]] <step> ...)</procedure>
    7197
    72 ==== Syntax
    73 
    74 <parameter><initial-value></parameter>
    75 
    76 {{<initial-value>}} is an expression.
    77 
    78 
    79 <parameter><placeholder></parameter>
    80 
    81 
    82 <parameter><ellipsis></parameter>
    83 
    84 
    85 {{<placeholder>}} and {{<ellipsis>}} are literal symbols; these are the placeholder symbol and ellipsis symbol. If {{<placeholder>}} or {{<ellipsis>}} are not present, they default to _ and ..., respectively.
    86 
    87 <parameter><step></parameter>
    88 
    89 The syntax of {{<step>}} is (<datum> ...), where each {{<datum>}} is either the placeholder symbol, the ellipsis symbol, or an expression. A {{<step>}} must contain at least one {{<datum>}}. The ellipsis symbol is only allowed at the end of a {{<step>}}, and it must immediately follow a placeholder symbol.
    90 ==== Semantics
    91 chain evaluates each {{<step>}} in order from left to right, passing the result of each step to the next.
    92 
    93 Each {{<step>}} is evaluated as an application, and the return value(s) of that application are passed to the next step as its pipeline values. {{<initial-value>}} is the pipeline value of the first step. The return value(s) of chain are the return value(s) of the last step.
    94 
    95 The placeholder symbols in each {{<step>}} are replaced with that step's pipeline values, in the order they appear. It is an error if the number of placeholders for a step does not equal the number of pipeline values for that step, unless the step contains no placeholders, in which case it will ignore its pipeline values.
     98{{chain}} evaluates each {{<step>}} in order from left to right, passing the result
     99of each step to the next.
     100
     101{{<initial-value>}} is an expression. {{<placeholder>}} and {{<ellipsis>}} are
     102literal symbols; these are the placeholder symbol and ellipsis symbol. If
     103{{<placeholder>}} or {{<ellipsis>}} are not present, they default to {{_}} and
     104{{...}}, respectively.
     105
     106The syntax of {{<step>}} is {{(<datum> ...)}}, where each {{<datum>}} is either
     107the placeholder symbol, the ellipsis symbol, or an expression. A {{<step>}}
     108must contain at least one {{<datum>}}. The ellipsis symbol is only allowed at
     109the end of a {{<step>}}, and it must immediately follow a placeholder symbol.
     110
     111Each {{<step>}} is evaluated as an application, and the return value(s) of that
     112application are passed to the next step as its pipeline values.
     113{{<initial-value>}} is the pipeline value of the first step. The return
     114value(s) of {{chain}} are the return value(s) of the last step.
     115
     116The placeholder symbols in each {{<step>}} are replaced with that step's
     117pipeline values, in the order they appear. It is an error if the number of
     118placeholders for a step does not equal the number of pipeline values for that
     119step, unless the step contains no placeholders, in which case it will ignore
     120its pipeline values.
    96121
    97122<enscript highlight="scheme">
     
    101126</enscript>
    102127
    103 If a {{<step>}} ends with a placeholder symbol followed by an ellipsis symbol, that placeholder sequence is replaced with all remaining pipeline values that do not have a matching placeholder.
     128If a {{<step>}} ends with a placeholder symbol followed by an ellipsis symbol,
     129that placeholder sequence is replaced with all remaining pipeline values that
     130do not have a matching placeholder.
    104131
    105132<enscript highlight="scheme">
     
    108135</enscript>
    109136
    110 chain and all other SRFI 197 macros support custom placeholder symbols, which can help to preserve hygiene when used in the body of a syntax definition that may insert a {{_}} or {{...}}.
     137{{chain}} and all other SRFI 197 macros support custom placeholder symbols,
     138which can help to preserve hygiene when used in the body of a syntax definition
     139that may insert a {{_}} or {{...}}.
    111140
    112141<enscript highlight="scheme">
     
    116145; => (let*-values (((x1 . x2) (a)) ((x) (apply b x1 c x2))) (d x))
    117146</enscript>
     147
    118148==== chain-and
    119149
    120150<procedure>(chain-and <initial-value> [<placeholder>] <step> ...)</procedure>
    121151
    122 ===== Syntax
    123 
    124 <parameter><initial-value></parameter>
    125 
    126 {{<initial-value>}} is an expression.
    127 
    128 
    129 <parameter><placeholder></parameter>
    130 
    131 {{<placeholder>}} is a literal symbol; this is the placeholder symbol. If {{<placeholder>}} is not present, the placeholder symbol is {{_}}.
    132 
    133 
    134 <parameter><step></parameter>
    135 
    136 The syntax of {{<step>}} is (<datum> ... [<_> <datum> ...]), where {{<_>}} is the placeholder symbol.
    137 ===== Semantics
    138 A variant of chain that short-circuits and returns {{#f}} if any step returns {{#f}}. chain-and is to chain as SRFI 2 {{and-let*}} is to {{let*}}.
    139 
    140 Each {{<step>}} is evaluated as an application. If the step evaluates to {{#f}}, the remaining steps are not evaluated, and chain-and returns {{#f}}. Otherwise, the return value of the step is passed to the next step as its pipeline value. {{<initial-value>}} is the pipeline value of the first step. If no step evaluates to {{#f}}, the return value of chain-and is the return value of the last step.
    141 
    142 The {{<_>}} placeholder in each {{<step>}} is replaced with that step's pipeline value. If a {{<step>}} does not contain {{<_>}}, it will ignore its pipeline value, but chain-and will still check whether that pipeline value is {{#f}}.
    143 
    144 Because chain-and checks the return value of each step, it does not support steps with multiple return values. It is an error if a step returns more than one value.
     152A variant of {{chain}} that short-circuits and returns {{#f}} if any step
     153returns {{#f}}. {{chain-and}} is to chain as SRFI 2 {{and-let*}} is to
     154{{let*}}.
     155
     156{{<initial-value>}} is an expression. {{<placeholder>}} is a literal symbol;
     157this is the placeholder symbol. If {{<placeholder>}} is not present, the
     158placeholder symbol is {{_}}.
     159
     160The syntax of {{<step>}} is {{(<datum> ... [<_> <datum> ...])}}, where {{<_>}}
     161is the placeholder symbol.
     162
     163Each {{<step>}} is evaluated as an application. If the step evaluates to
     164{{#f}}, the remaining steps are not evaluated, and {{chain-and}} returns
     165{{#f}}. Otherwise, the return value of the step is passed to the next step as
     166its pipeline value. {{<initial-value>}} is the pipeline value of the first
     167step. If no step evaluates to {{#f}}, the return value of {{chain-and}} is the
     168return value of the last step.
     169
     170The {{<_>}} placeholder in each {{<step>}} is replaced with that step's
     171pipeline value. If a {{<step>}} does not contain {{<_>}}, it will ignore its
     172pipeline value, but {{chain-and}} will still check whether that pipeline value is
     173{{#f}}.
     174
     175Because {{chain-and}} checks the return value of each step, it does not support
     176steps with multiple return values. It is an error if a step returns more than
     177one value.
     178
    145179==== chain-when
    146180
    147181<procedure>(chain-when <initial-value> [<placeholder>] ([<guard>] <step>) ...)</procedure>
    148182
    149 ===== Syntax
    150 {{<initial-value>}} and {{<guard>}} are expressions. {{<placeholder>}} is a literal symbol; this is the placeholder symbol. If {{<placeholder>}} is not present, the placeholder symbol is _. The syntax of {{<step>}} is (<datum> ... [<_> <datum> ...]), where {{<_>}} is the placeholder symbol.
    151 ===== Semantics
    152 A variant of chain in which each step has a guard expression and will be skipped if the guard expression evaluates to {{#f}}.
    153 ===== Example
     183A variant of {{chain}} in which each step has a guard expression and will be
     184skipped if the guard expression evaluates to {{#f}}.
     185
     186{{<initial-value>}} and {{<guard>}} are expressions. {{<placeholder>}} is a
     187literal symbol; this is the placeholder symbol. If {{<placeholder>}} is not
     188present, the placeholder symbol is {{_}}. The syntax of {{<step>}} is
     189{{(<datum> ... [<_> <datum> ...])}}, where {{<_>}} is the placeholder symbol.
     190
    154191<enscript highlight="scheme">
    155192(define (describe-number n)
     
    163200(describe-number 4) ; => '("positive" "even")
    164201</enscript>
    165 ===== Description
    166 Each {{<step>}} is evaluated as an application. The return value of the step is passed to the next step as its pipeline value. {{<initial-value>}} is the pipeline value of the first step.
    167 
    168 The {{<_>}} placeholder in each {{<step>}} is replaced with that step's pipeline value. If a {{<step>}} does not contain {{<_>}}, it will ignore its pipeline value
    169 
    170 If a step's {{<guard>}} is present and evaluates to {{#f}}, that step will be skipped, and its pipeline value will be reused as the pipeline value of the next step. The return value of chain-when is the return value of the last non-skipped step, or {{<initial-value>}} if all steps are skipped.
    171 
    172 Because chain-when may skip steps, it does not support steps with multiple return values. It is an error if a step returns more than one value.
     202
     203Each {{<step>}} is evaluated as an application. The return value of the step is
     204passed to the next step as its pipeline value. {{<initial-value>}} is the
     205pipeline value of the first step.
     206
     207The {{<_>}} placeholder in each {{<step>}} is replaced with that step's
     208pipeline value. If a {{<step>}} does not contain {{<_>}}, it will ignore its
     209pipeline value
     210
     211If a step's {{<guard>}} is present and evaluates to {{#f}}, that step will be
     212skipped, and its pipeline value will be reused as the pipeline value of the
     213next step. The return value of {{chain-when}} is the return value of the last
     214non-skipped step, or {{<initial-value>}} if all steps are skipped.
     215
     216Because {{chain-when}} may skip steps, it does not support steps with multiple
     217return values. It is an error if a step returns more than one value.
     218
    173219==== chain-lambda
    174220
    175221<procedure>(chain-lambda [<placeholder> [<ellipsis>]] <step> ...)</procedure>
    176222
    177 ===== Syntax
    178 
    179 <parameter><placeholder></parameter>
    180 
    181 
    182 <parameter><ellipsis></parameter>
    183 
    184 {{<placeholder>}} and {{<ellipsis>}} are literal symbols these are the placeholder symbol and ellipsis symbol. If {{<placeholder>}} or {{<ellipsis>}} are not present, they default to _ and ..., respectively.
    185 
    186 
    187 <parameter><step></parameter>
    188 
    189 The syntax of {{<step>}} is (<datum> ...), where each {{<datum>}} is either the placeholder symbol, the ellipsis symbol, or an expression. A {{<step>}} must contain at least one {{<datum>}}. The ellipsis symbol is only allowed at the end of a {{<step>}}, and it must immediately follow a placeholder symbol.
    190 ===== Semantics
    191 Creates a procedure from a sequence of chain steps. When called, a {{chain-lambda}} procedure evaluates each {{<step>}} in order from left to right, passing the result of each step to the next.
     223Creates a procedure from a sequence of chain steps. When called, a
     224{{chain-lambda}} procedure evaluates each {{<step>}} in order from left to
     225right, passing the result of each step to the next.
     226
     227{{<placeholder>}} and {{<ellipsis>}} are literal symbols these are the
     228placeholder symbol and ellipsis symbol. If {{<placeholder>}} or {{<ellipsis>}}
     229are not present, they default to {{_}} and {{...}}, respectively.
     230
     231The syntax of {{<step>}} is {{(<datum> ...)}}, where each {{<datum>}} is either
     232the placeholder symbol, the ellipsis symbol, or an expression. A {{<step>}}
     233must contain at least one {{<datum>}}. The ellipsis symbol is only allowed at
     234the end of a {{<step>}}, and it must immediately follow a placeholder symbol.
    192235
    193236<enscript highlight="scheme">
     
    196239</enscript>
    197240
    198 Each {{<step>}} is evaluated as an application, and the return value(s) of that application are passed to the next step as its pipeline values. The procedure's arguments are the pipeline values of the first step. The return value(s) of the procedure are the return value(s) of the last step.
    199 
    200 The placeholder symbols in each {{<step>}} are replaced with that step's pipeline values, in the order they appear. It is an error if the number of placeholders for a step does not equal the number of pipeline values for that step, unless the step contains no placeholders, in which case it will ignore its pipeline values.
    201 
    202 If a {{<step>}} ends with a placeholder symbol followed by an ellipsis symbol, that placeholder sequence is replaced with all remaining pipeline values that do not have a matching placeholder.
    203 
    204 The number of placeholders in the first {{<step>}} determines the arity of the procedure. If the first step ends with an ellipsis symbol, the procedure is variadic.
     241Each {{<step>}} is evaluated as an application, and the return value(s) of that
     242application are passed to the next step as its pipeline values. The procedure's
     243arguments are the pipeline values of the first step. The return value(s) of the
     244procedure are the return value(s) of the last step.
     245
     246The placeholder symbols in each {{<step>}} are replaced with that step's
     247pipeline values, in the order they appear. It is an error if the number of
     248placeholders for a step does not equal the number of pipeline values for that
     249step, unless the step contains no placeholders, in which case it will ignore
     250its pipeline values.
     251
     252If a {{<step>}} ends with a placeholder symbol followed by an ellipsis symbol,
     253that placeholder sequence is replaced with all remaining pipeline values that
     254do not have a matching placeholder.
     255
     256The number of placeholders in the first {{<step>}} determines the arity of the
     257procedure. If the first step ends with an ellipsis symbol, the procedure is
     258variadic.
     259
    205260==== nest
    206261
    207262<procedure>(nest [<placeholder>] <step> ... <initial-value>)</procedure>
    208263
    209 ===== Syntax
    210 
    211 <parameter><placeholder></parameter>
    212 
    213 {{<placeholder>}} is a literal symbol; this is the placeholder symbol. If {{<placeholder>}} is not present, the placeholder symbol is _. The syntax of {{<step>}} is {{(<datum> ... <_> <datum> ...)}}, where {{<_>}} is the placeholder symbol. {{<initial-value>}} is expression.
    214 ===== Semantics
    215 nest is similar to chain, but sequences its steps in the opposite order. Unlike chain, nest literally nests expressions; as a result, it does not provide the same strict evaluation order guarantees as chain.
     264{{nest}} is similar to {{chain}}, but sequences its steps in the opposite
     265order. Unlike chain, nest literally nests expressions; as a result, it does not
     266provide the same strict evaluation order guarantees as chain.
     267
     268{{<placeholder>}} is a literal symbol; this is the placeholder symbol. If
     269{{<placeholder>}} is not present, the placeholder symbol is {{_}}. The syntax
     270of {{<step>}} is {{(<datum> ... <_> <datum> ...)}}, where {{<_>}} is the
     271placeholder symbol. {{<initial-value>}} is expression.
    216272
    217273<enscript highlight="scheme">
     
    219275</enscript>
    220276
    221 A nest expression is evaluated by lexically replacing the {{<_>}} in the last {{<step>}} with {{<initial-value>}}, then replacing the {{<_>}} in the next-to-last {{<step>}} with that replacement, and so on until the {{<_>}} in the first {{<step>}} has been replaced. It is an error if the resulting final replacement is not an expression, which is then evaluated and its values are returned.
    222 
    223 Because it produces an actual nested form, nest can build expressions that chain cannot. For example, nest can build a quoted data structure:
     277A {{nest}} expression is evaluated by lexically replacing the {{<_>}} in the
     278last {{<step>}} with {{<initial-value>}}, then replacing the {{<_>}} in the
     279next-to-last {{<step>}} with that replacement, and so on until the {{<_>}} in
     280the first {{<step>}} has been replaced. It is an error if the resulting final
     281replacement is not an expression, which is then evaluated and its values are
     282returned.
     283
     284Because it produces an actual nested form, {{nest}} can build expressions that
     285chain cannot. For example, {{nest}} can build a quoted data structure:
    224286
    225287<enscript highlight="scheme">
     
    227289</enscript>
    228290
    229 nest can also safely include special forms like if, let, lambda, or parameterize in a pipeline.
     291{{nest}} can also safely include special forms like {{if}}, {{let}},
     292{{lambda}}, or {{parameterize}} in a pipeline.
    230293
    231294A custom placeholder can be used to safely nest nest expressions.
     
    237300; => '(1 2 3 (4 5 6))
    238301</enscript>
     302
    239303==== nest-reverse
    240304
    241305<procedure>(nest-reverse <initial-value> [<placeholder>] <step> ...)</procedure>
    242306
    243 ===== Syntax
    244 
    245 <parameter><initial-value></parameter>
    246 
    247 {{<initial-value>}} is an expression. {{<placeholder>}} is a literal symbol; this is the placeholder symbol. If {{<placeholder>}} is not present, the placeholder symbol is _.
    248 
    249 The syntax of {{<step>}} is (<datum> ... <_> <datum> ...), where {{<_>}} is the placeholder symbol.
    250 ===== Semantics
    251 nest-reverse is variant of nest that nests in reverse order, which is the same order as chain.
     307nest-reverse is variant of nest that nests in reverse order, which is the same
     308order as chain.
     309
     310{{<initial-value>}} is an expression. {{<placeholder>}} is a literal symbol;
     311this is the placeholder symbol. If {{<placeholder>}} is not present, the
     312placeholder symbol is {{_}}.
     313
     314The syntax of {{<step>}} is {{(<datum> ... <_> <datum> ...)}}, where {{<_>}} is
     315the placeholder symbol.
    252316
    253317<enscript highlight="scheme">
     
    255319</enscript>
    256320
    257 A nest-reverse expression is evaluated by lexically replacing the {{<_>}} in the first {{<step>}} with {{<initial-value>}}, then replacing the {{<_>}} in the second {{<step>}} with that replacement, and so on until the {{<_>}} in the last {{<step>}} has been replaced. It is an error if the resulting final replacement is not an expression, which is then evaluated and its values are returned.
    258 === Implementation
    259 A sample implementation is available on GitHub. This repository contains two portable SRFI 197 implementations, one in R7RS-small and syntax-rules, the other in R6RS and syntax-case. The only dependency of either implementation is SRFI 2. It includes an R7RS library wrapper and a test script.
    260 === Acknowledgements
    261 Thanks to the participants in the SRFI 197 mailing list who helped me refine this SRFI, including Marc Nieper-Wißkirchen, Linus Björnstam, Shiro Kawai, Lassi Kortela, and John Cowan.
    262 
    263 Marc provided a paragraph that has been included (with only minor changes) in the Semantics section of the nest and nest-reverse macros.
    264 
    265 Thanks to Rich Hickey for Clojure and the original implementation of Clojure threading macros, and to Paulus Esterhazy for the (EPL licensed) threading macros
    266 documentation page, which was a source of inspiration and some of the examples in this document.
     321A nest-reverse expression is evaluated by lexically replacing the {{<_>}} in
     322the first {{<step>}} with {{<initial-value>}}, then replacing the {{<_>}} in
     323the second {{<step>}} with that replacement, and so on until the {{<_>}} in the
     324last {{<step>}} has been replaced. It is an error if the resulting final
     325replacement is not an expression, which is then evaluated and its values are
     326returned.
     327
    267328=== Author
    268 Adam Nelson. Ported to Chicken Scheme 5 by Sergey Goldgaber.  Maintained by Diego A. Mundo.
     329
     330Adam Nelson
     331
     332=== Maintainer
     333
     334[[diego-mundo|Diego A. Mundo]]
     335
     336Ported to CHICKEN 5 by Sergey Goldgaber
    269337
    270338=== Repository
     
    272340[[https://code.dieggsy.com/srfi-197|https://code.dieggsy.com/srfi-197]]
    273341
    274 
    275 === Copyright
    276 Â© 2020 Adam Nelson.
    277 
    278 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
    279 
    280 The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
    281 
    282 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     342=== License
     343
     344 Â© 2020 Adam Nelson.
     345 
     346 Permission is hereby granted, free of charge, to any person obtaining a copy
     347 of this software and associated documentation files (the "Software"), to deal
     348 in the Software without restriction, including without limitation the rights
     349 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     350 copies of the Software, and to permit persons to whom the Software is
     351 furnished to do so, subject to the following conditions:
     352 
     353 The above copyright notice and this permission notice (including the next
     354 paragraph) shall be included in all copies or substantial portions of the
     355 Software.
     356 
     357 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     358 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     359 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     360 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     361 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     362 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     363 SOFTWARE.
     364
    283365=== Version history
    284 * [[https://github.com/diamond-lizard/srfi-197/releases/tag/0.1|0.1]] - Ported to Chicken Scheme 5
     366
     367; 0.1 : Ported to CHICKEN 5
Note: See TracChangeset for help on using the changeset viewer.