OILS / doc / block-literals.md View on Github | oilshell.org

168 lines, 111 significant
1---
2default_highlighter: oils-sh
3in_progress: true
4---
5
6Block Literals
7==============
8
9Procs are shell like-functions, but they can have declared parameters, and lack
10dynamic 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
18Blocks are fragments of code within `{ }` that can be passed to builtins (and
19eventually 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
35You don't define blocks. Blocks are data types.
36
37-->
38
39<div id="toc">
40</div>
41
42## Syntax
43
44These forms work:
45
46 cd / {
47 echo $PWD
48 }
49 cd / { echo $PWD }
50 cd / { echo $PWD }; cd / { echo $PWD }
51
52These 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
58Runtime error:
59
60 local a=1 { echo bad }; # assignment builtins can't take blocks
61
62Caveat: 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
67Quoting of `{ }` obeys the normal rules:
68
69 echo 'literal braces not a block' \{ \}
70 echo 'literal braces not a block' '{' '}'
71
72## Semantics
73
74TODO: This section has to be implemented and tested.
75
76### Use `eval` to evaluate a block
77
78TODO: 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
99TODO
100
101### Errors
102
103Generally, 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
118See 16 use cases on the blog: [Sketches of YSH
119Features](https://www.oilshell.org/blog/2023/06/ysh-features.html).
120
121<!--
122### Configuration Files
123
124Evaluates to JSON (like YAML and TOML):
125
126 server foo {
127 port = 80
128 }
129
130And can also be serialized as command line flags.
131
132Replaces 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
157Probably use a block format. Compare with Python's optparse.o
158
159See issue.
160
161### Unit Tests
162
163Haven't decided on this yet.
164
165 check {
166 }
167-->
168