🌱 Beginner's Guide lesson 10 of 12

Maybe Values with Optionals

Sometimes a value might not exist. Your friend might not have a nickname. A search through a list might not find anything. A game character might not be holding an item. Programs need a way to say "there's nothing here", and steav2 has one: sone.

sone: nothing at all

sone means nothing (programmers often call this "nil" or "null"). But steav2 is careful with it: an ordinary variable can never be sone. A LekKut is always a real number, an Ahsor is always real text.

[ x_x broken on purpose ]
bongSlanhOun "nothing";
akthe score: LekKut = sone;
[ what it prints ]
[line 2] Error at 'sone': expected LekKut but got sone

That's a good thing! It means that when you have a LekKut, you never have to worry that it's secretly empty.

Optionals: T?

When a value really might be missing, you say so by adding a question mark to its type. Ahsor? means "maybe some text, maybe sone". This is called an optional type. (In docs you'll see T?, where T stands for any type.)

[ try-it.sts ]
bongSlanhOun "nickname";
akthe nickname: Ahsor? = sone;
jongyeytha nickname;
nickname = "Bo";
jongyeytha nickname;
[ what it prints ]
sone
Bo

An optional box can hold either a real value or sone, and you can switch between them whenever you like.

Checking before you use it

Because an optional might be sone, steav2 won't let you use it as if it were definitely there:

[ x_x broken on purpose ]
bongSlanhOun "careless";
sampoan Pet {
    akthe name: Ahsor;
}
akthe lostPet: Pet? = sone;
jongyeytha lostPet.name;
[ what it prints ]
[line 6] Error at 'name': this is Pet?, it might be sone: check it with ber (x != sone) first

The error tells you exactly what to do. Check with ber (x != sone), and inside that block, steav2 knows the value is really there, so you can use it like a normal value:

[ try-it.sts ]
bongSlanhOun "careful";
sampoan Pet {
    akthe name: Ahsor;
}
akthe foundPet: Pet? = Pet("Mew");
ber (foundPet != sone) {
    jongyeytha "Found " + foundPet.name + "!";
} minjengte {
    jongyeytha "Still looking.";
}
[ what it prints ]
Found Mew!

This also works the other way round: in the minjengte of a ber (x == sone), the value is known to be there.

[ try-it.sts ]
bongSlanhOun "greeting";
akthe nickname: Ahsor? = "Bo";
ber (nickname == sone) {
    jongyeytha "Hello, stranger!";
} minjengte {
    jongyeytha "Hey " + nickname + "!";
}
[ what it prints ]
Hey Bo!

Functions that might not find anything

Optionals are perfect for a function's answer when there sometimes isn't one. Here's a function that searches an array and returns the position of a word, or sone if the word isn't there:

[ try-it.sts ]
bongSlanhOun "search";
rupamun find(words: [Ahsor], wanted: Ahsor) -> LekKut? {
    somhab (akthe i: LekKut = 0; i < words.len(); i += 1) {
        ber (words[i] == wanted) {
            morvenh i;
        }
    }
    morvenh sone;
}

akthe menu = ["rice", "noodles", "soup"];
akthe spot = find(menu, "noodles");
ber (spot != sone) {
    jongyeytha "noodles are dish number " + (spot + 1);
}
jongyeytha find(menu, "pizza");
[ what it prints ]
noodles are dish number 2
sone

Notice that morvenh i; returns a plain LekKut, and that's fine: a real value can always go into a LekKut? box. And inside ber (spot != sone), spot is a plain LekKut, so spot + 1 works.

Your turn

  1. Make an akthe favouriteColor: Ahsor? = sone; and print No favourite yet if it's sone, or I love ... with the colour otherwise. Then set it and try again. Hint: ber (favouriteColor == sone).
  2. Write firstLong(words: [Ahsor]) -> Ahsor? that returns the first word that isn't "a" or "the", or sone if there isn't one.
  3. Write safeDivide(a: LekKut, b: LekKut) -> LekKut? that returns sone when b is 0, and a / b otherwise.

Solution for exercise 3:

[ try-it.sts ]
bongSlanhOun "safe divide";
rupamun safeDivide(a: LekKut, b: LekKut) -> LekKut? {
    ber (b == 0) {
        morvenh sone;
    }
    morvenh a / b;
}

jongyeytha safeDivide(10, 2);
jongyeytha safeDivide(10, 0);
[ what it prints ]
5
sone
  • steav2♡ help
  • Y2K✓ ready
  • wasminside
  • .stsvalid

best viewed at 1024x768 ☆ made with ♡ ☆ the reference is steav2's own docs