In computer language design, stropping is a method of explicitly marking letter sequences as having a special property such as being a keyword or certain type of variable or storage location, and thus inhabiting a different namespace from ordinary names ("identifiers"), avoiding clashes. Stropping is not used in most modern languages – instead, keywords are reserved words and cannot be used as identifiers. Stropping allows the same letter sequence to be used both as a keyword and as an identifier, and simplifies parsing in that case – for example allowing a variable named
if without clashing with the keyword if.
The method of stropping and the term "stropping" arose in the development of ALGOL in the 1960s, where it was used to represent typographical distinctions (boldface and underline) found in the publication language which could not directly be represented in the hardware language – a typewriter could have bold characters, but in encoding in punch cards there were no bold characters. The term "stropping" arose in ALGOL 60, from "apostrophe", as some implementations of ALGOL 60 used apostrophes around text to indicate boldface, such as
'if' to represent the keyword if. Stropping is also important in ALGOL 68, where multiple methods of stropping, known as "stropping regimes", are used; the original matched apostrophes from ALGOL 60 was not widely used, with a leading period or uppercase being more common, as in
IF and the term "stropping" was applied to all of these.
A range of different syntaxes for stropping have been used:
- Algol 60 commonly used only the convention of single quotes around the word, generally as apostrophes, whence the name "stropping" (e.g.
- Algol 68 in some implementations treat letter sequences prefixed by a single quote, ', as being keywords (e.g.,
In fact it was often the case that several stropping conventions might be in use within one language. For example, in ALGOL 68, the choice of stropping convention can be specified by a compiler directive (in ALGOL terminology, a "pragmat"), namely POINT, UPPER, QUOTE, or RES:
- POINT for 6-bit (not enough characters for lowercase), as in
.FOR– a similar convention is used in FORTRAN 77, where LOGICAL keywords are stropped as
.EQ.etc. (see below)
- UPPER for 7-bit, as in
FOR– with lowercase used for ordinary identifiers
- QUOTE as in ALGOL 60, as in
- RES reserved words, as used in modern languages –
foris reserved and not available to ordinary identifiers
The various rules regimes are a lexical specification for stropped characters, though in some cases these have simple interpretations: in the single apostrophe and dot regimes, the first character is functioning as an escape character, while in the matched apostrophes regime the apostrophes are functioning as delimiters, as in string literals.
- Atlas Autocode had the choice of three: keywords could be
underlinedusing backspace and overstrike on a Flexowriter keyboard, they could be introduced by a
%percent %symbol, or they could be typed in
UPPER CASEwith no delimiting character ("uppercasedelimiters" mode, in which case all variables had to be in lower case).
- ALGOL 68RS programs are allowed the use of several stropping variants, even within the one language processor.
Note the leading pr (abbreviation of pragmat) directive, which is itself stropped in POINT or quote style, and the ¢ for comment (from "2¢") – see ALGOL 68: pr & co: Pragmats and Comments for details.
as typically published
¢ underline or bold typeface ¢ mode xint = int; xint sum sq:=0; for i while sum sq≠70×70 do sum sq+:=i↑2 od
'pr' quote 'pr'
'mode' 'xint' = 'int';
'xint' sum sq:=0;
'for' i 'while'
|For a 7-bit character code compiler
.PR UPPER .PR MODE XINT = INT; XINT sum sq:=0; FOR i WHILE sum sq/=70*70 DO sum sq+:=i**2 OD
|For a 6-bit character code compiler
.PR POINT .PR
.MODE .XINT = .INT;
.XINT SUM SQ:=0;
.FOR I .WHILE
SUM SQ .NE 70*70
SUM SQ .PLUSAB I .UP 2
|Algol68 using res stropping
.PR RES .PR
mode .xint = int;
.xint sum sq:=0;
for i while
Most modern computer languages do not use stropping, with one notable exception. The use of many languages in Microsoft’s .NET Common Language Infrastructure (CLI) requires a way to use variables in a different language that may be keywords in a calling language. This is sometimes done by prefixes, such as
@ in C#, or enclosing the identifier in brackets, in Visual Basic.NET.
There are other, more minor examples. For example, Web IDL uses a leading underscore
_ to strop identifiers that otherwise collide with reserved words: the value of the identifier strips this leading underscore, making this stropping, rather than a naming convention.
Unstropping by the compiler
In a compiler frontend, unstropping originally occurred during an initial line reconstruction phase, which also eliminated whitespace. This was then followed by scannerless parsing (no tokenization); this was standard in the 1960s, notably for ALGOL. In modern use, unstropping is generally done as part of lexical analysis. This is clear if one distinguishes the lexer into two phases of scanner and evaluator: the scanner categorizes the stropped sequence into the correct category, and then the evaluator unstrops when calculating the value. For example, in a language where an initial underscore is used to strop identifiers to avoid collisions with reserved words, the sequence
_if would be categorized as an identifier (not as the reserved word
if) by the scanner, and then the evaluator would give this the value
(Identifier, if) as the token type and value.
A number of similar techniques exist, generally prefixing or suffixing an identifier to indicate different treatment, but the semantics are varied. Strictly speaking, stropping consists of different representations of the same name (value) in different namespaces, and occurs at the tokenization stage. For example, in ALGOL 60 with matched apostrophe stropping,
'if' is tokenized as (Keyword, if), while
if is tokenized as (Identifier, if) – same value in different token classes.
Using uppercase for keywords remains in use as a convention for writing grammars for lexing and parsing – tokenizing the reserved word
if as the token class IF, and then representing an if-then-else clause by the phrase
IF Expression THEN Statement ELSE Statement where uppercase terms are keywords and capitalized terms are nonterminal symbols in a production rule (terminal symbols are denoted by lowercase terms, such as
integer, for an integer literal).
Most loosely, one may use naming conventions to avoid clashes, commonly prefixing or suffixing with an underscore, as in
_then. A leading underscore is often used to indicate private members in object-oriented programming.
These names may be interpreted by the compiler and have some effect, though this is generally done at the semantic analysis phase, not the tokenization phase. For example, in Python, a single leading underscore is a weak private indicator, and affects which identifiers are imported on module import, while a double leading underscore (and no more than one trailing underscore) on a class attribute invokes name mangling.
While modern languages generally use reserved words rather than stropping to distinguish keywords from identifiers – e.g., making
if reserved – they also frequently reserve a syntactic class of identifiers as keywords, yielding representations which can be interpreted as a stropping regime, but instead have the semantics of reserved words.
This is most notable in C, where identifiers that begin with an underscore are reserved, though the precise details of what identifiers are reserved at what scope are involved, and leading double underscores are reserved for any use; similarly in C++ any identifier that contains a double underscore is reserved for any use, while an identifier that begins with an underscore is reserved in the global space.[a] Thus one can add a new keyword
foo using the reserved word
__foo. While this is superficially similar to stropping, the semantics are different. As a reserved word, the string
__foo represents the identifier
__foo in the common identifier namespace. In stropping (by prefixing keywords by
__), the string
__foo represents the keyword
foo in a separate keyword namespace. Thus using reserved words, the tokens for
foo are (identifier, __foo) and (identifier, foo) – different values in the same category – while in stropping the tokens for
foo are (keyword, foo) and (identifier, foo) – same values in different categories. These solve the same problem of namespace clashes in a way that is the same for a programmer, but which differs in terms of formal grammar and implementation.
Name mangling also addresses name clashes by renaming identifiers, but does this much later in compilation, during semantic analysis, not during tokenization. This consists of creating names that include scope and type information, primarily for use by linkers, both to avoid clashes and to include necessary semantic information in the name itself. In these cases the original identifiers may be identical, but the context is different, as in the functions
foo(int x) versus
foo(char x), in both cases having the same identifier
foo, but different signature. These names might be mangled to
foo_c, for instance, to include the type information.
A syntactically similar but semantically different phenomenon are sigils, which instead indicate properties of variables. These are common in Perl, Ruby, and various other languages to identify characteristics of variables/constants: Perl to designate the type of variable, Ruby to distinguish variables from constants and to indicate scope. Note that this affects the semantics of the variable, not the syntax of whether it is an identifier or keyword.
- There are other restrictions, such as an identifier that begins with an underscore, followed by an uppercase letter.
- Proceedings of an International Conference on ALGOL 68 Implementation: Department of Computer Science, University of Manitoba, Winnipeg, June 18–20, 1974, ed. Peter R. King, University of Manitoba. Dept. of Computer Science, p. 148 – More serious problems are posed by "stropping," the technique used to distinguish boldface text from roman text. Some implementations demand apostrophes around boldface (whence the name stropping); others require backspacing and underlining; ...
- Revised Report, p. 123, footnote
- van Wijngarten et al. (1976) Section 9.3
- Lindsey and van der Meulen (1977) pp.348-349
- Web IDL, "3.1. Names":
For all of these constructs, the identifier is the value of the identifier token with any single leading U+005F LOW LINE ("_") character (underscore) removed. Note
A leading "_" is used to escape an identifier from looking like a reserved word so that, for example, an interface named “interface” can be defined. The leading "_" is dropped to unescape the identifier.
- PEP 008: Descriptive: Naming Styles
- C99 standard, 7.1.3 Reserved identifiers
- A. van Wijngaarden et al. (1976). Revised Report on the Algorithmic Language ALGOL 68. Springer-Verlag. ISBN 0-387-07592-5. OCLC 1991170.
- C. H. Lindsey; S. G. van der Meulen (1977). Informal Introduction to ALGOL 68. North-Holland. ISBN 0-7204-0726-5. OCLC 230034877.
- W. J. Hansen; H. J. Boom (1978). "Report on the Standard Hardware Representation for Revised ALGOL 68". Acta Informatica 9: 105–119. doi:10.1007/BF00289072.
- C.H. Lindsey, "An ISO-Code Representation for ALGOL 68" ALGOL Bulletin AB31.3.6, Issue 31, March 1970, pp. 37–60 ACM