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 |
|