Glossary#
- abstract syntax tree#
- ast#
An intermediate tree data structure used by most compilers after parsing a programming language. The AST stage of Lissp is Hissp, and Lissp is a pretty direct representation of it.
- anaphor#
- anaphoric macro#
An anaphoric macro creates one or more lexical (local) variable bindings without explicitly naming them. Such a bound name is called an anaphor.
- atom#
A
formthat is either the empty tuple()or not of typetuple. Atoms are the leaf elements of Hisspâs syntax trees, while non-empty tuples are the nodes.is_nodetests for the non-leaves, so its negation tests for atoms.- bare token#
An
object tokenwithout the initial character marking it as acomment token(;),Unicode token("),fragment token(|), orcontrol token(:). It is either aliteral token, or failing that, asymbol token.- comment token#
An
object tokenconsisting of one or more lines, possibly indented with spaces, each starting with a semicolon (;) character. Comment tokens read ashissp.reader.Commentinstances, a type that is normally discarded by the reader. However, they can still be arguments for atagging token.- control token#
An
object tokenthat begins with a colon:character. It reads as acontrol word, a type ofstr atom.- control word#
A
str atomthat begins with a colon:character. These normally compile directly to Python string literals with the same contents (including the leading colon), but may have special interpretation in some contexts. (Both Python and other Lisps use the term âkeywordâ, but they meandifferent things, including Lispâs equivalent concept.)is_controltests for control words.- discard tag#
- discarded item#
_#. Aspecial tagused to structurally disable parts of code during development, for commentary, or as adoorstop. The argument to a discard tag is the discarded item. It is unique amongtagging tokens in that it doesnât return aparsed objectat all. Although atagcould achieve a similar effect by returning a (normally discarded)hissp.reader.Commentinstance or by consuming twoparsed objects and returning the second one unchanged, the discard tag (like allspecial tags) is unary, making it applicable to the last (or only) element in a tuple (such as adoorstop), and a discarded item cannot be an argument to another tagging token, unlike aCommentinstance, which allows its use for commentary between atagging tokenand one of its arguments.- doorstop#
A
discarded itemused to âhold openâ a bracket trail or avoid a))in line. Any discarded item used this way is functionally a doorstop, but, in Lissp, the typical style starts with_#/and may continue with a label of what form the next)is closing, like_#/foo, similar to XML tags.- eof#
End-of-file. In most Unix terminals, use a Ctrl+D, or Ctrl+Z Enter in Windows. Quits a subREPL without also terminating the Python session, unlike
(exit), and works similarly in most shells.- form#
An object meant for evaluation; a Hissp expression for passing to the Hissp compiler.
- fragment#
A
fragment token,fragment atom, orpython fragment, depending on context.- fragment atom#
A
str atomthat is not acontrol word, especially if it does not simply contain an identifier or literal. So called because the compilerâs usual interpretation is to emit the contents directly (making the contents aPython fragment), although there is a preprocessing step for imports (seemodule handle).- fragment token#
An
object tokenthat begins and ends with a vertical line (|) character. Internal vertical lines must be escaped as two vertical lines (||). It reads directly as astr atom, which typically becomes afragment atom, hence the name. In the case that the fragment token begins with|:, it becomes acontrol wordinstead.- full qualifier#
- full qualification#
- fully-qualified identifier#
A
module handleprepended to aqualified nameand separated with a.is a fully-qualified identifier; itâs the path of attribute access from the full import path of the module, which is enough to get a reference to the object from anywhere. Compiles to attribute access from an__import__expression. E.g.,foo.bar.baz..spam.eggs.bacon, or, with fewer segments,foo..spam. The full qualifier part is everything but the last segment, commonly used as an argument toalias. Full qualification is the process of adding a full qualifier or the state of having a full qualifier.- gensym#
- gensym hash#
A generated
symbol. These are produced by thegensym tag. A gensym hash is unique to the template it was created in. This prevents accidental name collisions inmacro expansions. A gensym hash is mostly used for local variables because they canât be disambiguated with afull qualifier.- gensym tag#
$#. Aspecial tagonly valid in atemplatefor creating agensym. Prepends agensym hashto its argument, or replaces$characters with it.- hissp#
The project at https://github.com/gilch/hissp. The package produced by the project. The language of Python data structures used by the project, which
hissp.compilercan transpile into executable Python code. The Python data structures encoding this language: aform, or a series of them. This is also theASTstage ofLissp, a programming language implemented in terms of Hissp.- hissp injection#
Any
atomofnonstandardtype (or the use thereof), i.e., anything the compiler doesnât have a literal notation for, which it would have to attempt to emit as apickle expression. This includes instances of standard types without a literal notation (e.g.,floatis a standard type, butmath.nanhas no literal) or collections containing nonstandard elements or cycles. Amacro expansionmay be an injection. Besides macro expansions, in readerless mode, this almost always requires the use of non-literal notation, (i.e., notation not accepted byast.literal_eval). In Lissp, this almost always requires the use of atagging token. (A notable exception is a float literal big enough in magnitude to overflow toinfor-inf, e.g.,1e999. The compiler still considers this nonstandard because thatâs not itsrepr, and would emit apickle expressionfor it.) Basic container types containing only standard elements do not count as injections, because the compiler has a notation for them, even though Lissp doesnât.- hissp string#
A
formorparsed objectwhich would directly represents a string in Hissp, if evaluated on its own. Allstring literal fragments are Hissp strings. Aquotedstr atomis also a Hissp string.is_hissp_stringtests for Hissp strings.- inject#
- inject tag#
.#. Aspecial tagwhich evaluates the nextparsed objectand returns its result. So named because itâs typically used to make aninjection, although it can result in an object of any type.- injection#
Either a
Python injectionor aHissp injection, depending on context.- invocation#
- invoke#
- invoking#
A tuple
formthat looks like a function call is an invocation. May actually compile to a run-time function call, or may instead be aspecial formormacro form, which calls amacroat compile time. Or the process of making such a call.- kwarg token#
A single-argument
tagging tokenending in an equals sign (=) and read as ahissp.reader.Kwarginstance. Used as keyword arguments for atag.- literal token#
A
bare tokenthat is a valid Python literal, as determined byast.literal_eval, but not of a container type. It reads as anatomof that type.- macro#
A
macro functionormacro form, depending on context.- macro expansion#
- expansion#
- macro form#
A
formwhich represents some otherform, called itsexpansion. Compilationinvokes amacroto make the substitution.- macro function#
A
metaprogrammeant to run at compile time. A callable attribute of a_macro_namespace.- metaprogram#
- metaprogramming#
A metaprogram is a program that writes code. Typically, this means the callable referred to by
tagormacrosyntax, or helper functions used for abbreviations inreaderless mode. But the compiler itself is also a kind of metaprogram. Metaprogramming is the process of writing metaprograms.- module handle#
A
str atomcontaining a.-separated path ending in a., representing an import path for a module. Any segments before the module name are package names. E.g.,foo.bar.baz.orfoo.. The compiler processes it into a__import__expression before emission.- munging#
The process of replacing characters invalid in a Python identifier with
Quotezequivalents. Primarily used to make asymbol tokeninto astr atomcontaining a valid Python identifier (asymbol). The munging machinery is inhissp.munger.- object token#
A type of
tokenwhich by itself results in aparsed objectwhen passed to the Lissp parser. These are what the reader considers nouns. Typically emitted as anatom, but may instead be arguments to atagging token.- params#
- params tuple#
- params symbol#
The first argument to the
lambdaspecial form. It represents the lambda parameters. Typically either a tuple or astr atom, but other iterables can work. Also amacroargument that becomes the whole params argument in a lambda expansion, such as the first argument tolet-fromorany*map. The equivalent concept is called the âlambda listâ in Common Lisp, and the âparams vectorâ in Clojure, but Hissp is made of tuples, not linked-lists or vectors, hence âparams tupleâ when written with a tuple.- parsed object#
The result of parsing an
object token; or atagging tokenwith its arguments (except thediscard tag); or a balanced pair of parentheses (open(and close)tokens), with their contents (if any). Typically emitted as aform, but may instead be arguments to atagging token.- pickle expression#
The compilerâs final fallback emission when it doesnât have a literal notation for an
atom. Itâs an import ofpickle.loadspassed abytesliteral containing a serialization of the object. Evaluating it should result in an equivalent object.- python fragment#
A piece of Python code, especially one emitted by the compiler. Typically a Python expression, but not necessarily anything complete. The compiler assembles and emits fragments to produce compiled output.
- python injection#
The technique of writing a
Python fragmentrather than allowing the Hissp machinery to do it for you, or the fragments so used or thefragment atomcontaining one. Atext macroworks via Python injection. Injection is discouraged because it bypasses a lot of Hisspâs machinery, and is opaque to code-walking macros, making them less useful or risking errors. However, the compiler only targets a subset of Python expressions. Injection transcends that limitation. Injection of identifiers is consideredstandardin Hissp, so is not discourarged. A LisspUnicode tokenreads as astring literal fragment, rather than as aquotedstr atom, making them an example of injection as well. This usage isstandardin Lissp.- qualifier#
- qualification#
- partial qualification#
- partially qualified identifier#
A
str atomcontaining a.-separated identifier path prepended to an identifier is a qualified identifier. Compiles to Python attribute access syntax. If this is the path from the containing module, the result is aqualified name. If this includes amodule handle, itâsfull qualification, if qualification is not full, itâs partial. Aqualified nameis partial qualification, but partial qualification is not necessarily aqualified name, because the path may start from some namespace other than the module globals. The qualifier part is everything but the last segment. Qualification is the process of adding a qualifier or the state of having a qualifier.hissp.macros._macro_.aliasproduces atagto abbreviate a qualifier.- quote#
- hard quote#
'. Aspecial tagabbreviating thequotespecial form. Sometimes called a âhard quoteâ to distinguish it from thetemplate quote.- quotez#
The
mungerâs character replacement format. Itâs the characterâs Unicode name wrapped inQzand_. (Spaces becomexand hyphens becomeh.) Characters without names use their hexadecimal ordinals instead. Some ASCII characters use the short names fromTO_NAMEinstead. Thegensymhashes andhissp.compiler.MAYBEuse the sameQz{}_wrapper.- read time#
The phase before compilation proper that translates Lissp to Hissp: when the
readerruns and whentagging tokens are activated.- readerless mode#
A representation of
forms in the Python language using mostly literals. Hissp written this way does not require the use of a reader, hence itâs the âreaderlessâ mode of writing Hissp.- repl#
- read-evaluate-print loop#
- read-eval-print loop#
The
LisspREPL, Lisspâs interactive interpreter shell, layered on Pythonâs. (Or a similar language shell.) Reads Lissp input, compiles it to Python, and passes it to Pythonâs shell for evaluation and printing, then repeats. Used for inspection, online help, interactive development, and debugging. A subREPL is just a REPL started from within a REPL, analogous to a subshell.- special form#
A
formspecial-casedin the compiler. These are tuples beginning with either aquoteorlambdastr atom. They look like function calls but act more like macros, in that arguments are not all evaluated first. While acontrol wordis aformand can have special interpretations in certain contexts, they are not considered special forms.module handles also have a processing rule in the compiler, but arenât considered special forms.- special tag#
One of the built-in unary
tagging tokens treated as aspecial casein thereader.- splice#
- splicing unquote#
,@. Aspecial tagonly valid in atemplate. Its argument is interpolated and unpacked rather than quoted first.- standalone property#
When the compiled Python output of Hissp doesnât depend on the
hissppackage, it can run in a Python environment that doesnât havehisspinstalled. Hissp was designed for this, but it can be lost by adding ahisspimport explicitly. Using Hisspâsmetaprogramminghelpers only in metaprograms (or in metaprogramming helper functions only called by metaprograms) is fine because metaprograms only run at compile time (orread time), so they wonât crash at run time even whenhisspcannot be imported. Forgetting to remove or disable import oftranspileused in main or a package__init__is another way the standalone property can be lost.- standard#
- nonstandard#
The standard language is a disciplined subset with full generality. Standard (
readerless mode) Hissp usesstr atoms only forcontrol words andsymbols (which include imports and attribute access) and avoids otherPython injections. Standard Lissp also usesstr atoms forstring literal fragments. (Standard readerless mode instead compiles string literals exclusively via the quotespecial form, or nested inset,dict, orlistatoms.) Other Python injections are considered nonstandard. Nonstandard constructions should be used sparingly and with care. Metaprograms are not necessarily expected to handle nonstandard Python injections, because that would require processing the much more complicated language of Python expressions, but not all nonstandard injections are problematic. The bundled tags and macros mostly avoid nonstandard injections in expansions, but (with the notable exception ofmix) allow them where they would be no worse than an opaquefully-qualified identifier, or in a few cases where the user writes part of the injection. Standard Hissp also avoids importing thehissppackage outside of metaprograms (and direct helpers not otherwise called) to preserve thestandalone property. Standard atom types are those the compiler has a literal notation for. Use of nonstandard types can result in apickle expressionor a crash during compilation (if the atom is unpickleable).- stararg token#
One of
*=or**=. Aspecial tagwhich reads as ahissp.reader.Kwarginstance. Used as unpacking positional or keyword arguments (respectively) to atag.- str atom#
An
atomof typestr. Usually represents aPython fragment. If it starts with a colon (:), it is acontrol word. May contain amodule handle.- string literal fragment#
A
Python fragmentwhichast.literal_evalwould evaluate to an object of typestr. Not allstr atoms are string literal fragments; it must contain a Python string literal expression.is_string_literaltests for string literal fragments.- subform#
A
formnested inside a tuple form; a Hissp subexpression. An (e.g.)params tupleisnât aform, so itâs not a subform either, but a default argument inside it would be. Similarly, macro arguments donât necessarily count as subforms.- symbol#
A
module handleor aPython fragmentcontaining anidentifier. (Possibly withqualification.) A symbol is always astr atom.is_symboltests for symbols. Some identifiers arereservedin Python and canât be used as variable/attribute names (Boolean operations,None,class, etc.) These still count as symbols.- symbol token#
A
bare tokenthat is not aliteral token. These are subject tomungingand read as asymbol, a type ofstr atomused for identifiers.- tag#
- tag token#
- hash tag#
- module-local tag#
- fully-qualified tag#
A
tagging tokenthat ends in one or more number sign (#) characters (also known as âhashâ characters, making these âhash tagsâ when distinguishing them from othertagging tokens.) If it includes amodule handlepart, itâs a fully-qualified tag. Any callable accessible this way can be applied as a tag. E.g.builtins..str.format##,fractions..Fraction#,textwrap..dedent#, etc. If it doesnât, it refers to a module-localmetaprogramstored in the moduleâs_macro_namespace. These usually need to be pure or at least idempotent, as theREPLor similar tooling may have to make multiple attempts at applying them.- tagging token#
A type of
tokenthat, when read, consumes one or moreparsed objects and results in aparsed object. These can be thought of as reader adjectives. They serve a function similar to reader macros in other Lisps, but operate on theparsed objectstream (parser level), not the raw character stream (lexer level). Think Clojure/EDN tags, not Common Lisp reader macros.- template#
A
template quoteand its argument, a domain-specific language (DSL) for creating aform, supporting tuple interpolation,gensyms, and automaticfull qualification. Can also be used for data, not just code. Typically used in the definition of amacro function.- template quote#
- soft quote#
`. Aspecial tagstarting atemplate. The equivalent concept is called a âquasiquoteâ or âsyntax quoteâ in other Lisps.- text macro#
A
macrothatexpandsto astr atominstead of some otherform, especially if thestr atomdoesnât simply contain a string literal or (possibly qualified) identifier. Effectively, they return Python code, rather than Hissp, which makes them opaque to Hisspmetaprogramming, like pre-expanding, code-walking macros.- token#
A lexical unit of Lissp. This is how the
readerchunks Lissp in preparation for parsing. Some are considered implementation details, but a Lissp programmer should be able to mentally parse the language.- top level#
- top-level form#
A form not nested inside another form, or the location of such a form. âTopâ here means the top of the syntax tree rather than the top of the file. Each top-level form is a compilation unit. A macro defined in a top-level form cannot affect any other
subformin the same top-level form, because by the time it exists, the top-level form has already been compiled.Injectionof a Python statement is only valid at the top level.- unicode token#
An
object tokenthat begins and ends with a quotation mark (") character. They may contain newline characters like Pythonâs triple-quoted string literals, as is typical of Lisps. Internal quotation marks must be escaped with a preceding reverse solidus (\) character. It reads as astring literal fragment, specifically, astr atomcontaining a Python string literal wrapped in parentheses.- unqualified#
An identifier without a
qualifier. An unqualifiedtagis only valid if itâs available as an attribute in the current moduleâs_macro_namespace, and similarly for an unqualifiedmacro. A unqualified variable is valid if itâs in thebuiltinsmodule, a global of the current module, or a variable in the current lexical scope.- unquote#
,. Aspecial tagonly valid in atemplate. Its argument is directly interpolated rather than quoted first.