Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Dyalog/link
Browse files Browse the repository at this point in the history
  • Loading branch information
abrudz committed Feb 27, 2024
2 parents c6c38fb + 3558a31 commit 6992cbe
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 15 deletions.
13 changes: 8 additions & 5 deletions docs/Discussion/TechDetails.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@ In the following, for want of a better word, the term *object* will be used to r

**Unscripted Namespaces:** Namespaces created with `⎕NS` or `)NS` have no source code of their own and are mapped to directories.

**Classes and Scripted Namespaces:** Classes and so-called *scripted* namespaces created using the editor or `⎕FIX`, have textual source and are treated the same way as functions and other "code objects". Support for scripted namespaces as endpoints for a Link was introduced in Link 4.0. Before 4.0, scripted namespaces were allows only as objects *within* a an unscripted linked namespace.
**Classes and Scripted Namespaces:** Classes and so-called *scripted* namespaces created using the editor or `⎕FIX`, have textual source and are treated the same way as functions and other "code objects". Support for scripted namespaces as endpoints for a Link was introduced in Link 4.0. Before 4.0, scripted namespaces were allowed only as objects *within* a an unscripted linked namespace.

Note that *unnamed* namespaces are **NOT** supported, either as endpoints of a Link or indeed within a linked namespace: **Changes to - or within - unnamed namespaces will be ignored by Link**. This is discussed in more detail in the next section.

**Variables** are ignored by default, because most of them are not part of the source code of an application. However, they may be explicitly saved to file with [Link.Add](../API/Link.Add.md), or with the `-arrays` modifier of [Link.Create](../API/Link.Create.md) and [Link.Export](../API/Link.Export.md).

**Functions and Operators:** Link is not able to represent names which refer to primitive or derived functions or operators, or trains. You will need to define such objects in the source of another function, or a scripted namespace.
**Functions and Operators:** Link is not able to represent names which refer to primitive or derived functions or operators, or trains. You will need to define such objects in the source of another function, or a scripted namespace. For example, the derived function `Pairs←⊢⌺(⍪2 2)` cannot be represented directly. However, inclusion of the following tradfn will have the desired effect:
```apl
∇ F←Pairs
F←⊢⌺(⍪2 2)
```

**Unsupported:** In addition to unnamed namespaces, Link has no support for name classes 2.2 (field), 2.3 (property), 2.6 (external/shared variable), 3.3 (primitive or derived function or train), 4.3 (primitive or derived operator), 3.6 (external function) 9.2 (instance), 9.6 (external class) and 9.7 (external interface).
**Unsupported:** In addition to unnamed namespaces, Link has no support for name classes 2.2 (field), 2.3 (property), 2.6 (external/shared variable), 3.3 (primitive or derived function or train), 4.3 (primitive or derived operator), 3.6 (external function) 9.2 (instance), 9.6 (external class) and 9.7 (external interface). These can be listed with `]names 2.2 2.3 2.6 3.3 4.3 3.6 9.2 9.6 9.7` and listed for the namespace `myns` with `]names myns 2.2 2.3 2.6 3.3 4.3 3.6 9.2 9.6 9.7`.

## Other Limitations

Expand All @@ -30,8 +35,6 @@ Note that *unnamed* namespaces are **NOT** supported, either as endpoints of a L

In other words, Link does not support source files that define multiple names, even though `2∘⎕FIX` does support this.

- Names which have source files should not have more than one definition within the same namespace. For example, if you have a global constant linked to a source file, you should not reuse that name for a local variable. If you were to edit the local variable while tracing, Link would be unable to distinguish it from the global name, and overwrite the source file.

- In a case-insensitive file system, Links created with default options cannot contain names which differ only in case, because the source files would have indistinguishable names. The `caseCode` option can be used to get Link to generate file names which encode case information - see [Link.Create](../API/Link.Create.md) for more information.

- Link does not support namespace-tagged functions and operators (e.g. `foo←namespace.{function}`).
Expand Down
19 changes: 9 additions & 10 deletions docs/Usage/Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Starting with Dyalog APL version 18.0, it is simple to launch the interpreter fr

Using `LOAD` to link to a directory on startup is simple way to handle very simple applications or ad-hoc development. However, configuration files allow you to both set a startup expression and include other configuration options for the interpreter and are probably a better solution for applications consisting of more than one source directory. For example, we could start our example application by creating a file `dev.dcfg` in the `linkdemo` folder with the following contents:

```json
```json5
{
Settings: {
MAXWS: "100M",
Expand All @@ -72,15 +72,15 @@ Using `LOAD` to link to a directory on startup is simple way to handle very simp

This specifies an APL session with a MAXWS of 100 megabytes, which will start by creating the `linkdemo` namespace and calling `linkdemo.Start`. The namespace will be created using the directory named by the result of the function `⎕SE.Link.LaunchDir`; this will be the directory that the CONFIGFILE parameter refers to (or, if there is no CONFIGFILE, the directory referred to by the LOAD parameter).

The function `linkdemo.Start` will bring in the `stats` library using `Link.Import`: since we are not developers of this library, we don't want to create a bi-directional link that might allow us to accidentally modify it during our testing. It also creates the name `ST` to point to the stats library, which means that our `Run` function can use more pleasant names, like `ST.Mean` in place of `#.stats.Mean` - which also makes it easier to relocate that module in the workspace:
The function `linkdemo.Start` will bring in the `stats` library using `Link.Import`: since we are not developers of this library, we don't want to create a bi-directional link that might allow us to accidentally modify it during our testing. It also creates the name `ST` to point to the stats library, which means that our `Main` function can use more pleasant names, like `ST.Mean` in place of `#.stats.Mean` - which also makes it easier to relocate that module in the workspace:

```apl
∇ Start run
[1] ⍝ Establish development environment for the linkdemo application
[2]
[3] ⎕IO←⎕ML←1
[4] ⎕SE.Link.Import '#.stats' '/users/sally/stats' ⍝ Load the stats library
[5]
[5] ST←#.stats
[6] :If run
[7] Main
[8] ⎕OFF
Expand All @@ -92,11 +92,11 @@ We can now launch our development environment using `dyalog CONFIGFILE=linkdemo/

### Development vs Runtime

The `Start`function takes a right argument `run` which decides whether it should just exit after initialising the environment, or it should launch the application by calling `Run`and terminate the session when the user decides that the job is done.
The `Start` function takes a right argument `run` which decides whether it should just exit after initialising the environment, or it should launch the application by calling `Main` and terminate the session when the user decides that the job is done.

This allows us to create a second configuration file, `linkdemo/run.dcfg`, which differs from `dev.dcfg` in that we reserve a bigger workspace (since we'll be doing real work rather than just testing), and brings the source code in using `Link.Import` rather than `Link.Create`, which means that we won't waste resources setting up a file system watcher, and that accidental changes made by anyone running the application will not update the source files.

```json
```json5
{
Settings: {
MAXWS: "1G",
Expand All @@ -117,8 +117,7 @@ To prepare a workspace for shipment, we will need to:

### Scripted Applications

Recent versions of Dyalog APL support running APL from a script either by redirecting input to a normal APL interpreter or (recommended from version 18.2) using the new script engine. When the interpreter is running from a script, it intentionally provides you with a completely clean environment without any development tools loaded. This means that the session namespace is not populated, and Link is not loaded. If you add the following expression to the beginning of your script, it will (amongst other things) bring Link into the session so that the API becomes available:

`(⎕NS⍬).({}enableSALT⊣⎕CY'salt')`

Note that this depends on the interpreter being able to find the salt workspace (`salt.dws`). You may need to provide a full path name to that file, if you don't have a standard installation.
Recent versions of Dyalog APL support running APL from a script either by redirecting input to a normal APL interpreter or (recommended from version 18.2) using the new script engine. When the interpreter is running from a script, it intentionally provides you with a completely clean environment without any development tools loaded. This means that the session namespace is not populated, and Link is not loaded. If you add the following line to the top of your script, it will (amongst other things) bring Link into the session so that the API becomes available:
```apl
#! dyalogscript DYALOG_INITSESSION=1
```

0 comments on commit 6992cbe

Please sign in to comment.