github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/gen/parser/lambda_doc.yaml (about)

     1  - DocumentID: lambda
     2    Title: >-
     3       `[{ Lambda }]`
     4    CategoryID: parser
     5    Summary: >-
     6      Iterate through structured data
     7    Description: |-
     8      Lambdas, in Murex, are a concise way of performing various actions against
     9      structured data. They're a convenience tool to range over arrays and objects,
    10      similar to `foreach` and `formap`.
    11  
    12      ### Etiquette
    13  
    14      The intention of lambdas isn't to be used liberally within shell scripts but
    15      rather than allow for more efficient one liners when performing quick, often
    16      one-off, tasks in the interactive terminal. The terse syntax for lambdas
    17      combined with it's adaptive functionality allow for flexibility when using,
    18      albeit at the potential cost of readability.
    19  
    20      For shell scripts where error handling, readability, and maintainability are a
    21      concern, more conventional iteration blocks like `foreach` and `formap` are
    22      recommended.
    23  
    24      The reason lambda variables (known as **meta values** are single characters
    25      also falls in line with this vision: they're terse to make one-liners
    26      convenient and to discourage shell script usage.
    27  
    28      ### Technical
    29  
    30      Code running inside a lambda inherit a special variable, named **meta values**,
    31      which hold the state for each iteration (see section below).
    32  
    33      Lambdas will adapt its return value depending on the nature of the code it's
    34      executing.
    35  
    36      #### Filter
    37  
    38      If your code returns a boolean data type, eg `[{$.v =~ "foobar"}]`, then the
    39      lambda will filter that list or map, only returning values that match `true`,
    40      discarding the others.
    41  
    42      #### Update
    43  
    44      If the **meta value** `v` (value) is updated then the lambda output reflects
    45      that change.
    46  
    47      The **meta value** `k` (key) works similarly for maps / objects too. However
    48      updating it in arrays and lists currently does nothing.
    49  
    50      This cannot be used in combination with **output**.
    51  
    52      #### Output
    53  
    54      If STDOUT isn't empty, then STDOUT is outputted rather than the object being
    55      filtered and/or updated.
    56  
    57      This usage most closely resembles `foreach` and `formap` except that the data
    58      type of STDOUT is not preserved.
    59    Examples: |-
    60      #### Filter
    61  
    62      Filtering a map:
    63  
    64      ```
    65      » %{hello: world, foo: bar} -> [{$.v == "world"}]
    66      {
    67          "hello": "world"
    68      }
    69      ```
    70  
    71      Filtering an array:
    72  
    73      In this example we return the days of the week excluding todays day (in this
    74      example, today is Friday)
    75  
    76      ```
    77      » %[Monday..Sunday] -> [{$.v != datetime(--in {now} --out {py}%A)}]
    78      [
    79          "Monday",
    80          "Tuesday",
    81          "Wednesday",
    82          "Thursday",
    83          "Saturday",
    84          "Sunday"
    85      ]
    86      ```
    87  
    88      #### Update
    89  
    90      Updating a map:
    91  
    92      ```
    93      » %{hello: world, foo: bar} -> [{$.v == "world" -> if {$.v = "Earth"}}]
    94      {
    95          "foo": "bar",
    96          "hello": "Earth"
    97      }
    98      ```
    99  
   100      Updating an array:
   101  
   102      ```
   103      » %[monday..friday] -> [{$.v | tr [:lower:] [:upper:] | set $.v}]
   104      [
   105          "MONDAY",
   106          "TUESDAY",
   107          "WEDNESDAY",
   108          "THURSDAY",
   109          "FRIDAY"
   110      ]
   111      ```
   112  
   113      #### Output
   114  
   115      Output from a map:
   116  
   117      ```
   118      » %{hello: world, foo: bar} -> [{$.v == "world" && out "Key '$.k' contains '$.v'"}]
   119      Key 'hello' contains 'world'
   120      ```
   121  
   122      Output from an array:
   123  
   124      ```
   125      » %[Monday..Sunday] -> [{ $.v =~ "^S" && out "$.v is the weekend"}]
   126      Saturday is the weekend
   127      Sunday is the weekend
   128      ```
   129  
   130      #### Foreach
   131  
   132      Here we are using a lambda just as a terser way of writing a standard `foreach`
   133      loop:
   134  
   135      ```
   136      » %[Monday..Sunday] -> [{$.v =~ "^S" && $count+=1}]; echo "$count days being with an 'S'"
   137      Error in `expr` (0,22): [json marshaller] no data returned
   138      2 days being with an 'S'
   139      ```
   140  
   141      However this is a contrived example. The more idiomatic way to write the above
   142      would be (and notice it doesn't produce any empty array error too):
   143  
   144      ```
   145      » %[Monday..Sunday] -> foreach day { $day =~ "^S" && $count+=1}; echo "$count days being with an 'S'"
   146      2 days being with an 'S'
   147      ```
   148  
   149      ...or even just using `regexp`, since the check is just a simple regexp match:
   150  
   151      ```
   152      » %[Monday..Sunday] -> regexp m/^S/ -> count
   153      2
   154      ```
   155    Detail: |-
   156      {{ include "gen/includes/meta-values.inc.md" }}
   157  
   158      * `i`: iteration number (counts from one)
   159      * `k`: key name (for arrays / lists this will count from zero)
   160      * `v`: item value of map / object or array / list
   161    Related:
   162      - foreach
   163      - formap
   164      - while
   165      - alter
   166      - datetime
   167      - create-array
   168      - create-object
   169      - regexp