SALT II
Vector 23:4, page 90
Transcribed from the printed issue; not yet reviewed. Read it in the article’s own PDF Read it in the PDF of the issue, page 90
Introduction¶
SALT stands for Simple APL Library Toolkit, a code-management tool for APL. It first appeared in V11 as a prototype. Since then it has undergone many changes and is now fully supported by Dyalog. It allows you to store code in flat Unicode text files, often called scripts, outside the workspace. There are many ways to keep code out of the workspace but text files have advantages over traditional APL ways. they let you:
- Exchange, send or archive the scripts without using the interpreter
- Compare scripts easily
- Divide and work on different sections of code in parallel
- Use an external code-management systems
In environments where the ability to manage code externally is important this is a considerable advantage over storing code in workspaces.
Basics¶
Besides storing and retrieving, SALT allows you to list and view folders of scripts. It can save multiple versions and manage them locally. It can compare them. And it comes with its own set of utilities.
If you share code it is important to be able to manage it, one way or another. You want to be able to:
- Store multiple versions and retrieve any of them
- Compare them
- Do housekeeping
Dyalog offers all this with SALT and more. You don’t have to use SALT’s ability to store multiple versions but it might well be all you need. If a third-party version-control system is used, SALT’s versioning should not be used as it would probably interfere rather than help.
SALT can store functions and sourced namespaces [1] onto file. Non-sourced namespaces can be stored but they need to be converted into sourced form first [2]. At present, there are restrictions and root variables, for example, cannot be stored.
All the SALT code resides in ⎕SE and is enabled by default in V12.
Simple examples¶
-
Function
Foois defined and we want to keep a scripted copy of it. To do so we enterand file
\projectZ\fns\Foo.dyalogwill now contain a copy of the function in text form. -
Sourced namespace
Utilscontains functions and variables used everywhere. They constitute a set of utilities that must remain together. We want to store the namespace in fileU1.dyalog:Note that in this case we made the filename differ from the namespace’s name.
-
Sourced namespace
GUIutilsis another set of utilities relying on the aboveUtilsnamespace. To save it and start using version numbers we add theversionswitch:
The next time we want to get those two namespaces (and their contents) all we need to do is
There may be more sets of utilities starting with the letter U. If we don’t want them all we must load the ones we want one by one. If there are dependencies we can tell SALT by using the SALT tag ⍝∇:require. For example, if the above GUI namespace requires the Utils namespace to be present we should insert the line
preferably at the top of the source. If we know that Utils is always in the same folder as GUI we can use instead
with the = meaning same folder as myself. We then only need to load U2, even if both files are moved together to a different location.
Automatic update¶
Because SALT intercepts editor events, it can save changes on file right after editing an object, optionally prompting you for confirmation.
In other words, every time you edit a salted object, SALT will come up and ask you if you wish to save the changes back to file, making a new version if necessary.
Making life easier, the settings¶
Instead of always specifying the path of the objects to save or load you can tell SALT to look in specific places when a relative path (one that does not start with \) is given. To do so you use
SALT will save objects in location1 if a relative path is given or look in each location until the file is found when a load is requested. Each full path must be separated from the next one by a semi-colon.
If you do not wish SALT to confirm with you when saving the changes every time you modify an object you should do
This will skip the prompting and the changes will be made to file automatically.
Everyday examples¶
Let’s have a look at a typical use.
Mike has been gathering functions for years. They’re all over the place, in various workspaces, sometimes in duplicates, sometimes in triplicates. He wants to clean this up and start using a system to manage his code. SALT gives him two choices:
- He can store all his functions, each one in a single script file, grouped by topic in folders of his choice.
- He can start reorganising each workspace in namespaces and store each namespace in a separate file.
Whichever he chooses, he can snap his workspace straight into files like this:
Each function and namespace will be saved in a file with the same name followed by the .dyalog extension.
If he wants to start keeping track of versions he must add the -version switch as well. Let’s see both cases:
Method 1: store each function in a separate file¶
Let’s assume the workspace looks like this:
To store each function in separate files in the same folder we simply do
We can then use a ‘Disk Explorer’ type program to organise files in folders.
If we decide to reorganise the functions and, say, put the GUI functions together, the utilities (those functions whose names begin with u) together and the rest in the top folder, we can do
⎕SE.SALT.Snap '\projectX\scripts\APL\GUI –stem=GUI'
⎕SE.SALT.Snap '\projectX\scripts\APL\utils –stem=u'
We now save the remaining functions in \projectX\scripts\APL.
SALT keeps track of what has been saved and won’t save a new copy again.
Method 2: regroup some functions into namespaces first¶
Same thing. This time we organise the functions into namespaces first. We must create the namespaces and move functions into them. We can
a. create the namespaces:
and then use Workspace Explorer to reorganise (move) the functions or
b. do it manually, e.g.:
We need to make sure the functions do not appear in two places (hence the ⎕EX).
Then we do all functions and namespaces at once:
Note that everything (functions and namespaces) are saved in the same location. If you wish to separate them you could do
⍝ functions in folder 'base'
⎕SE.SALT.Snap '\projectX\scripts\APL\base -class=3 4'
⍝ namespaces in folder 'groups'
⎕SE.SALT.Snap '\projectX\scripts\APL\groups -class=9'
When an object has been salted, modifications can be stored to file automatically after making changes via the editor. If you subsequently erase an object or redefine it the tagged information is lost and no automatic update can occur.
Important note¶
Only sourced functions and namespaces can be tagged. Non-sourced functions (e.g. derived functions) and namespaces cannot be tagged and although some of them can be saved (SALT generates source for them subject to constraints such as no GUI object in them), they cannot be edited and must be resaved manually or skipped. If you wish to convert a non-sourced namespace into a sourced one you should use the SALT utilities [3] provided. Saving it will then allow SALT to pick up subsequent changes automatically.
Saving new code¶
Once your code is in SALT your changes will be picked up automatically if you wish. If you disable SALT or if you decline to save changes when prompted (perhaps you want to test before filing the changes) you will end up with code that is not in SALT yet. You can )SAVE the workspace and resume later as all the tagged information is kept unless you deliberately remove it.
With SALT enabled you can pick up all the new code by using Snap again or you can use Save for an individual item.
Using your code¶
We’ve seen how to move code outside the workspace into text files. Now is the time to use that code. The function to bring the code in is Load. You give it a filename and it defines the code in the workspace, ready for use. Let’s go back to Mike’s code.
To bring everything back in we do
If namespaces were saved there they will now also appear as namespaces in the root of the workspace.
If other needed namespaces were saved elsewhere they have to be brought in, separately:
All these objects are tagged by SALT, and editing any of them will get the modifications saved back to file, if you wish. If you do not want the objects to be so tagged use the switch nolink, e.g.:
You might typically do that in a production environment.
You might also prefer to keep some functions together, saved in a single file (a namespace), but to have them in the workspace (in the root by default) and not in a namespace. You use the disperse switch for that:
You can even choose which objects to disperse:
This method has the advantage of being able to define variables. A serious disadvantage, though, is that this version of SALT cannot keep track of where the objects came from: changes are not picked up and filed automatically.
Tackling variables¶
SALT cannot tag variables and save them individually on file.
There are two ways around this:
-
Initialise the variables in a function and call the function before doing anything else:
-
Put the variables in a namespace and disperse its contents. If
globalVarswas saved thus:
then
would define GlobalSetting in the workspace root.
Version control¶
One of the main reasons for using version control is to be able to go back in time and retrieve previous versions.
Let’s say you had code working fine at version 3 and you made a series of changes that have brought you to version 5 and you now realise there is a problem or a difference in behaviour. If you want to check and run that previous code you can retrieve it simply by doing
If you’d rather only see what the difference is you can use Compare:
SALT will use its own code to do the comparison but you prefer to use your favourite file-comparison program located, say, [4] in [ProgramFiles]\X then tell SALT [5]:
SALT’s way of tracking versions is very simple and each file can have its own version number. SALT has no locking mechanism and does not allow you to ‘lock out’ files but it will warn you if it detects that a file has been revised when you try to save back a modified object. If you see such a warning and you don’t know why, then you should investigate.
For serious version control in a large system you should use a more robust system like SubVersion or CVS. In that case you should not be using SALT’s versions at all.
If you decide to use versions you should keep in mind that SALT creates a new file each time a modification is made to an object. After a while you might end up with a large number of files, many of which you are uninterested in keeping. For example, let’s say you started working on namespace NmspX at version 15. After having modified it sixty times you are now at version 75. If you are happy with the result and confident that versions 16 to 74 are useless you can use Explorer to get rid of the files NmspX.16.dyalog to NmspX.74.dyalog. There will be a gap between 15 and 75 but that might not matter.
If you would like to collapse those sixty versions into one, bringing the good version 75 to a version just above the current good version 15 (i.e. 16) you can get SALT to do it like this:
SALT will confirm with you the deletion of (here) 60 versions, delete 59 of them and rename the last one to version 16. The collapse switch is used to keep the last version. Without it the last 60 versions would be deleted (which may also be what you want to do).
Epilogue¶
You might not need SALT or any version control system at all. If all you have is a small system that runs well in 1 or 2 workspaces and needs little or no maintenance then SALT would not be very useful to you.
If you already have your own management system that takes care of all the maintenance problems and you don’t need to use text files then, again, SALT would not improve your life much.
But if you don’t have such a system, and your code requires a fair amount of maintenance, then SALT can help. It is already there and it is free.
As you have seen, SALT supports many ways to organise your code. It is good at saving and retrieving code, keeping track of versions and managing them. Coupled with a professional external version-control system it could solve many problems.
SALT comes with V12 but will be available online before 2009.
Check it out.
Notes¶
-
Sourced namespaces are those for which the
⎕SRCfunction returns a canonical representation similar to what⎕NRreturns for functions. -
There are SALT utilities to do this.
-
You will find those utilities in
lib/NStoScript. The main function isConvert. It takes a namespace as argument and turns it into a sourced namespace. -
[ProgramFiles]is where Windows keeps all programs. SALT will replace it by whatever value is appropriate. -
SALT uses a consistent syntax for each function: a single string argument that describes the command arguments and the switches that start by a dash. Each switch can be shortened to a non-conflicting length. Here there are no other switches starting with
vso-vis sufficient to denote-version.