| 1 | ---
|
| 2 | default_highlighter: oils-sh
|
| 3 | in_progress: true
|
| 4 | ---
|
| 5 |
|
| 6 | Block Literals
|
| 7 | ==============
|
| 8 |
|
| 9 | Procs are shell like-functions, but they can have declared parameters, and lack
|
| 10 | dynamic scope.
|
| 11 |
|
| 12 | proc p(name, age) {
|
| 13 | echo "$name is $age years old"
|
| 14 | }
|
| 15 |
|
| 16 | p alice 42 # => alice is 42 years old
|
| 17 |
|
| 18 | Blocks are fragments of code within `{ }` that can be passed to builtins (and
|
| 19 | eventually procs):
|
| 20 |
|
| 21 | cd /tmp {
|
| 22 | echo $PWD # prints /tmp
|
| 23 | }
|
| 24 | echo $PWD # prints original dir
|
| 25 |
|
| 26 | - See [YSH Idioms](idioms.html) for examples of procs.
|
| 27 |
|
| 28 | <!--
|
| 29 |
|
| 30 | - Block literals are a syntax for unevaluated code like `cd /tmp { echo $ PWD
|
| 31 | }`. They are instances of "quotation type" `value.Command`. The `{ }`
|
| 32 | syntax is niec for passing to blocks to procs, but they can be passed to
|
| 33 | funcs as well.
|
| 34 |
|
| 35 | You don't define blocks. Blocks are data types.
|
| 36 |
|
| 37 | -->
|
| 38 |
|
| 39 | <div id="toc">
|
| 40 | </div>
|
| 41 |
|
| 42 | ## Syntax
|
| 43 |
|
| 44 | These forms work:
|
| 45 |
|
| 46 | cd / {
|
| 47 | echo $PWD
|
| 48 | }
|
| 49 | cd / { echo $PWD }
|
| 50 | cd / { echo $PWD }; cd / { echo $PWD }
|
| 51 |
|
| 52 | These are syntax errors:
|
| 53 |
|
| 54 | a=1 { echo bad }; # assignments can't take blocks
|
| 55 | >out.txt { echo bad }; # bare redirects can't take blocks
|
| 56 | break { echo bad }; # control flow can't take blocks
|
| 57 |
|
| 58 | Runtime error:
|
| 59 |
|
| 60 | local a=1 { echo bad }; # assignment builtins can't take blocks
|
| 61 |
|
| 62 | Caveat: Blocks Are Space Sensitive
|
| 63 |
|
| 64 | cd {a,b} # brace substitution
|
| 65 | cd { a,b } # tries to run command 'a,b', which probably doesn't exist
|
| 66 |
|
| 67 | Quoting of `{ }` obeys the normal rules:
|
| 68 |
|
| 69 | echo 'literal braces not a block' \{ \}
|
| 70 | echo 'literal braces not a block' '{' '}'
|
| 71 |
|
| 72 | ## Semantics
|
| 73 |
|
| 74 | TODO: This section has to be implemented and tested.
|
| 75 |
|
| 76 | ### Use `eval` to evaluate a block
|
| 77 |
|
| 78 | TODO: use `eval`
|
| 79 |
|
| 80 |
|
| 81 | proc p(&block) {
|
| 82 | echo '>'
|
| 83 | $block # call it?
|
| 84 | # or maybe just 'block' -- it's a new word in the "proc" namespace?
|
| 85 | echo '<'
|
| 86 | }
|
| 87 |
|
| 88 | # Invoke it
|
| 89 | p {
|
| 90 | echo 'hello'
|
| 91 | }
|
| 92 | # Output:
|
| 93 | # >
|
| 94 | # hello
|
| 95 | # <
|
| 96 |
|
| 97 | ### Hay Config Blocks
|
| 98 |
|
| 99 | TODO
|
| 100 |
|
| 101 | ### Errors
|
| 102 |
|
| 103 | Generally, errors occur *inside* blocks, not outside:
|
| 104 |
|
| 105 | cd /tmp {
|
| 106 | cp myfile /bad # error happens here
|
| 107 | echo 'done'
|
| 108 | } # not here
|
| 109 |
|
| 110 | ### Control Flow
|
| 111 |
|
| 112 | - `break` and `continue` are disallowed inside blocks.
|
| 113 | - You can exit a block early with `return` (not the enclosing function).
|
| 114 | - `exit` is identical: it exits the program.
|
| 115 |
|
| 116 | ### 16 Use Cases for Blocks
|
| 117 |
|
| 118 | See 16 use cases on the blog: [Sketches of YSH
|
| 119 | Features](https://www.oilshell.org/blog/2023/06/ysh-features.html).
|
| 120 |
|
| 121 | <!--
|
| 122 | ### Configuration Files
|
| 123 |
|
| 124 | Evaluates to JSON (like YAML and TOML):
|
| 125 |
|
| 126 | server foo {
|
| 127 | port = 80
|
| 128 | }
|
| 129 |
|
| 130 | And can also be serialized as command line flags.
|
| 131 |
|
| 132 | Replaces anti-patterns:
|
| 133 |
|
| 134 | - Docker has shell
|
| 135 | - Ruby DSLs like chef have shell
|
| 136 | - similar to HCL I think, and Jsonnet? But it's IMPERATIVE. Probably. It
|
| 137 | might be possible to do dataflow variables... not sure. Maybe x = 1 is a
|
| 138 | dataflow var?
|
| 139 |
|
| 140 | ### Awk Dialect
|
| 141 |
|
| 142 | BEGIN {
|
| 143 | end
|
| 144 | }
|
| 145 |
|
| 146 | when x {
|
| 147 | }
|
| 148 |
|
| 149 | ### Make Dialect
|
| 150 |
|
| 151 | rule foo.c : foo.bar {
|
| 152 | cc -o out @srcs
|
| 153 | }
|
| 154 |
|
| 155 | ### Flag Parsing to replace getopts
|
| 156 |
|
| 157 | Probably use a block format. Compare with Python's optparse.o
|
| 158 |
|
| 159 | See issue.
|
| 160 |
|
| 161 | ### Unit Tests
|
| 162 |
|
| 163 | Haven't decided on this yet.
|
| 164 |
|
| 165 | check {
|
| 166 | }
|
| 167 | -->
|
| 168 |
|