RSS Feed

Lisp Project of the Day

golden-utils

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

golden-utilsutils

This is a yet another utility collection like "alexandria", rutils or mentioned in the #16 #pfotheday "kmrcl". The author is @mfiano. He has many interesting CL projects on the GitHub, but now let's look at "golden-utils".

This library lack documentation, but it's package.lisp file is structured so you can figure out which areas are covered by the library.

For example, it has interesting functions to create and merge hash tables:

POFTHEDAY> ;; Here is how we can create a simple dictionary:

POFTHEDAY> (golden-utils:dict :foo "bar")
#<HASH-TABLE :TEST EQ :COUNT 1 {1008B89313}>

POFTHEDAY> ;; If first argument is a function, it will be used
POFTHEDAY> ;; as :test for created hash table:

POFTHEDAY> (golden-utils:dict #'equal "foo" "bar")
#<HASH-TABLE :TEST EQUAL :COUNT 1 {1008FEFC73}>

POFTHEDAY> ;; Also, there are few conversion functions:
POFTHEDAY> (golden-utils:hash->alist
            (golden-utils:dict :foo "bar"))
((:FOO . "bar"))

POFTHEDAY> ;; And a function hash-merge:    

POFTHEDAY> (golden-utils:hash->alist
            (golden-utils:hash-merge
             (golden-utils:dict :foo "bar")
             (golden-utils:dict :blah "minor")))
((:BLAH . "minor") (:FOO . "bar"))

There are also interesting macroses. For example, this little helper to define a "print-object" method for your classes.

This macro hides all common boilerplate:

POFTHEDAY> (defclass foo () ())
#<STANDARD-CLASS POFTHEDAY::FOO>

POFTHEDAY> (defvar *obj* (make-instance 'foo))
*OBJ*

;; By default, only class method and object's ID are printed:
POFTHEDAY> *obj*
#<FOO {10094F9363}>

POFTHEDAY> (golden-utils:define-printer (foo stream)
             (format stream "Hello Lisp World!"))
#<STANDARD-METHOD COMMON-LISP:PRINT-OBJECT (FOO T) {100632A163}>

;; But now, when we defined a method, we can have a human-readable
;; object description:
POFTHEDAY> *obj*
#<FOO Hello Lisp World!>

POFTHEDAY> (macroexpand-1
            '(golden-utils:define-printer (foo stream)
              (format stream "Hello Lisp World!")))
(DEFMETHOD PRINT-OBJECT ((FOO FOO) STREAM)
  (PRINT-UNREADABLE-OBJECT (FOO STREAM :TYPE T :IDENTITY NIL)
    (FORMAT STREAM "Hello Lisp World!")))

There is another interesting macro "mvlet", which combines together semantics of "let" and "multiple-value-bind".

This macro does is complex and does not have a docstring.

I was able to find an example in other Michael's sources and to create this simplified example for you:

;; First, we'll define a function which
;; returns multiple values
POFTHEDAY> (defun foo ()
             (values 1 2 3))
POFTHEDAY> (foo)
1 (1 bit, #x1, #o1, #b1)
2 (2 bits, #x2, #o2, #b10)
3 (2 bits, #x3, #o3, #b11)

;; Using usual "let" we can catch only the first value:
POFTHEDAY> (let ((a (foo))
                 (blah "minor"))
             (list a blah))
(1 "minor")

;; We have to use nested "multiple-value-bind":
POFTHEDAY> (let ((blah "minor"))
             (multiple-value-bind (a b c)
                 (foo)
               (list a b c blah)))
(1 2 3 "minor")

;; With mvlet we can decrease nesting level:
POFTHEDAY> (golden-utils:mvlet ((a b c (foo))
                                (blah "minor"))
             (list a b c blah))
(1 2 3 "minor")

There are also other libraries which bring similar functionality, like:

By the way in the "serapeum", binding macro also is called "mvlet", but internal code is different.

Investigate other "golden-utils" facilities and maybe you will find gold!


Brought to you by 40Ants under Creative Commons License