On this page:
12.1 Split one workflow across files
12.2 Library syntax
12.3 Make a small library
12.4 Import and call it
12.5 Share a record interface
9.3

12 Files and libraries🔗ℹ

Use include to split one workflow across local files. Use import to reuse a versioned library from another Git repository. A ScienceLogo library is one Git repository with a main branch and a library.rkt file at its root. Importing makes its procedures and record interfaces available.

12.1 Split one workflow across files🔗ℹ

Every included file begins with #lang sciencelogo. Its path starts at the directory of the file containing include; it must stay in the same Git repository. An included workflow file has no workflow title or import and can include more files. For example, these three paths are in one repository:

method.rkt:

#lang sciencelogo

workflow "Pendulum trial"

include "methods/period.rkt"

do period 20 10 as seconds-per-swing

print seconds-per-swing

methods/period.rkt:

#lang sciencelogo

include "../shared/divide.rkt"

to period :seconds :swings [

  do divide :seconds :swings as result

  output result

]

shared/divide.rkt:

#lang sciencelogo

to divide :total :count [output :total / :count]

The reader assembles and validates the workflow before running it. Missing files, duplicate includes, and cycles are errors. include does not create a local scope.

12.2 Library syntax🔗ℹ

Form

Rule

library name [ ... ]

One declaration in the root library.rkt file; contains imports, includes, procedures, and record interfaces

import "Git URL" at "tag or commit" as alias

Directly in a library block, or at the top of an entry workflow

include "relative/path.rkt"

Loads a file relative to the file containing this include

do alias.procedure ...

Calls an imported procedure

alias.Interface

Names an imported interface in construction, inheritance, is tests, and implement mappings

The URL begins with https:// or file://. at selects a tag or full commit ID reachable from the library’s main branch, not a branch name. An alias is local to the file that declares the import. A library may import another library; a workflow imports that dependency itself if it needs to use the dependency’s procedures or interfaces directly. Importing a library never runs its procedures.

12.3 Make a small library🔗ℹ

Create a separate directory named hello-world. Save this as its library.rkt:

#lang sciencelogo

 

library hello-world [

  to greeting [output "Hello, world!"]

]

The greeting procedure returns text. Loading the library does not print it. In that directory, initialize and tag the Git repository:

git init --initial-branch=main

git add library.rkt

git -c user.name="ScienceLogo example" -c user.email="example@example.invalid" commit -m "Add greeting library"

git tag v1.0.0

12.4 Import and call it🔗ℹ

Save the following investigation in another file. Replace the example file:// URL with the absolute path to your hello-world directory:

Compact

#lang sciencelogo

 

workflow "Try a library"

import "file:///absolute/path/to/hello-world" at "v1.0.0" as hello

do hello.greeting as message

print message

Verbose

#lang sciencelogo

 

workflow "Try a library"

import library from "file:///absolute/path/to/hello-world" at "v1.0.0" as hello

do hello.greeting as message

print message

The at value selects a tag or full commit ID reachable from main; it does not select a branch. hello is the local alias for this import. The call returns "Hello, world!" as message, and the investigation displays it. The reader resolves and validates the library before running the investigation.

12.5 Share a record interface🔗ℹ

A library can also define a data interface, with required fields and defaults grouped inside must [...]; see Records and interfaces. In library.rkt:

Compact

#lang sciencelogo

 

library timing [

  interface Timing [must [duration unit = "seconds"]]

]

Verbose

#lang sciencelogo

 

library timing [

  interface Timing [must [duration set unit to "seconds"]]

]

After committing and tagging that repository, a workflow can import and use it:

Compact

import "file:///absolute/path/to/timing" at "v1.0.0" as timing

interface Timed-place [extends timing.Timing must [place]]

trial = Timed-place.[duration = 2 place = "lab"]

trial implement timing.Timing

Verbose

import library from "file:///absolute/path/to/timing" at "v1.0.0" as timing

interface Timed-place [extends timing.Timing must [place]]

set trial to Timed-place with [set duration to 2 set place to "lab"]

trial implements timing.Timing

The alias qualifies the interface name just as it qualifies a procedure name. Interfaces may also be placed in included library files. An included file can use include "../shared/file.rkt" from a subdirectory: the path starts at the directory containing that include, and must stay in the same repository.

For larger libraries, the root library.rkt can contain include "relative/path.rkt" declarations and imports of other libraries. Included files contain top-level to, record interface, and include declarations. A dependency alias stays inside the library that declared it; a workflow imports that dependency separately if it needs to use its procedures or interfaces directly. The library specification has the full layout and dependency rules.