Variables and Types in SNOBOL
Learn how SNOBOL handles dynamically typed variables, automatic conversions, and pattern values as first-class data
SNOBOL4 has one of the most permissive type systems of any classic language. There are no type declarations, no var or let keywords, and no fixed types attached to names — a variable simply becomes whatever value you assign to it, including patterns, tables, and arrays. This freedom is essential to SNOBOL’s pattern-directed paradigm: because patterns are themselves first-class values that you build at runtime, the language cannot meaningfully restrict what a variable holds.
SNOBOL is dynamically and weakly typed. Strings, integers, and real numbers convert automatically when an operator or built-in expects a particular form. Add 1 to "100" and SNOBOL silently produces the integer 101; concatenate a number into a string and the number quietly becomes its string representation. The type machinery is invisible most of the time, but DATATYPE() lets you peek at what a value actually is.
This tutorial covers how variable assignment works in SNOBOL, the built-in data types you will meet, the rules for automatic and explicit conversion, and how unset variables and patterns fit into the picture.
Variable Assignment and Built-in Types
A SNOBOL variable comes into existence the moment you assign to it. The same name can hold an integer on one line, a string on the next, and a pattern after that. The built-in DATATYPE() function returns the current type as a string such as INTEGER, STRING, REAL, PATTERN, ARRAY, or TABLE.
Create a file named variables.sno:
| |
A few things to notice:
EMPTY =with nothing on the right assigns the null string, which is also the value every unreferenced variable starts with. SNOBOL has no separatenullornil— the empty string plays both roles.- Adjacent values such as
"COUNT = " COUNTare concatenated. There is no+for strings; juxtaposition is the operator. - Variable names are conventionally uppercase. SNOBOL is case-sensitive, and lowercase names are valid but unusual.
Automatic Type Conversion
Because SNOBOL is weakly typed, operators drive conversion. Arithmetic operators force their operands toward numbers; string contexts force them toward strings. There is no error for “wrong type” as long as the value can be reasonably interpreted.
Create a file named conversions.sno:
| |
CONVERT(value, target) is the explicit form. It fails (in SNOBOL’s success/failure sense) if the conversion is impossible, which lets you branch on :F(label) to handle bad input. Implicit conversion, by contrast, simply applies whenever an operator demands a particular type.
Patterns as First-Class Values
The most distinctive thing about SNOBOL’s type system is that patterns are values. ANY, SPAN, BREAK, and friends construct pattern objects you can store in variables, combine with concatenation and alternation, and pass around just like strings or numbers. This is what makes SNOBOL “pattern-directed” rather than merely “string processing.”
Create a file named patterns_as_data.sno:
| |
Two SNOBOL features make this example work:
- The
.operator binds the matched substring to a variable. AfterWORD VOWEL . Vruns,Vholds the single character that matched. The captured value is a STRING, even though it came from a PATTERN match. - Statements end with goto labels.
:F(NOMATCH)jumps to theNOMATCHlabel if the match fails. Without goto control, a failed match would simply skip the rest of that single statement and continue with the next one.
Running with Docker
| |
Expected Output
Running variables.sno:
COUNT = 42
GREETING = Hello
PI = 3.14159
EMPTY = ''
type of COUNT = INTEGER
type of GREETING = STRING
type of PI = REAL
type of EMPTY = STRING
Running conversions.sno:
'100' + 25 = 125
type of N = INTEGER
7 + 0.5 = 7.5
type of MIX = REAL
concat result = answer=42
type of LABEL = STRING
CONVERT(3.14,'STRING') = 3.14 (STRING)
CONVERT('256','INTEGER') = 256 (INTEGER)
Running patterns_as_data.sno:
type of VOWEL = PATTERN
type of NUMBER = PATTERN
first vowel in 'snobol4' is: o
trailing number is: 4 (STRING)
Key Concepts
- No declarations. A variable is created on first assignment; its type comes from whatever value is bound to it.
- Dynamic, weak typing. Operators coerce operands as needed:
"100" + 25produces an integer,"x=" 42produces a string. - The null string is the universal default. Unset variables read as
"", and there is no separate null/nil concept. - Built-in
DATATYPE()returns the current type name (INTEGER,REAL,STRING,PATTERN,ARRAY,TABLE, …). - Numbers convert in both directions. Strings that look numeric become numbers under arithmetic; numbers become strings under concatenation.
CONVERT()does it explicitly and can fail. - Patterns are first-class values.
ANY,SPAN,BREAKand others build pattern objects you can store, combine, and reuse — this is the foundation of SNOBOL’s whole programming model. - Names belong in column 1; statements do not. Any line whose first character is non-blank is treated as a label, so always indent assignments and matches.
Running Today
All examples can be run using Docker:
docker pull esolang/snobol:latest
Comments
Loading comments...
Leave a Comment