Search code examples
scopescopingapllexical-scopedyalog

Accessing namespace script variable


Concider the following namespace script in Dyalog APL:

:Namespace Test

    x ← 0

    ∇ F
        ##.Test.x ← 1
    ∇

    ∇ G; x
        x ← 0
        F
    ∇          

:EndNamespace

If I run Test.G and then Test.x, I get the output zero. How come? How do I set Test.x in Test.F?


Solution

  • Tradfns (traditional functions using and a header, etc.) use dynamic scoping, which means that they "see" the environment of the place they are called from. (This is in contrast to dfns which use lexical scoping; they see environment in which they were defined.) See the documentation for details.

    Now, when G calls F, while x is localised in G, the global x is invisible to F because the localisation in G shadows the global x.

    Notice that ##.Test. doesn't change which namespace we're working in. x is still shadowed.

    If instead you had used dfns, you would see the behaviour you want:

    :Namespace Test
    
        x ← 0
    
          F←{
              ##.Test.x←1
          }
    
          G←{
              x←0
              F ⍬
          }
    
    :EndNamespace
    

    Try it online!