Python and Viv · Basics
Loops
What to notice
for i in range(n)isfor i to n;range(a, b, s)isfor i from a to b by s, and a negative step counts down in both.reversed(range(n))isfor i to n reversed.- Viv's
printalways ends the line; there is noend=" ". The Viv side builds the line in a string and prints it once. viv lintrefuses an integer literal other than 0, 1 and 2 as a loop bound, so the Viv side names its bounds (FIRST,LAST,STEP). Python has no such rule; the Python side names the ones that mean something.enumerate,zip, the comprehension[p * p for p in primes]and the if-expressionn // 2 if n % 2 == 0 else 3 * n + 1are the same in both. (primes * primeswould also multiply element by element in Viv.)- A comprehension's
fortakes Viv's loop heads:for c from 1 to TABLEwhere Python writesfor c in range(1, TABLE). continueandbreakare the same.found.append(k)isfound = append(found, k): an append gives back a new array, written by rebinding the name.- A comparison of two arrays is elementwise in Viv, so a test of equality is
all(found == [3, 5]).
Python loops.py · 58 lines
Viv loops.viv · 81 lines
py2viv refuses loops.py
1 a count from zero
4N = 5
5for i in range(N):
6 print(i, end=" ")
7print()
2N = 5
3line = ""
4for i to N {
5 line += f"{i:d} "
6}
7print(line)
py2viv refuses this program:
loops.py:6:5: not numeric Python: print's end=' ' (lifted by R4)
print(i, end=" ")
^^^^^^^^^^^^^^^^^
Every Viv print ends its line: build the line in one print.
loops.py:11:5: not numeric Python: print's end=' ' (lifted by R4)
print(i, end=" ")
^^^^^^^^^^^^^^^^^
Every Viv print ends its line: build the line in one print.
loops.py:14:5: not numeric Python: print's end=' ' (lifted by R4)
print(i, end=" ")
^^^^^^^^^^^^^^^^^
Every Viv print ends its line: build the line in one print.
loops.py:19:5: not numeric Python: print's end=' ' (lifted by R4)
print(i, end=" ")
^^^^^^^^^^^^^^^^^
Every Viv print ends its line: build the line in one print.
4 constructs outside the numeric subset (tools/py2viv/SUBSET.md) 2 a start, an end and a step
10for i in range(3, 20, 4):
11 print(i, end=" ")
12print()
13for i in range(10, 0, -3):
14 print(i, end=" ")
15print()
10FIRST = 3
11LAST = 20
12STEP = 4
13line = ""
14for i from FIRST to LAST by STEP {
15 line += f"{i:d} "
16}
17print(line)
18TOP = 10
19DOWN = -3
20line = ""
21for i from TOP to 0 by DOWN {
22 line += f"{i:d} "
23}
24print(line)
(refused)
3 reversed
18for i in reversed(range(N)):
19 print(i, end=" ")
20print()
27line = ""
28for i to N reversed {
29 line += f"{i:d} "
30}
31print(line)
(refused)
4 over the items of a list, with their index
23primes = [2, 3, 5, 7, 11]
24for k, p in enumerate(primes):
25 print(f"primes[{k}] = {p}")
34primes = [2, 3, 5, 7, 11]
35for k, p in enumerate(primes) {
36 print(f"primes[{k:d}] = {p:d}")
37}
(refused)
5 two lists side by side
28squares = [p * p for p in primes]
29for p, s in zip(primes, squares):
30 print(p, s)
40squares = [p * p for p in primes]
41for p, s in zip(primes, squares) {
42 print(p, s)
43}
(refused)
6 a while loop
33n = 27
34steps = 0
35while n != 1:
36 n = n // 2 if n % 2 == 0 else 3 * n + 1
37 steps += 1
38print("Collatz steps from 27:", steps)
46n = 27
47steps = 0
48while n != 1 {
49 n = n // 2 if n % 2 == 0 else 3 * n + 1
50 steps += 1
51}
52print("Collatz steps from 27:", steps)
(refused)
7 break and continue
41LIMIT = 30
42found = []
43for k in range(2, LIMIT):
44 if k % 2 == 0:
45 continue
46 if k * k > LIMIT:
47 break
48 found.append(k)
49print("odd k with k*k <= 30:", found)
55LIMIT = 30
56found = []
57for k from 2 to LIMIT {
58 if k % 2 == 0 {
59 continue
60 }
61 if k * k > LIMIT {
62 break
63 }
64 found = append(found, k)
65}
66print("odd k with k*k <= 30:", found)
(refused)
8 nested loops
52TABLE = 4
53for r in range(1, TABLE):
54 print(" ".join(f"{r * c:3d}" for c in range(1, TABLE)))
69TABLE = 4
70for r from 1 to TABLE {
71 print(" ".join(f"{r * c:3d}" for c from 1 to TABLE))
72}
(refused)
9 checks
57assert steps == 111
58assert found == [3, 5]
75test "loops" {
76 assert_true(steps == 111)
77 assert_true(all(found == [3, 5]))
78}
(refused)
What they print
identical — the two programs print the same text.
Dimmed lines are left out of the comparison. Each Viv test block prints one PASS line; the Python checks the same facts with assert, which prints nothing.
$ python3 loops.py
0 1 2 3 43 7 11 15 1910 7 4 14 3 2 1 0primes[0] = 2primes[1] = 3primes[2] = 5primes[3] = 7primes[4] = 112 43 95 257 4911 121Collatz steps from 27: 111odd k with k*k <= 30: [3, 5]1 2 32 4 63 6 9
$ viv run loops.viv
0 1 2 3 43 7 11 15 1910 7 4 14 3 2 1 0primes[0] = 2primes[1] = 3primes[2] = 5primes[3] = 7primes[4] = 112 43 95 257 4911 121Collatz steps from 27: 111odd k with k*k <= 30: [3, 5]1 2 32 4 63 6 9PASS loops