The LETV Package. Exports two macros, LETV and LETV* that allow to combine standard LET and LET* constucts with MULTIPLE-VALUE-BIND in a possible less verbose way that also requires less indentation.
<mantoniotti [at] common-lisp.net>
See the file
COPYING for copyright and licensing information.
This little hack introduces two handy Common Lisp macros,
LETV* that allow you to mix regular
forms in a less verbose way. The amount of indentation needed is
The syntax of
LETV*) is very "loopy", with a nod to
SML/OCaml/F#/Haskell/Julia. The current syntax is the following:
letv ::= 'LETV' [vars] [IN [body]] letvstar ::= 'LETV*' [vars] [IN [body]] vars ::= var | var vars var ::= ids '=' <form> [decls] decls ::= decl | decl decls decl ::= OF-TYPE idtypes ids ::= <symbol> | '(' <symbol> + ')' idtypes ::= <type designator> | '(' <type designator> + ')' body ::= [<declarations>] <form> *
(I know: the grammar is not completely kosher, but I trust you will understand it.)
The two macros expand in forms that mimic the semantics of
MULTIPLE-VALUE-BIND. All type declarations, if present,
are properly handled via
LETV expands into a
LET, with variable initialized by
LETV* expands into a form that is an interleaving of
- Simple case:
(letv x = 42 in (format t "The answer is ~D.~%" x))
- Same with declaraion:
(letv x = 42 of-type fixnum in (format t "The answer is ~D." x))
- Simple case with
(letv (v found) = (gethash 'the-key *my-hash-table*) in (if found (format t "Found THE-KEY, doing stuff.~%") (error "THE-KEY not found.")))
- Mixing things up:
(letv (v found) = (gethash 'the-key *my-hash-table*) of-type (fixnum boolean) x = 42 in (if found (format t "Found THE-KEY, adding to the answer ~D.~%" (+ v x)) (error "THE-KEY not found.")))
(letv* (v found) = (gethash 'the-key *my-hash-table*) of-type (fixnum boolean) x = (when found (+ v 42)) in (if found (format t "Found THE-KEY, adding to the answer ~D.~%" x) (error "THE-KEY not found.")))
- The other way around.
(letv x = 42 of-type integer (v found) = (gethash 'the-key *my-hash-table*) of-type (fixnum boolean) in (if found (format t "Found THE-KEY, adding to the answer ~D.~%" (+ v x)) (error "THE-KEY not found.")))
- A more compelling example.
(letv* (p found) = (gethash 'the-key *points-table*) of-type (point) (x y) = (if found (unpack-point p) (values :missing :missing)) in ;; Adding declarations here also works. (declare (type point p) (type (or real (eql :missing)) x y)) (do-stuff-with x y) (do-things-with p))
All the examples are meant to illustrate the use of
LETV* are obviously not the first macros of this kind
floating around: others are available and all have their niceties. But
I never claimed not to suffer form NIH syndrome.
LETV* do not do "destructuring" or "pattern matching".
That is a different can of worms; but you can check
cl-unification for a library
(always by yours truly) that provides facilities in that sense.
A NOTE ON FORKING
Of course you are free to fork the project subject to the current licensing scheme. However, before you do so, I ask you to consider plain old "cooperation" by asking me to become a developer. It helps keeping the entropy level at an acceptable level.