Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

extendible and minimalistic binding and destructuring

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 LICENSE
Octocat-spinner-32 README
Octocat-spinner-32 common.lisp
Octocat-spinner-32 declarations.lisp
Octocat-spinner-32 let-star.lisp
Octocat-spinner-32 package.lisp
Octocat-spinner-32 tests.lisp
Octocat-spinner-32 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. 

Something went wrong with that request. Please try again.