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