ddonche/goblin-lang
0.46.24
1
0
docs reference
[[shadow]]

Shadow


In Goblin, shadowing creates a new variable with the same name as an existing variable in an outer scope.1 In Goblin, shadowing requires its own operator; this is because many errors come from accidental shadowing. Here, you must intentionally shadow a variable.

Note
The shadow operator [= is considered as belonging to the tether operator family. Tether: |, Retether: |=, Shadow: [=, Update: |!, Delete: !|.

Unlike Retether, shadowing does not change the original variable.

Instead, the new variable temporarily hides the original while the inner scope is active.


Creating a Shadow

Use the shadow operator [= :

inventory_slots | 20

if inventory_slots < 50
    inventory_slots [= inventory_slots + 10
    :say("With Backpack: {inventory_slots}")
xx

:say("Without Backpack: {inventory_slots}")
inventory_slots | 20

if inventory_slots < 50
    inventory_slots [= inventory_slots + 10
    :say("With Backpack: {inventory_slots}")
xx

:say("Without Backpack: {inventory_slots}")

Output:

With packpack: 30
Without Backpack: 20
With packpack: 30
Without Backpack: 20

Inside the if block, the shadow variable is used.

After the block ends, the original variable becomes visible again.

Lore
Goblin's shadow operator came about after Dan saw Go's "walrus operator" := and wanted something in a similar vein.

Why Shadow?

Shadowing is useful when you need a temporary value without changing the original value.

Imagine a shop offers a holiday promotion.

You want to see what a player's gold would be during the sale without permanently changing their actual gold.

player_gold | 100

if holiday_sale
    player_gold [= player_gold + 50
    :say("Sale Value: {player_gold}")
xx

:say("Actual Gold: {player_gold}")
player_gold | 100

if holiday_sale
    player_gold [= player_gold + 50
    :say("Sale Value: {player_gold}")
xx

:say("Actual Gold: {player_gold}")

Possible output:

Sale Value: 150
Actual Gold: 100
Sale Value: 150
Actual Gold: 100

The temporary sale value exists only inside the promotion block.

The player's real gold remains unchanged.


Shadow vs Retether

Shadowing creates a temporary variable:

gold | 100

if true
    gold [= 500
    :say(gold)
xx

:say(gold)
gold | 100

if true
    gold [= 500
    :say(gold)
xx

:say(gold)

Output:

500
100
500
100

Retethering changes the existing variable:

gold | 100
gold |= 500

:say(gold)
gold | 100
gold |= 500

:say(gold)

Output:

500
500

After a retether, the variable now points to the new value.

After a shadow, the original variable is still there.


Rules

A shadow must be created inside a nested scope.

This is valid:

gold | 100

if true
    gold [= 500
xx
gold | 100

if true
    gold [= 500
xx

This is not:

gold | 100
gold [= 500
gold | 100
gold [= 500

Because both variables would exist in the same scope.

Goblin reports:

duplicate-local
duplicate-local


Mental Model

Think of a variable name as a tether attached to a stash of information.

When you create a shadow, Goblin creates a second tether with the same name inside a smaller scope.

While the shadow exists, Goblin uses the nearest matching variable.

When the shadow goes out of scope, the original variable becomes visible again.

The original variable is never modified.


Use Retether when you want to replace a value.

Use Shadow when you need a temporary value that should not affect the original.

  1. Various. (n.d.). Variable shadowing. Wikipedia. https://en.wikipedia.org/wiki/Variable_shadowing