@ -107,6 +107,8 @@
( defun true ( f )
( not ( null f ) ) )
; Functional
( defun nop ( )
"Do nothing"
nil )
@ -115,6 +117,42 @@
"Do nothing"
t )
; Combinators
( defun deatomise ( list )
"If `list' is a list, pass it through; if it is a non-nil atom, wrap it in a single-element list"
( if ( and list ( atom list ) )
( cons list nil )
list ) )
( defun deatomise! ( list ) "Ensure `list' is a list" ( cons list nil ) )
( defun combine ( fa fb &key ( pass #' deatomise! ) )
" Returns an applicative lambda that runs ( ` fb ' ( ` fa ' args... ) . . . )
NOTE: This function *applies* the result of ` fa ' to ` fb ', therefore, if the result of ` fa ' is a list, the elements of said list are applied as the sequential arguments for ` fb ', if the result is a single element, it is passed as argument 1 only ( this includes ` ` nil ' ' ) . If you want to pass the result of ` fa ' to ` fb ' verbatim through the first argument only, use ` ` combine1 ' ' ( ) .
WARNING: By default, if ` fa ' returns ` ` nil ' ', the ` ` nil ' ' is passed as argument 1 to ` fb '. Therefore, no function ` fa ' will ever produce 0 arguments for ` fb ' ; if you wish to override this behaviour and allow a nil return to mean 0 arguments, set `pass' to ``deatomise''() (to still ensure the return of `fa' is contained list; you can use ``combine!''() for behaviour instead too), or the ``identity''() function, if you know `fa' returns a list."
( lambda ( &rest args ) ( apply fb ( funcall pass ( apply fa args ) ) ) ) )
( defun combine! ( fa fb )
" Returns an applicative lambda that runs ( ` fb ' [ ( ` fa ' args... ) . . . ] )
NOTE: This is the same as calling ` combine ' with ` pass ' as ` ` deatomise ' ' ( ) . "
( combine fa fb :pass #' deatomise ) )
( defun combine1 ( fa fb )
" Returns a lambda that runs ( ` fb ' ( ` fa ' args... ) )
NOTE: The difference between this an ` ` combine ' ' ( ) is that ` combine ' *applies* the result of ` fa ' to ` fb ', whereas ` combine1 ' ( ) simply calls ` fb ' with the result of ` fa '. "
( lambda ( &rest args ) ( funcall fb ( apply fa args ) ) ) )
( defun inverse ( func )
"Returns a lambda that resolves ¬(`func' args...)"
( lambda ( &rest n ) ( not ( apply func n ) ) ) )
( defun inverse* ( &rest functions )
"Returns a list of `inverse'()d functions from `functions'"
( mapcar #' inverse functions ) )
;; Mapping
( defun mapline ( input fi &key ( read-line #' read-line ) )
"Map lines from stream"
( loop for line = ( funcall read-line input nil )