Skip to content

Commit 50984d5

Browse files
committed
blog: Add 2025-07-19.md
1 parent 5f50adc commit 50984d5

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

blog/2025-07-19.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
---
2+
title: YAML Explicit Keys and YS
3+
date: 2025-07-19
4+
draft: false
5+
authors: [ingydotnet]
6+
categories: [Summer-of-YS]
7+
edit: blog/2025-07-19.md
8+
comments: true
9+
---
10+
11+
Did you know that in YAML you can write:
12+
13+
```yaml
14+
? foo
15+
: bar
16+
```
17+
18+
instead of:
19+
20+
```yaml
21+
foo: bar
22+
```
23+
24+
The `?` is called an explicit key indicator.
25+
26+
But why would you want to use it?
27+
28+
It's not often useful in YAML config files, but it is actually useful in YS
29+
code.
30+
31+
<!-- more -->
32+
33+
34+
## Explicit Keys in YAML
35+
36+
In YAML, a mapping key doesn't have to be a string.
37+
It can be any node.
38+
39+
In flow mode, we could write:
40+
41+
```yaml
42+
{ {foo: 1, bar: 2}: baz }
43+
```
44+
45+
Where `{foo: 1, bar: 2}` is a mapping node that is also a mapping key.
46+
47+
How would we write that in block (indented) mode?
48+
49+
With explicit key syntax!
50+
51+
```yaml
52+
? foo: 1
53+
bar: 2
54+
: baz
55+
```
56+
57+
Note that when you use `?` the `:` has to be on a different line and in the same
58+
column as the `?`.
59+
60+
61+
## Explicit Keys in YS
62+
63+
There's another reason to use explicit keys in YAML.
64+
65+
String keys need to be encoded on a single line, even if they are quoted.
66+
String values can be multi-line, but string keys cannot.
67+
68+
```yaml
69+
this is a very long string key for example:
70+
this is a very
71+
long string value
72+
for example
73+
```
74+
75+
It's not a common problem to solve in YAML, but in YS it comes up more often.
76+
77+
In [Yesterday's blog post](2025-07-18.md#the-ys-code) I showed you a YS program
78+
with a `loop` function that started like this:
79+
80+
```yaml
81+
loop i 0 [x y], [0 0], data {}, [minx maxx miny maxy] [0 0 0 0]:
82+
dir =: i-to-dir(i)
83+
nx ny =: +
84+
...
85+
```
86+
87+
That line isn't terribly long, but it could be if we had used longer variable
88+
names or more arguments to the `loop` function.
89+
90+
We haven't covered the YS `loop` function in detail yet, but it starts with a
91+
set of symbol bindings and their initial values.
92+
Then in the tail position of the body we either `recur` with a new value for
93+
binding or we return the result.
94+
95+
In YS the word `loop` and its bindings need to be on the key side and the rest
96+
of the body needs to be on the value side.
97+
So we ended up with a long line that was hard to read (even though we used
98+
commas to separate the bindings).
99+
100+
It might be nicer to see each binding on a separate line.
101+
102+
Of course we'd have to use YAML explicit keys to do that!
103+
104+
```yaml
105+
? loop
106+
i 0
107+
[x y] [0 0]
108+
data {}
109+
[minx maxx miny maxy] [0 0 0 0]
110+
: dir =: i-to-dir(i)
111+
nx ny =: +
112+
...
113+
```
114+
115+
YAML is often criticized for having too many features that are rarely used.
116+
117+
That's fair, but I'd like to point out that YS has put many of those features
118+
to good use.
119+
120+
YS is not just about trying to encode Clojure/Lisp forms into YAML...
121+
122+
It's about doing that and making it actually be pretty awesome!

0 commit comments

Comments
 (0)