hissp.basic module

Hissp’s basic macros.

These are automatically made available as unqualified macros in the Lissp REPL. To use them in a Hissp module, either use the fully-qualified names, or start with the prelude macro. You can abbreviate qualifiers with the alias macro:

(hissp.basic.._macro_.alias b/ hissp.basic.._macro_.)
;; Now the same as (hissp.basic.._macro_.define foo 2).
(b/#define foo 2)

The basic macros are deliberately restricted in design.

They have NO DEPENDENCIES in their expansions; they use only the standard library with no extra helper functions. This means that all helper code must be inlined, resulting in larger expansions than might otherwise be necessary. But because macros expand before runtime, the compiled code does not require Hissp to be installed to work, assuming, of course, that there are no other runtime imports of the library code.

These may suffice for small projects, but projects with access to better alternatives need not use the basic macros at all.

They also have no prerequisite initialization, beyond what is available in a standard Python module. For example, a _macro_ namespace need not be available for defmacro. It’s smart enough to check for the presence of _macro_ in its expansion context, and inline the initialization code when required.

With the exception of prelude (which is only meant for the top level), they also eschew any expansions directly to Python code, relying only on the built-in special forms quote and lambda, which makes their expansions compatible with advanced rewriting macros that process the Hissp expansions of other macros.

To help keep macros and their expansions manageable in complexity, these basic macros lack some of the extra features their equivalents have in Python or in other Lisps.

macros

hissp.basic._macro_.alias(alias, module)

Defines a reader macro abbreviation of a symbol prefix (such as a qualifier). For example,

(hissp.basic.._macro_.alias b/ hissp.basic.._macro_.)
;; Now the same as (hissp.basic.._macro_.define foo 2).
(b/#define foo 2)
hissp.basic._macro_.anyxH_for(variable, iterable, *body)

any-for Bind the variable and evaluate the body for each item from the iterable until any result is true (and return True), or until the iterable is exhausted (and return False).

hissp.basic._macro_.attach(target, *args)

Attaches the named variables to the target as attributes.

Positional arguments must be unqualified identifiers, and use that as the attribute name. Names after the : are attribute-value pairs. Returns the target.

hissp.basic._macro_.bxHASH_(raw)

b# bytes literal reader macro

hissp.basic._macro_.cascade(self, *calls)

Call multiple methods on one object.

Evaluates the given self, then injects it as the first argument to a sequence of calls. Returns the result of the last call.

hissp.basic._macro_.cond(*pairs)

Multiple condition branching.

Pairs are implied. Default is (). Use :else to change it. For example:

(cond)  ; ()
;; Assume some number 'x
(cond (operator..gt x 0) (print "positive")
      (operator..lt x 0) (print "negative")
      (operator..eq x 0) (print "zero")
      :else (print "not a number"))
hissp.basic._macro_.define(name, value)

Assigns a global in the current module.

hissp.basic._macro_.defmacro(name, parameters, docstring=(), *body)

Creates a new macro for the current module.

If there’s no _macro_, creates one (using types.ModuleType). If there’s a docstring, stores it as the new lambda’s __doc__. Adds the _macro_ prefix to the lambda’s __qualname__. Saves the lambda in _macro_ using the given attribute name.

hissp.basic._macro_.deftype(name, bases, *body)

Defines a type (class) in the current module.

Key-value pairs are implied in the body.

hissp.basic._macro_.ifxH_else(test, then, otherwise)

if-else Basic ternary branching construct.

Like Python’s conditional expressions, the ‘else’ clause is required.

hissp.basic._macro_.let(pairs, *body)

Creates locals. Pairs are implied. Locals are not in scope until the body.

hissp.basic._macro_.prelude()

Grants unqualified access to the basics.

Star imports from operator and itertools. And adds the basic macros, but only if available, so its expansion does not require Hissp to be installed. (This overwrites _macro_ if you already had one.)

hissp.basic._macro_.prog1(expr1, *body)

Evaluates each expression in sequence (for side effects), resulting in the value of the first.

hissp.basic._macro_.progn(*body)

Evaluates each form in sequence for side effects.

Evaluates to the same value as its last form (or () if empty).

hissp.basic._macro_.unless(condition, *body)

Unless the condition is true, evaluates each form in sequence for side effects. Evaluates to the same value as its last form. Otherwise, skips them and returns ().

hissp.basic._macro_.when(condition, *body)

When the condition is true, evaluates each form in sequence for side effects. Evaluates to the same value as its last form. Otherwise, skips them and returns ().

hissp.basic._macro_.xBAR_xBAR_(first=(), *rest)

|| ‘or’. Like Python’s or operator, but for any number of arguments.

hissp.basic._macro_.xET_xET_(*exprs)

&& ‘and’. Like Python’s and operator, but for any number of arguments.

hissp.basic._macro_.xH_xGT_(expr, *forms)

-> ‘Thread-first’.

Converts a pipeline to function calls by recursively threading it as the first argument of the next form. E.g. (-> x (A b) (C d e)) is (C (A x b) d e) Makes chained method calls easier to read.

hissp.basic._macro_.xH_xGT_xGT_(expr, *forms)

->> ‘Thread-last’.

Converts a pipeline to function calls by recursively threading it as the last argument of the next form. E.g. (->> x (A b) (C d e)) is (C d e (A b x)). Can replace partial application in some cases. Also works inside a -> pipeline. E.g. (-> x (A a) (->> B b) (C c)) is (C (B b (A x a)) c).