Skip to content

Latest commit

 

History

History
464 lines (298 loc) · 21.9 KB

specialforms.rst

File metadata and controls

464 lines (298 loc) · 21.9 KB

Special Forms

Special forms are the building blocks of any Lisp. Special forms are fundamental forms which offer functionality directly from the base distribution.

Primary Special Forms

Intern the value expr with the name name as a Var <vars> in the current namespace (the namespace pointed to by :lpy*ns* in the current thread).

name should be an unqualified symbol <symbols>. If a namespace is included with the symbol, it will be silently discarded by the compiler. Metadata <metadata> applied to the symbol name will be copied and applied to the interned Var. Common Var metadata applied via def include ^:private, ^:dynamic, and ^:redef.

expr may be any valid expression.

If no expression is expression is given, the Var is interned unbound <unbound_vars>.

If a docstring is provided, the value of the docstring will be accessible on the :doc key of the Var meta. Docstrings must be string literals <strings>. References to names or Vars containing strings will be cause a compile-time error.

(def my-var "Cool docstring!" :a-value)

(:doc (meta (var my-var)))  ;;=> "Cool docstring!"
(:doc (meta #'my-var))      ;;=> "Cool docstring!"

Note

By convention, def forms should only be used at the top level of a namespace file. While it is entirely legal to def a value within a function, the results of interning the Var within the function still apply to the current namespace. Within a function or method context, users should use the :lpylet special form to bind a value to a name in that scope.

Wrap zero or more expressions in a block, returning the result of the last expression in the block. If no expressions are given, return nil.

Create a new anonymous function accepting zero or more arguments with zero or more body expressions. The result of calling the newly created function will be the final expression in the body, or nil if no body expressions are given.

Anonymous functions may optionally be given a name which should be an unqualified symbol <symbols>. Function names may be useful in debugging as they will be used in stack traces.

Function arguments should be symbols given in a vector <vectors>. Functions may be defined with zero or more arguments. For functions with a fixed number of positional arguments, it is a runtime error to call a function with the wrong number of arguments. Functions may accept a variadic number of arguments (called "rest" arguments by convention) by terminating their argument list with & rest, with rest being any symbol name you choose. Rest arguments will be collected into a sequence which can be manipulated with the Basilisp sequence functions.

Note

Arguments in fn forms support destructuring which is an advanced tool for accessing specific portions of arguments.

Functions may be overloaded with one or more arities (signature with different numbers of arguments). If a function has multiple arities, each arity should appear in its own list <lists> immediately after fn symbol or name if one is given.

Warning

All arities in a multi-arity function must have distinct numbers of arguments. It is a compile-time error to include two or more arities with the same number of arguments.

Warning

Multi-arity functions may only have zero or one arities which include a rest argument. It is a compile-time error to include multiple arities with rest arguments.

Warning

For multi-arity functions with a variadic arity, the variadic arity must have at least the same number of positional arguments as the maximum number of positional arguments across all of the remaining arities. It is a compile-time error to include a variadic arity in a multi-arity function with fewer fixed positional arguments than any other arity.

Note

Functions annotated with the :async metadata key will be compiled as Python coroutine functions (as by Python's async def). Coroutine functions may make use of the :lpyawait special form.

Evaluate the expression test, returning true-expr if test is truthy and false-expr otherwise. If no false-expr is given, it defaults to nil.

true-expr and false-expr may only be single expressions, so it may be necessary to combine if with :lpydo for more complex conditionals.

Note

In Basilisp, only nil and false <boolean_values> are considered false by if -- all other expressions are truthy. This differs from Python, where many objects may be considered falsey if they are empty (such as lists, sets, and strings).

:lpyand, :lpyor, :lpyif-not, :lpywhen, :lpywhen-not

Call the method method of obj with zero or more arguments.

method must be an unqualified symbol <symbols>.

Note

Methods prefixed with a - will be treated as property accesses :lpy.-, rather than method calls.

accessing_object_methods_and_props

Access the attribute attr on object obj.

attr must be an unqualified symbol <symbols>.

accessing_object_methods_and_props

Basilisp-specific Special Forms

The special forms below were added to provide direct support for Python VM specific features and their usage should be relegated to platform-specific code.

Yield a value from a function as by Python's yield statement. Use of the yield form automatically converts your function into a Python generator. Basilisp seq and sequence functions integrate seamlessly with Python generators.

Basilisp provides two special forms specifically for importing Python and Basilisp code into the current context.

Warning

These special forms should be considered an implementation detail and their direct usage is strongly discouraged. In nearly all cases, users should delegate to the corresponding functions in :lpybasilisp.core instead.