3 Compact and verbose syntax
ScienceLogo accepts compact, verbose, and mixed source with the same #lang sciencelogo header. A normalizer converts the spellings to compact source before the compact parser resolves names and applies language checks. Both spellings describe the same workflow and preserve its existing constraints. Source conversion accepts compact, verbose, or mixed input and produces either output form. A file needs no label identifying its input syntax.
Use the Compact and Verbose tabs on examples to choose a spelling. The choice applies to the other examples and is remembered across pages. When both versions are identical, the code appears once without tabs.
Compact
to estimate-period :duration :swings [ |
output :duration / :swings |
] |
trial = [duration = 20 swings = 10] |
do estimate-period trial.duration trial.swings as period |
print period |
Verbose
to estimate-period :duration :swings [ |
output :duration / :swings |
] |
set trial to [set duration to 20 set swings to 10] |
do estimate-period duration of trial swings of trial as period |
print period |
The example prints 2. Procedure definitions, :inputs, do, as, and output keep their familiar spelling.
3.1 Values and nested access
Compact | Verbose |
period = 2 | set period to 2 |
trial.period | period of trial |
experiment.trial.period | period of experiment.trial |
trial.period = 2 | set period of trial to 2 |
trials.[2] | [2] of trials |
trials.[1 3] | [1 3] of trials |
trial.[period unit] | [period unit] of trial |
trials.[2] = 3 | set [2] of trials to 3 |
target += value | update target with value |
trial.[period = 2] | trial with [set period to 2] |
Timing.[duration = 20] | Timing with [set duration to 20] |
period u [...] | period with uncertainty [...] |
Only the final access becomes of. The container keeps its dotted path: write period of experiment.trial. The rule also applies to procedure inputs, stage locations, count of trials, and u of period. Qualified procedure and interface names, such as tools.Timing, keep their existing names.
Within object brackets, set field to value supplies a field. Within an interface, it supplies a default. The same spelling creates or updates a local value at command position.
update target with value is exactly target += value. On a number, it adds; on a record, it merges fields; on a proposition, it adds a named child. On a list, it appends one complete item. List replacement uses = or set ... to ... on an indexed position:
Compact
values = [1 2] |
values.[2] = 3 ; values is now [1 3] |
values += [4 5] ; values is now [1 3 [4 5]] |
Verbose
set values to [1 2] |
set [2] of values to 3 ; values is now [1 3] |
update values with [4 5] ; values is now [1 3 [4 5]] |
A standalone multi-field update can be written by assigning a changed value back to the same name:
Compact
trial.[unit = "minutes" duration = 3] |
Verbose
set trial to trial with [set unit to "minutes" set duration to 3] |
3.2 Conditions and control flow
Compact | Verbose |
a == b | a equals b |
a != b | a does not equal b |
a < b | a is less than b |
a <= b | a is at most b |
a > b | a is greater than b |
a >= b | a is at least b |
a xor b | a exclusive or b |
value in values | is value in values |
notes in trial | is notes in trial |
period is number | is period a number |
trial is Timing | is trial a Timing |
range a to b step c | range from a to b with step c |
repeat 3 [...] | repeat 3 times [...] |
if condition [...] | if condition then [...] |
else if condition [...] | else if condition then [...] |
Arithmetic operators, and, or, not, else, while, for each ... in ..., and repeat [...] until ... stay shared. Operator precedence follows the Compact grammar rules.
3.3 Stages, interfaces, and libraries
Compact | Verbose |
stage measure | start stage measure |
end stage with state [...] | end stage with state [...] |
measure implement Protocol.measurement | measure implements Protocol.measurement |
affects measurement analysis | measurement affects analysis |
must stages in order [prepare measure] | must do stages in order [prepare measure] |
duration is number | duration is a number |
duration = unknown number | set duration to unknown number |
import "URL" at "version" as tools | import library from "URL" at "version" as tools |
The type declaration duration is a number belongs inside an interface; is duration a number asks a question about a value. interface, version, extends, must, must do name, include, library, performer, resource, hypothesis, assumption, conclusion, workflow, and about stay shared. Their fields can use either assignment spelling at every depth. The existing implements "file.rkt" as alias [provide ... by "..."] file-reference form also stays shared.
A paired stage can use start stage measure by observer from state [...]; its closing end stage with state [...] remains identical. Its calls use the existing input and output words, with optional of access for locations:
Compact
do estimate-period with [ |
duration at information.elapsed |
swings at information.swing-count |
] into information.period |
Verbose
do estimate-period with [ |
duration at elapsed of information |
swings at swing-count of information |
] into period of information |
Both entry and exit state objects remain required for paired stages. Performer rules, state restrictions, interface requirements, and resource-only external data references apply equally to compact and verbose spellings.
3.4 Mixed source and preservation
Either spelling can appear inside the other:
set trial to [duration = 20 set swings to 10] |
period = trial.duration / swings of trial |
if period >= 2 and not (is notes in trial) then [ |
print period |
] |
Names remain unquoted and case-sensitive, with optional capitalization and hyphen conventions. Quoted strings, Markdown in about, ; comments, and nested #| ... |# comments retain their contents. Every explicit parenthesis group is retained, including redundant and nested groups. The normalizer also retains a source location for each output character, so reader diagnostics can refer to the original source.
The verbose syntax specification gives the complete equivalences and preservation contract.
3.5 Convert a source file
Choose the output syntax on the command line:
racket -l sciencelogo/translate -- --to verbose investigation.rkt |
racket -l sciencelogo/translate -- --to compact investigation.rkt |
The converter writes the converted source to standard output. Either command accepts a compact, verbose, or mixed file. To save the result, redirect it to a different file:
racket -l sciencelogo/translate -- --to verbose investigation.rkt > investigation-verbose.rkt |
Each invocation converts one file. Source dependency paths and qualified definition names retain their references. In verbose output, containing paths stay dotted and shared forms keep their spelling, as specified above. The converter retains code indentation and line endings while normalizing spacing between tokens. Repeated conversion does not accumulate indentation or spaces. Strings, comments, and existing parentheses are retained.
3.6 Source conversion API for applications
The Racket API is sciencelogo/normalize; sciencelogo/translate also exports it. normalize-source produces compact source. translate-source accepts either spelling or any mixture and requires #:to ’compact or #:to ’verbose to choose the output.
(require sciencelogo/normalize) |
|
(define result |
(translate-source "period = 2\n" #:to 'verbose #:source 'example)) |
|
(normalized-source-text result) |
(normalized-source-origin result 1) |
The output text in this example is "set period to 2\n". Both functions accept a string, with optional #:source, #:line, #:column, and #:position. Defaults are #f, 1, 0, and 1. Both return a normalized-source whose text is source in the selected output syntax and whose origins is an immutable vector.
normalized-source-origin accepts that result and a one-based position in its text, including the position immediately after its last character. It returns a source-origin with source, line, column, position, and span. Lines and positions start at one; columns start at zero. The EOF entry has span zero. Verbose conversion retains the original locations through both passes: normalization to compact, then generation of verbose source. Other SDKs can use the same sequence and keep one compact parser and set of language checks. Conversion recognizes source forms; parsing, name resolution, and language checks determine whether the result is a valid workflow.