extendible and minimalistic binding and destructuring
Common Lisp
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
LICENSE
README
common.lisp
declarations.lisp
let-star.lisp
package.lisp
tests.lisp
x.let-star.asd

README

X.LET-STAR is a binding/destructuring utility for Common Lisp which currently combines:

a) let* 
b) destructuring-bind
c) :mval - multiple-value-bind
d) :slot - with-slots
e) :slotval - "projection" of slot values of structure/object to local variables,
   avoiding slot lookup every time the slot value is used in the scope
   of let*
f) :accessor - with-accessors
g) :accessorval - "projection" of values retrieved by accessor function to local variables (same concept as e) )
h) :all - binding of a group of variables to one initialization value
i) destructuring of arrays
j) :complex - destructuring of complex numbers 

Destructuring of lists, arrays and multiple values can contain
nested other binders, and also recognizes "don't care" variable _.

A small example of nested sequences destructuring:

(defstruct xxx a b)

(let* (((:mval #(x
                 (y (:complex r i) &rest rest)
                 (:slotval a b))
               (f g))
        (values (vector 10 
                        (list 20 (complex 30 40) 50 60) 
                        (make-xxx :a 70 :b 80))
                (list 90 100))))
  (values x y r i rest a b f g))

It's trivially extendible with DEFINE-BINDER macro, and supports adding
of customized declarations via DEFINE-DECLARATION-PROCESSING macro. 

It's designed as drop-in replacement of common-list:let* (without any changes 
in sources needed) and as almost drop-in replacement for metabang-bind.

X.LET-START shadows common-lisp:let* (since it's completely compatible with common-lisp:let*)
To use the X.LET-STAR library, your defpackage should roughly look as:

(defpackage :your-lib
  (:use :common-lisp :x.let-star ...)
  (:shadowing-import-from x.let-star let*) ;; the important line
  ...)

Example of other features:

(defstruct xxx a b c)

(let* (((_ (e . _) &key (g :xxx)) '(:sdfg (:wert :dfg :tyu) :g 100))      ;; b
       ((:mval h _) (rem 1234 34))                                        ;; c
       ((:slot a (b-first b)) (make-xxx :a 123))                          ;; d
       ((:slotval (b-second b) c) (make-xxx :b 3245 :c 3456))             ;; e
       ((:all x y z) :init))                                              ;; f
   (values e g h a b-first b-second c x y z))

==>

:WERT
100
10
123
NIL
3245
3456
:INIT
:INIT
:INIT

expansion:

(DESTRUCTURING-BIND                                            ;; b
      (#:IGNORE-1021 (E . #:IGNORE-1022) &KEY (G :XXX))        ;; b
    '(:SDFG (:WERT :DFG :TYU) :G 100)                          ;; b
  (DECLARE (IGNORE #:IGNORE-1021) (IGNORE #:IGNORE-1022))      ;; b
  (MULTIPLE-VALUE-BIND                                         ;; c
        (H #:IGNORE-1020)                                      ;; c
      (REM 1234 34)                                            ;; c
    (DECLARE (IGNORE #:IGNORE-1020))                           ;; c
    (WITH-SLOTS (A (B-FIRST B)) (MAKE-XXX :A 123)              ;; d
      (LET ((#:VAL1019 (MAKE-XXX :B 3245 :C 3456)))            ;; e
        (LET ((B-SECOND (SLOT-VALUE #:VAL1019 'B)))            ;; e
          (LET ((C (SLOT-VALUE #:VAL1019 'C)))                 ;; e
            (LET ((#:VAL1139 :INIT))                           ;; f
              (LET ((X #:VAL1139) (Y #:VAL1139) (Z #:VAL1139)) ;; f 
                (VALUES E G H A B-FIRST B-SECOND C X Y Z)))))))))
    
More binders will be added in future as the need arises.