Skip to content

Commit 932a9cb

Browse files
committed
blog: Add 2025-07-31.md
1 parent 95143fc commit 932a9cb

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

blog/2025-07-31.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
title: The loop and more loops
3+
date: 2025-07-31
4+
draft: false
5+
authors: [ingydotnet]
6+
categories: [Summer-of-YS]
7+
edit: blog/2025-07-31.md
8+
comments: true
9+
---
10+
11+
12+
The looping function that offers the most control in YS is called `loop`.
13+
It's also the most verbose.
14+
15+
There are lots of alternatives that are more specific and require less code, but
16+
they don't let you do everything, like decide when to stop.
17+
18+
We'll talk about both today.
19+
20+
<!-- more -->
21+
22+
23+
## The `loop` function
24+
25+
I implied above that you could control when to stop the `loop` function.
26+
27+
It's kinda the other way around.
28+
29+
You control when to keep looping!
30+
31+
Loop has a matching `recur` "function" that you can call to keep looping.
32+
Otherwise it exits and returns the value that was evaluated.
33+
34+
And remember, `loop` is a function, so it always returns something.
35+
36+
The `loop` function takes a set of paired arguments where the first value is a
37+
variable name and the second value is its starting value.
38+
39+
The `recur` call, calls the `loop` function (tail) recursively with a new value
40+
for each variable.
41+
42+
Here's a simple example that finds the highest power of 2 less than a million:
43+
44+
```bash
45+
$ ys -pe '
46+
loop i 1:
47+
if i < 1000000:
48+
recur: i * 2
49+
else: i'
50+
1048576
51+
```
52+
53+
See how we used the `if` function to decide when to continue rather than when to
54+
stop?
55+
It's really the same question but it feels backwards.
56+
57+
58+
## More loops
59+
60+
We've seen these before but the main ones are: `map`, `for` and `reduce`.
61+
62+
`map` is a list comprehension.
63+
That's useful for transforming the elements of a list.
64+
Let's double the numbers 0 through 9:
65+
66+
```bash
67+
ys -pe '(1 .. 9).map(double)'
68+
(1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0)
69+
```
70+
71+
By "double" we don't mean "multiply by 2".
72+
We mean convert integers to floats (longs to doubles).
73+
74+
`for` is a loop that iterates over a list assigning each element to a variable.
75+
It processes the entire list before returning.
76+
77+
Let's use it to double (in the by 2 sense) the numbers 0 through 9:
78+
79+
```bash
80+
$ ys -pe 'for i (1 .. 9): 2 * i'
81+
(2 4 6 8 10 12 14 16 18)
82+
```
83+
84+
OK, so I lied.
85+
The `for` function actually does give you some control.
86+
You can use `:when` to let it know which elements to process.
87+
88+
Let's double the numbers 0 through 9 that are even:
89+
90+
```bash
91+
$ ys -pe 'for i (1 .. 100) :when (i < 10): 2 * i'
92+
(2 4 6 8 10 12 14 16 18)
93+
```
94+
95+
96+
`reduce` takes each element of a list and uses them to calculate a single value.
97+
98+
It takes a function, a starting value (or accumulator), and a list to process.
99+
100+
Let's total the squares of 1 through 9 and add them to 100:
101+
102+
```bash
103+
$ ys -e '
104+
say:
105+
reduce _ 100 (1 .. 9):
106+
fn(total, n):
107+
total + n:sqr
108+
'
109+
385
110+
```
111+
112+
Remember from before, the first argument to `reduce` is a function but in YS
113+
it's often nicer to put the big thing (the function) last, so we use the `_`
114+
placeholder.
115+
116+
There are lots more specialized looping functions in YS like `filter` and
117+
`remove` (for finding or removing elements from a list), but those are the most
118+
common ones.

0 commit comments

Comments
 (0)