0% found this document useful (0 votes)
78 views13 pages

Advanced Stack Manipulation - Uiua Docs

Uploaded by

Pete
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views13 pages

Advanced Stack Manipulation - Uiua Docs

Uploaded by

Pete
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Uiua An array-oriented tacit programming language

Support Uiua's development Home

Back to Docs Home

〈 Previous: Modifiers and Functions Next: Inverses 〉

Advanced Stack Manipulation


Uiua does not have local variables. With only . duplicate , : flip , and
, over , how do you work with more than 2 values at a time?

⊃ fork

⊃ fork is a dyadic modifier that takes 2 functions and calls them both on
the same set of arguments. The number of arguments used is the maximum
of the two functions.

1 [⊃+× 3 5] � ↧ �

[8 15] Run

If one of the functions takes more arguments than the other, the function
with fewer arguments uses the top-most values.

1 ⊃×⇌ [1 2 3] 10 � ↧ � 1/3

[3 2 1] Run < >


[10 20 30]

What's powerful about ⊃ fork is that it can be chained to use as many


functions as you want.
1 [⊃⊃⊃+-×÷ 5 8] � ↧ �

[13 3 40 1.6] Run

⊃ fork is also good because it does not require that its values be in an
array together, so they can be different shapes or types.

1 ⊃+- 1 @b � ↧ � 1/3

@a Run < >


@c

1 ⊃⊃⊃↻↙↘⊡ 2 [1 2 3 4 5] � ↧ � 1/3

3 Run < >


[3 4 5]
[1 2]
[3 4 5 1 2]

We'll see just how important ⊃ fork is later in this section.

both

both is a monadic modifier and a sort of complement to ⊃ fork . While


⊃ fork calls multiple functions on the same set of arguments, both
calls a single function on multiple sets of arguments.

1 ⇌ [1 2 3] [4 5 6] � ↧ � 1/3

[6 5 4] Run < >


[3 2 1]

Chaining both doubles the number of arguments each time.

1 ⇌ [1 2 3] [4 5 6] [7 8 9] [10 11 12]
� ↧ � 1/5

[12 11 10] Run < >


[9 8 7]
[6 5 4]
[3 2 1]

⊓ bracket

To round off the trio, we have ⊓ bracket , which is a dyadic modifier that
calls each of its functions on a different set of arguments.

1 [⊓+× 1 2 3 4] � ↧ �

[3 12] Run

⊓ bracket too can be chained. Each additional function is called on


arguments deeper in the stack.

1 [⊓⊓⊓+¯×. 1 2 3 4 5 6] � ↧ �

[3 ¯3 20 6 6] Run

Function Packs

All dyadic modifiers allow a special notation with a single set of () s with a
| in the middle separating the functions. This is called a function pack.

1 ⊓(+|×) 1 2 3 4 � ↧ � 1/5

12 Run < >


3

While all dyadic modifiers can use function packs, ⊃ fork and ⊓ bracket
allow more than 2 functions to be used. This can sometimes be shorter
and/or more readable than chaining the modifier.

1 [⊃(+|-|×|÷) 5 8] � ↧ �

[13 3 40 1.6] Run


1 [⊓(+1|×|÷2) 5 10 12 22] � ↧ �

[6 120 11] Run

⊙ dip

The ⊙ dip modifier temporarily pops the top value on the stack, calls its
function, then pushes the value back.

1 [⊙+ 1 2 3] � ↧ �

[1 5] Run

⊙ dip can be chained to dig deeper into the stack, though try not to dig
too deep, as it makes code harder to read.

1 [⊙⊙⊙⊙⊙⊙+ 1 2 3 4 5 6 7 8] � ↧ �

[1 2 3 4 5 6 15] Run

One use of ⊙ dip is to collect values from the stack into an array. Here, a
chain of ⊙ dip s are terminated with ∘ identity .

1 [⊙⊙⊙∘] 1 2 3 4 5 � ↧ � 1/6

5 Run < >


[1 2 3 4]

1 {⊙⊙∘} 1 2_3 "wow" � ↧ � 1/4

{1 [2 3] "wow"} Run < >

However, you do not typically need to do this because of...

Subscripts
Subscripts are a special syntax that allows you to augment some functions
and modifiers with a number.

Subscripts are typed with __ followed by some digits. The formatter will turn
them into subscript digit characters. A leading negative sign is allowed.

Several functions and modifiers are supported, but we'll only cover some
stack-related ones here. You can find a full list of subscript-compatible
functions here.

Subscripted both calls its function on N sets of arguments.

1 [ + 1 2 3 4] � ↧ � 1/3
2 [ + 1 2 3 4 5 6]
3 [ + 1 2 3 4 5 6 7 8] # Try formatting!
[3 7] Run < >
[3 7 11]
[3 7 11 15]

Subscripted ⊟ couple collects N values from the stack into an array.

1 1 2 3 4 5 � ↧ � 1/6

5 Run < >


[1 2 3 4]

□ box has similar behavior, but it boxes each value.

1 □₃ 5 "Hi!" [1 2 3] � ↧ � 1/4

{5 "Hi!" [1 2 3]} Run < >

� Planet Notation �

⋅ gap discards the top value on the stack and calls its function.

1 ⋅+ 1 2 3 � ↧ � 1/4
5 Run < >

But wait, ◌ pop exists! Why would you need this?

The main reason for ⊙ dip and ⋅ gap to exist is to be chained with
∘ identity , often inside of ⊃ fork . They act as a sort of boolean
selector to choose which arguments to keep and which to discard in a
branch.

This is called planet notation because it looks like the planets in a solar
system chart.

For example, let's say you want to × multiply the 2nd and 4th arguments
on the stack and discard the rest:

1 ×⋅⊙⋅∘ 1 2 3 4 � ↧ � 1/6

8 Run < >

Notice how the circles correspond to the stack arguments we want.

Maybe you want to + add 3 numbers but keep the second 2 on the stack:

1 [⊃⋅⊙∘(++)] 2 5 10 � ↧ � 1/4

[5 10 17] Run < >

You can read ⋅ ⊙ ∘ as "discard argument 1, keep argument 2, keep


argument 3."

If you only wanted to keep argument 2, you simply make the expression
shorter:

1 [⊃⋅∘(++)] 2 5 10 � ↧ � 1/4

[5 17] Run < >

For a more useful example, let's do a complex mathematical expression. We


will implement this function (shown here in mathematical notation):
f(a,b,c,x) = (a+x)(bx-c)

We'll start with the (a + x) part. We can grab a and x with ⊙ dip and
∘ identity , and ignore b and c with ⋅ gap .

1 +⊙⋅⋅∘ 1 2 3 4 � ↧ � 1/6

5 Run < >

Next, we'll do the (bx-c) part. We can grab each term with ⊃ fork .

1 -⊃(⋅⋅∘)(×⋅⊙⋅∘) 1 2 3 4 � ↧ � 1/6

5 Run < >

The first pair of () s is not actually necessary, so let's remove them.

1 -⊃⋅⋅∘(×⋅⊙⋅∘) 1 2 3 4 � ↧ � 1/6

5 Run < >

Finally, we can combine the two parts with another ⊃ fork .

1 ×⊃(+⊙⋅⋅∘)(-⊃⋅⋅∘(×⋅⊙⋅∘)) 1 2 3 4 � ↧ � 1/6

25 Run < >

If you like, you can factor out the ⋅ gap in the second part

1 ×⊃(+⊙⋅⋅∘)⋅(-⊃⋅∘(×⊙⋅∘)) 1 2 3 4 � ↧ � 1/6

25 Run < >

Alternatively, you can use a function pack.

1 ×⊃(+⊙⋅⋅∘|-⊃⋅⋅∘(×⋅⊙⋅∘)) 1 2 3 4 � ↧ � 1/6

25 Run < >


And there you have it! A readable syntax juggling lots of values without any
names!

It's annoying to write long lists of names like gapdipgapgapide , so those


three functions (plus ◌ pop ) have a special rule in the parser that allows you
to write them with only 1 character as long as there are at least 2 characters
in the sequence. Also, 'i' and 'p' for ∘ identity and ◌ pop only work if
they are the last character.

Try it out!

1 +gdggi 1 2 3 4 5 � ↧ � 1/7

7 Run < >

1 +dggdp 1 2 3 4 5 � ↧ � 1/7

5 Run < >

In general, planet notation as complex as the mathematical function example


above should only be used when it is necessary. For examples like that with
4+ values, it is. However, when working with fewer values, you can get very
far with just . duplicate and : flip . Maybe sprinkle some , over s
and ⊙ dip s in there too.

⟜ on and ⊸ by

As you write more Uiua code, you'll find that there is a kind of pattern you'll
encounter over and over again. It involves calling a function, then calling
another function that re-uses an argument to the first function.

One simple example is getting n numbers between 0 and 1 . One way you
may think to solve this is with . duplicate and : flip .

1 ÷:⇡. 5 � ↧ � 1/5

Style: Prefer ⟜ over : . here Run < >


at 1:2
1 | ÷:⇡. 5
───

[0 0.2 0.4 0.6 0.8]

This solution works, but as the style diagnostic suggests, it is not quite
idiomatic.

When the first function you call is dyadic, it can get a little trickier. For
example, if you wanted to get all the integers between two numbers, you
may try either of the following:

1 +⇡-,: 3 8 � ↧ � 1/11
2 +⊃∘(⇡-) 3 8
Style: Prefer `⟜:` over `,:` for clarity Run < >
at 1:4
1 | +⇡-,: 3 8
──
Style: Prefer `⟜` over `⊃∘` for clarity
at 2:2
2 | +⊃∘(⇡-) 3 8
──

[3 4 5 6 7]
[3 4 5 6 7]

Again, as the style diagnostics tell you, there is a better way.

The ⟜ on modifier calls a function but keeps its first argument on top of the
stack. This can be used in both of the above examples.

1 ÷⟜⇡ 5 � ↧ � 1/3

[0 0.2 0.4 0.6 0.8] Run < >

1 +⟜(⇡-) 3 8 � ↧ � 1/4

[3 4 5 6 7] Run < >


Having a single glyph for something that can be written as simply ⊃ ∘ may
seem unnecessary, but you'll find that because the pattern is so common, it
makes code easier to both read and write.

The ⊸ by modifier is similar. Instead of keeping the first argument on top of


the stack, it keeps the last argument below the function's outputs.

1 ÷⊸⧻ [1 2 3 4] � ↧ � 1/3

[0.25 0.5 0.75 1] Run < >

1 ▽⊸> 5 [1 8 4 9 2 8 4] � ↧ � 1/4

[8 9 8] Run < >

Challenges

Challenge 1

Write a program that moves the 4th value on the stack to the top.

1 � ↧ �

Run
Example: 1 2 3 4
3
2
1
4

Input: @x [1 2 3] □5 27
27
□5
[1 2 3]
@x

��
Challenge 2

Write a program that adds the second argument to the third and divides
by the first.

1 � ↧ �

Run
Example: 2 3 5
4

Input: 1 2 3
3
2
1

Input: 5 10 15
15
10
5

Challenge 3

Write a program that finds both the sum and product of three arguments.

1 � ↧ �

Run
Example: 4 5 6
120
15

Input: 10 10 10
10
10
10

Input: 1_2 3_4 5


5
[3 4]
[1 2]

Challenge 4

Write a program that collects 9 values from the stack evenly into 3 arrays.

1 � ↧ �

Run
Example: 1 2 3 4 5 6 7 8 9
[7 8 9]
[4 5 6]
[1 2 3]

Input: @G @o @o @d @ @j @o @b @!
@!
@b
@o
@j
@
@d
@o
@o
@G

Input: ...×2..+1...5
5
5
5
6
6
12
12
12
12

Challenge 5
Write a program that for numbers A, B, C, and D calculates (A+C)×(B+D).

1 � ↧ �

Run
Example: 1 2 3 4
24

Input: 10 ¯3 1 0
0
1
¯3
10

Input: 3 ¯7 2 2
2
2
¯7
3

��

〈 Previous: Modifiers and Functions Next: Inverses 〉

Back to Docs Home

You might also like