Stack and workspace info#

Let’s continue with other things which deal with functions and other items under program control.

Latent expression ⎕LX#

If you want to have an application start without having the user enter a command (for example, a function name) to boot it, you can assign an expression to ⎕LX (Latent eXpression) and then save your workspace with ⎕SAVE. When the workspace is loaded (including from the command line) APL will do ⍎⎕LX. This is what happens when you load the various workspaces supplied with APL.

)load dfns
⎕LX
⎕LX
/Applications/Dyalog-18.2.app/Contents/Resources/Dyalog/ws/dfns.dws saved Thu Apr  7 00:21:30 2022

An assortment of D Functions and Operators.

      tree #                ⍝ Workspace map.
      ↑¯10↑↓attrib ⎕nl 3 4  ⍝ What's new?
      ⍕notes find 'Word'    ⍝ Apropos "Word".
      ⎕ed'notes.contents'   ⍝ Workspace overview.

236
'
An assortment of D Functions and Operators.

      tree #                ⍝ Workspace map.
      ↑¯10↑↓attrib ⎕nl 3 4  ⍝ What''s new?
      ⍕notes find ''Word''    ⍝ Apropos "Word".
      ⎕ed''notes.contents''   ⍝ Workspace overview.
'

Name classification ⎕NC#

Since APL does not enforce a naming scheme (although you might want to adopt one), you may wonder what a certain name is. ⎕NC (Name Classification) to the rescue! Each type of item has a number. 2 is variable, 3 is function, 4 is operator, 9 is object.

⎕CY'dfns'   ⍝ Copy the dfns workspace silently
var42
⎕NC 'blah' '123' 'var' 'to' 'notes'
0 ¯1 2 3 9

0 is undefined (but valid name). ¯1 is invalid name. 1 is really rare these days. It is a line label, and can only occur while a tradfn/tradop is running or suspended:

tradfn
label:
⎕NC'label' 'label2' 'label3'
label2:

tradfn
1 1 0

Sometimes you want even more info. If the argument to ⎕NC is nested, then the values get a decimal which mean: .1=traditional, .2=field/direct, .3=property/tacit, .4=class, .5=interface, .6=external class, .7=external interface.

⎕CY'dfns'   ⍝ Copy the dfns workspace silently
var42
⎕NC 'blah' '123' 'var' 'to' 'notes'
0 ¯1 2.1 3.2 9.1

Name list ⎕NL#

Using those same codes, you can also use ⎕NL (Name List) to enquire which items of those name classifications are visible. For example, here are all of the dfns workspace’s operators:

⎕CY'dfns'
⎕NL 4
Cut     
Depth   
H       
UndoRedo
_fk     
acc     
alt     
and     
ascan   
ascana  
at      
avl     
bags    
big     
bsearch 
bt      
case    
cf      
cond    
cxdraw  
dft     
do      
each    
else    
file    
fk      
fk_     
fnarray 
foldl   
for     
invr    
kcell   
limit   
lof     
logic   
ltrav   
mdf     
memo    
nats    
of      
or      
perv    
pow     
pred    
profile 
rats    
ratsum  
ravt    
redblack
repl    
roman   
rows    
sam     
saw     
sbst    
splay   
tc      
ticks   
time    
traj    
trav    
until   
vof     
vwise   
while   

You can also specify decimals to get just those specific things. You can get just things beginning with specific letters, too, by giving a list of letters as left argument:

⎕CY'dfns'
'b' ⎕NL 4.2
bags   
big    
bsearch
bt     

If you’d rather have a VTV (vector of text vectors, i.e. a list of strings), then use negative numbers. APLers often use this shortcut to list everything:

⎕CY'dfns'
10⎕NL-⍳9    ⍝ Truncated for display purposes; contains 300+ items...
┌──────────┬───────────┬───────┬─────────┬────────┬─────┬─────────┬───┬───┬────┐
│APLVersion│ActivateApp│Caption│ChildList│Cholesky│Coord│CursorObj│Cut│DDE│Data│
└──────────┴───────────┴───────┴─────────┴────────┴─────┴─────────┴───┴───┴────┘

Expunge ⎕EX#

If you find that the name you want to use is unavailable, you may want to EXpunge its current value with ⎕EX:

⎕NC'var'  ⎕EX 'var'  var42
0

There we created, removed, and enquired about the name var.

Shadow ⎕SHADOW#

If you only want to use an already used name temporarily, then you can use ⎕SHADOW instead of ⎕EX. The name will then be freed up for your use until the current function terminates. Note that shadowing happens automatically in dfns and dops when you just do regular assignments. In a dfn, var←42 really means ⎕SHADOW 'var' var←42.

Be careful using ⎕SHADOW though. It is much better to localise your variables in the function header by putting ;varName at the end of the header.

State indicator ⎕SI#

Let’s say you’ve built a bunch of functions that call each other, and then you run it, and it stops due to some bug. Now you need some situational awareness. You already know that ⎕NL will let you check which names are defined, and ⎕NC what type of things they are. ⎕SI (State Indicator) will give you a list of function names on the stack:

foo{goo }
goo{moo }
moo{⎕SI}
foo
┌───┬───┬───┐
│moo│goo│foo│
└───┴───┴───┘

Line count ⎕LC#

⎕LC (Line Count) will give you a list of corresponding line numbers where each function in ⎕SI is holding:

]dinput
foo{
    goo 

}
]dinput
goo{


    moo 
}
]dinput
moo{

⎕LC}
foo 
2 3 1

Size ⎕SIZE#

If you get a WS FULL error, you may want to check how much memory is being used to represent a variable. Use ⎕SIZE:

nums100 100
⎕SIZE'nums'
480040

Workspace available ⎕WA#

You might also need to know how much [workspace available] (⎕WA) you have:

nums100 100
⎕SIZE'nums'
⎕WA
480040
8564555456

Screen dimensions ⎕SD#

⎕SD is the Screen Dimensions, which for a Jupyter kernel is something fairly arbitrary:

⎕SD
24 80