Skip to content

Commit

Permalink
Fill in ^# docstring again
Browse files Browse the repository at this point in the history
  • Loading branch information
gilch committed May 28, 2023
1 parent 65469a6 commit 3ce5f78
Showing 1 changed file with 149 additions and 16 deletions.
165 changes: 149 additions & 16 deletions src/hissp/macros.lissp
Original file line number Diff line number Diff line change
Expand Up @@ -2015,20 +2015,19 @@ except ModuleNotFoundError:pass"
Builds a function whose arguments are pushed to a stack, operates on
the stack according to the program, and finally pops its result.

Expressions are often terse enough to be used one-off inline.

The mini-language supports higher-order function manipulation
including composition, partial application, and point-free data flow.

The language is applied right-to-left, like function calls.
Magic characters are

``,`` -data
Suffix interprets callable as data. Write before any ``^``.
Suffix interprets callable as data.
``%`` -kwargs
Suffix interprets top element as **kwargs. Write before any ``^``.
Suffix interprets top element as ``**kwargs``.
``^`` -depth
Suffix increases arity. Assume depth 1 otherwise. Can be repeated.
Write after other suffixes.
``/`` DROP
Pops (at depth) and discards.
``&`` PICK
Expand All @@ -2050,23 +2049,157 @@ except ModuleNotFoundError:pass"
Other elements are either callables or data, and read as Lissp.
Data elements just push themselves on the stack (default depth 0).

#> (^#2)
2

Increasing the depth to 1 implies a lookup on the next element.
.. code-block:: REPL

#> (^#:'foo^ (% 'foo 2))
2
#> (^#:2)
>>> (lambda *_QzNo73_args:
... # hissp.macros.._macro_.let
... (lambda _QzNo73_stack=__import__('builtins').list(
... _QzNo73_args):(
... _QzNo73_stack.reverse(),
... _QzNo73_stack.append(
... (2)),
... (),
... _QzNo73_stack.pop())[-1])())()
2

Callables (default depth 1) pop args to their depth and push their
result. These are categorized at read time. Literals are always data,
but an element that reads as `tuple` or `str` type may be ambiguous,
in which case they are presumed callable, unless it ends with a ``,``.
result. Combine with a datum for partial application.

Methods at depth one are converted to attribute lookups.
.. code-block:: REPL

#> (^#.__class__.__name__ :x)
'str'
#> (define decrement ^#sub^@1)
>>> # define
... __import__('builtins').globals().update(
... decrement=(lambda *_QzNo73_args:
... # hissp.macros.._macro_.let
... (lambda _QzNo73_stack=__import__('builtins').list(
... _QzNo73_args):(
... _QzNo73_stack.reverse(),
... _QzNo73_stack.append(
... (1)),
... _QzNo73_stack.append(
... _QzNo73_stack.pop(
... (-2))),
... _QzNo73_stack.append(
... sub(
... _QzNo73_stack.pop(
... (-1)),
... _QzNo73_stack.pop(
... (-1)))),
... _QzNo73_stack.pop())[-1])()))

#> (decrement 5)
>>> decrement(
... (5))
4

Increasing the depth of data to 1 implies a lookup on the next
element. Methods always need a self, so they can be converted to
attribute lookups at the default depth of 1. Combine them to drill
into complex data structures.

.. code-block:: REPL

#> (^#.__class__.__name__:'spam^ (dict : spam 'eggs))
>>> (lambda *_QzNo73_args:
... # hissp.macros.._macro_.let
... (lambda _QzNo73_stack=__import__('builtins').list(
... _QzNo73_args):(
... _QzNo73_stack.reverse(),
... _QzNo73_stack.append(
... __import__('operator').getitem(
... _QzNo73_stack.pop(),
... 'spam')),
... (),
... _QzNo73_stack.append(
... __import__('operator').attrgetter(
... '__class__.__name__')(
... _QzNo73_stack.pop())),
... _QzNo73_stack.pop())[-1])())(
... dict(
... spam='eggs'))
'str'

The callable or data type is determined at read time. Literals are
always data. but an element that reads as `tuple` or `str` type may be
ambiguous, in which case they are presumed callable, unless it ends
with a ``,``.

.. code-block:: REPL

#> (define prod ^#reduce^mul,)
>>> # define
... __import__('builtins').globals().update(
... prod=(lambda *_QzNo73_args:
... # hissp.macros.._macro_.let
... (lambda _QzNo73_stack=__import__('builtins').list(
... _QzNo73_args):(
... _QzNo73_stack.reverse(),
... _QzNo73_stack.append(
... mul),
... _QzNo73_stack.append(
... reduce(
... _QzNo73_stack.pop(
... (-1)),
... _QzNo73_stack.pop(
... (-1)))),
... _QzNo73_stack.pop())[-1])()))

#> (en#prod 1 2 3)
>>> (lambda *_QzNo60_xs:
... prod(
... _QzNo60_xs))(
... (1),
... (2),
... (3))
6

#> (define geomean ^#pow^prod@truediv^1:len&)
>>> # define
... __import__('builtins').globals().update(
... geomean=(lambda *_QzNo73_args:
... # hissp.macros.._macro_.let
... (lambda _QzNo73_stack=__import__('builtins').list(
... _QzNo73_args):(
... _QzNo73_stack.reverse(),
... _QzNo73_stack.append(
... (lambda X,Y:X[-1-Y])(
... _QzNo73_stack,
... (0))),
... _QzNo73_stack.append(
... len(
... _QzNo73_stack.pop(
... (-1)))),
... (),
... _QzNo73_stack.append(
... (1)),
... _QzNo73_stack.append(
... truediv(
... _QzNo73_stack.pop(
... (-1)),
... _QzNo73_stack.pop(
... (-1)))),
... _QzNo73_stack.append(
... _QzNo73_stack.pop(
... (-2))),
... _QzNo73_stack.append(
... prod(
... _QzNo73_stack.pop(
... (-1)))),
... _QzNo73_stack.append(
... pow(
... _QzNo73_stack.pop(
... (-1)),
... _QzNo73_stack.pop(
... (-1)))),
... _QzNo73_stack.pop())[-1])()))

#> (geomean '(1 10))
>>> geomean(
... ((1),
... (10),))
3.1622776601683795

"
(let (reader (hissp..reader.Lissp : ns (.get hissp.compiler..NS))
Expand Down

0 comments on commit 3ce5f78

Please sign in to comment.