Stack and workspace info
Contents
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
var←42
⎕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
var←42
⎕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' ⊣ var←42
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
:
nums←⍳100 100
⎕SIZE'nums'
480040
Workspace available ⎕WA
#
You might also need to know how much [workspace available] (⎕WA
) you have:
nums←⍳100 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