This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

What little functions/macros do you use?

24 posts · 15815 views

I had (and still have) a little file with little utilities in it, many of these aren't a big deal, but i could imagine them being an annoyance to others. So we should discuss them and try see if we can agree on using the same ones. Part of the objective of Alexandria is presumably this. PDF Draft documentation, autodocumentation. (Confused that it is named ".0.DEV" there..) Incase pdf misses anything. Of course Alexandria isn't the only library that could help standardize how we do stuff.

I personally changed some code to start using $#'if-let, $#'when-let, $#'curry, $#'rcurry of Alexandria instead of my own. (Actually i think i sometimes even found CL functions/macros to suit the utility i originally met with my own macro/function.

Some macros i still use have my own variant for:

setf- change a setf-able by a function; (defmacro setf- (change-function to-set &rest args) `(setf ,to-set (,change-function ,@args))), for instance (setf- max var ...) does the same as (alexandria:maxf var ...) (it is just more general) Of course i usually don't use setting anything, usually end up using it if i am writing a simulation.

with-mod-slots allows you do do two things 1) treat slots as interned into the current package, and 2) have the slots of two objects with same-named slots accessible directly without writing a $#'symbol-macrolet yourself. I also encounter this usually in simulations.
(defmacro with-mod-slots (mod (&rest slots) object &body body)
  (with-gensyms (obj)
    `(let ((,obj ,object))
       (symbol-macrolet
	   (,@(mapcar (lambda (slot)
			`(,(intern (format nil "~D~D" mod slot))
			   (slot-value ,obj ',slot)))
		      slots))
	 ,@body))))
You could do the same for $#'with-accessors i guess.

And, as i whined before, denest, but not very often at all. I use a more complicated version than the below.(too complicated infact, and i don't make use of it, but i can just cut it out)
(defmacro denest (&rest forms)
  (if (null (cdr forms))
    (car forms)
    `(,@(car forms) (denest ,@(cdr forms)))))
But i think that if you're using it, it is likely(but not certain) that you need to rethink how you're doing things.

More minorly, constant Just a function of the constant given with an ignored (&rest rest) argument, sqr, and i have some more in the file that i either end up not using much(case-let, mk for make-instance), or i should phase out using. Also got vector stuff i use. (Not this just use lisps vectors and pray that optimizes now.. (The suggested packages there seem to involved there, i just wanted basic vectors, and maybe matrices.)

So what little functions/macros do you use? And which libraries or do you keep them yourself? Have any libraries to suggest to others?

Re: What little functions/macros do you use?

Hey, I use, among a couple of other less interesting utilities, these (apologies if I can't recall the originator):
(defmacro let^ (bindings &body body)
  (if (evenp (length bindings))
   `(let ,(loop :for (var val) :on bindings :by (function cddr)
           :collect (list var val)) ,@body)
      (cerror "Odd number of let^ bindings.")))
and a similar version analagous to let*. They only really save typing a few parentheses, but I use them a fair bit...

I also like Gary King's ap:
(defmethod ap ((thing cl:string) &optional package)
  (let ((*package* (or (and package (find-package package))
                       nil)))
    (apropos-list thing package)))

(defmethod ap ((thing symbol) &optional package)
  (ap (symbol-name thing) package))

(defmethod ap ((thing list) &optional package)
  (cond
    ((null thing) nil)
    ((null (rest thing)) (ap (first thing) package))
    (t (let ((current (ap (first thing) package)))
        (dolist (thenext (rest thing))
          (setf current (intersection current (ap thenext))))
        current))))
And aif and awhen, which you can probably google easy enough, and... ... curry and rcurry, but I have trouble using them if they are nested more than two levels :shock: (that's me trying to figure it out), and deb:
(defmacro deb (symbol &rest forms)
  "A debugging macro - prints the first (unevaluated) argument, and then each form with it's value.
It returns the value of the last form."
 (let ((result (gensym "result")))
   `(let^ (#+clisp *standard-output* #+clisp t
           ,result nil)
      (format *standard-output* "~&~A: ~{~{~A = ~A~}~^, ~}~%" ',symbol
              ,(cons 'list (mapcar #'(lambda (x) `(list ',x (setf ,result ,x))) forms)))
      ,result)))
If you think I should write deb a bit differently, I'd be interested. I also use compose (there's an implementation in Alexandria), and print-list, which is just a bit nicer to read for interactive sessions when working on long lists:
(defun print-list (list &optional (stream *standard-output*)
                   &key (leading #\Newline))
  "Prints a list in lisp style with an element to each line."
  (princ leading)
  (when (not list)
    (princ "()")
    (return-from print-list nil))
  (if (consp list)
    (progn
      (princ "(" stream)
      (prin1 (car list) stream)
      (when (cdr list)
        (dolist (item (cdr list))
          (princ "
 " stream)
          (prin1 item stream)))
      (princ ")" stream))
      (prin1 list stream))
  nil)
and one which someone wrote because it will let you compile and load it without warnings or errors:
(defspel defconst (name value &optional doc)
  `(eval-when (:compile-toplevel :load-toplevel :execute)
    (unless (boundp ',name)
      ,(if doc
        `(defconstant ,name ,value ,doc)
        `(defconstant ,name ,value)))))
And here's some that I haven't used much, but might be fun :mrgreen::
(defun random-remove (list)
  "Returns two values - the new, shorter, list and the removed element.
This is the two-pass version, please use me."
  (check-type list list)
  (when (null list) (return-from random-remove nil))
  (let^* (len (length list)
          i (random len)
          target (nthcdr i list))
    (values (append (subseq list 0 i) (cdr target))
            (car target))))

(defmacro random-pop (list-place)
  (let^ (remains (gensym "REMAINS")
         elt (gensym "ELT"))
    `(multiple-value-bind (,remains ,elt) (random-remove ,list-place)
      (setf ,list-place ,remains)
      ,elt)))
P.S. I assume that when you said this:
Jasper wrote: setf- change a setf-able by a function; (defmacro setf- (change-function to-set &rest args) `(setf ,to-set (,change-function ,@args))), for instance (setf- max var ...) does the same as (alexandria:maxf var ...) (it is just more general) Of course i usually don't use setting anything, usually end up using it if i am writing a simulation.
you actually meant:
... `(setf ,to-set (,change-function ,to-set ,@args)) ...
I really like that idea, thanks :).
blog.metalight.net

Re: What little functions/macros do you use?

Thanks for your input. let^ is neat!

Haven't ever used(or maybe even looked at before) apropos.. What do you use it for? Finding functions to use as you're coding? (For autodoccing i just iterate do-symbols or do-external-symbols. Btw, i'd do (defmethod ap ((thing null) &optional package) (declare (ignore package))) for the null case.

Was always stopped in using Anaphoras aif and such because of the nondescriptive names and IT, but it is clear enough, probably should start using that too..

For print-list how about
(defun print-obj (list &key (leading #\Newline))
  "For sequences, a line for each element."
  (princ leading)
  (typecase list ;;A really useful macro, btw
    (null (princ "()"))
    (sequence
     (princ "(") (prin1 (type-of list))
     (map nil #'print list)
     (princ ")"))
    (t    (prin1 list)))
  list)
Seems less messy to me. Although type-of-list is more informative, it's output may not always be the most desirable :), guess you could put a typecase in there (typecase list (list 'list) (vector 'vector) (array 'array) (t (type-of list)))

Don't know what to change about DEB, but doesn't that clisp-specific thing lead to a big surprise when people try to change *standard-output*? Not sure what problem in clisp that is trying to solve, though. If it isn't defaultly bound, you could check for that with boundp.

About random-remove and random-top why (check-type ..) vs (declare (type ..)), i feel that uncomfortable with random-pop being a macro, but no way of getting around setting it that is convenient, i guess. cl:push is also a macro, so..

Re: What little functions/macros do you use?

I use ap less nowadays, but I've found that it's most useful when you've picked up the basics of a package, but can't remember the function name exactly, or which functions have XYZ in their name. So, it's kind of a help to jog my memory, when I don't want to deal with the CL HyperSpec or other documentation. As an example, try comparing the output of:
(ap '("PRINT" "HASH"))
with the output of:
(apropos "PRINT")
(apropos "HASH")
As for print-obj, nice use of map - I should use the sequence functions more. I would, however, like to retain the nice output formatting.

About check-type, I never thought about it like that, but I see your point. I suppose that a declaration can (sometimes?) be ignored by the compiler, but check-type is actual code and is not going to be accidentally thwarted, so it may lead to more stable code. Also, efficiency isn't really an issue as it's a function I only use in interactive sessions.

I will have a look at deb and why I put in the binding for *standard-output*. Hmm. Yup, Clisp works without the extra binding - I must have had a bug when I was writing it, and didn't clean it up properly. :roll:

Regards,
Jonathan

Re: What little functions/macros do you use?

Ahh, the #'ap example looks a lot better if you have print-hash-table defined. That's one more I have accumulated from somewhere/someone :mrgreen::
(defun print-hash-table (hash-table)
  (maphash
    #'(lambda (key value)
      (format t "~S ==> ~S~%" key value))
    hash-table))

Oh, I forgot these ones...

I just looked into my array utilities, which I skipped over earlier when I wrote the other replies. One thing that has annoyed me in the past, is the 0 based indices for arrays, etc., so I wrote my own aref and elt versions:
(defun 1ref (array &rest indices)
  "Cool 1-based array indexing."
  (apply #'aref array (mapcar #'1- indices)))

(defsetf 1ref (array &rest indices) (newval)
  `(setf (aref ,array ,@(mapcar #'(lambda (i) `(1- ,i)) indices)) ,newval))

(defun 1elt (seq index)
  "Cool 1-based array indexing."
  (elt seq (1- index)))

(defsetf 1elt (seq index) (newval)
  `(setf (elt ,seq (1- ,index)) ,newval))
And, when I do bits of array processing, I like these (see comments for an explanation):
(defmacro with-easy-arrays (array-names &body body)
  "This macro (along with with-easy-1arrays) attempt to make code
that has a lot of array element accesses look simpler, and thus by
extension (if the array names are helpful) also easier to read.
Wraps body in a macrolet which establishes several temporary
macros that eliminate the need to include aref when retrieving
elements from the given arrays.  Because they're macros, we also
avoid writing aref when setting an element.  For example, when
you would normally write (setf (aref m 7 8) (aref m 3 2)), instead
you'd write (with-easy-arrays (m) (setf (m 7 8) (m 3 2))).  You
can still access each of the whole arrays, what you can't access
would probably be functions with the same names as your matrix
variable names."
  `(macrolet ,(mapcar #'(lambda (array)
                         `(,array (&rest args)
                           `(aref ,',array ,@args)))
                      array-names)
     ,@body))

(defmacro with-easy-1arrays (array-names &body body)
  "Like with-easy-arrays but uses 1ref instead of aref.
This means that all of your arrays are now indexed from
1, not 0 like they are with aref."
  `(macrolet ,(mapcar #'(lambda (array)
                         `(,array (&rest args)
                           `(1ref ,',array ,@args)))
                      array-names)
     ,@body))
I've also got some untyped (I haven't bothered to declare types) implementations of some linear algebra functions, such as gauss-jordan elimination (with and without partial pivoting), some LU decomposition routines, and matrix inversion, which I might ;) post if anyone's interested. I think someone has been doing some matrix stuff in Lisp, just can't remember who.

P.S. I really really like the way Lisp lets you use symbols like 1ref (illegal in C/C++, and probably other similar languages), and even pi/2, etc.
blog.metalight.net

Re: What little functions/macros do you use?

Perhaps some sort of regexprs would do better than AP though, hmm perhaps make a little 'peeker' lib that prints parts with possibly with regexpressions.

I think the main difference between check-type and declare is that check-type allows you to fill it in when it errors ithink. Contrary what you said you can't accidentally twart it, it will give an error if you enter a wrong type. (On defaults; it may depend on what the safety is relative to the other optimize declarations.) You can easily compare them by using them and entering an incorrect input.

Starting counting at 0 does seem more natural to me, for computers, at least. The first element in an array is a shift of 0 bytes. with-easy-arrays looks useful to me, but maybe simply with-array-aref is a better name for it, dont know. Perhaps it could take the arrays directly as arguments or something, tbh don't really like the idea of macros using variables that have been defined externally. (other then defvar defparameter) Perhaps a compromise:
(defmacro with-areffer (from &body body)
  (typecase from
    (list
     (destructuring-bind (array-name array) from
       `(let ((,array-name ,array))
	  (macrolet ((,array-name (&rest indices)
		       `(aref ,',array-name ,@indices)))
	    ,@body))))
    (symbol
     `(macrolet ((,from (&rest indices)
		  `(aref ,',from ,@indices)))
	,@body))))

(defmacro with-areffers ((&rest arefs) &body body)
  `(with-aref (,(car arefs))
     ,@(if (null(cdr arefs))
	 body `((with-arefs (,@(cdr arefs)) ,@body)))))
Also with the let^ things, we could apply it to this macro, but doing that for every other macro would be annoying. Or we could do:
(defmacro ^ (name bindings &body body)
  `(,name ,(loop :for (var val) :on bindings :by (function cddr)
              :collect (list var val)) ,@body))
So that it can be applied to any macro with corresponding structure. (^ let .. ) = (let^ ...) This way we can write the macros with the usual assoc-list structure people are used to and use that to make the ^ version(perhaps the hat better before then?) or just apply ^ in the code.

About vectors&matrices yeah, a standard package with those seems missing. I asked, but all those are rather large packages or are for sparse matrices etcetera, i just wanted numerical vectors, with a few dimensions. I also posted code for vectors there, but it is slow to load; it has to combine them all i think. Currently i use another little package that just uses cl:vectors. It puts the operators on v+, v-, v*, v/ and such. What is handy is that defining it for vectors allows you to define matrices in one swoop, just define those operators on numbers too, and if there is a vector there it will work correctly. Even works for inproducts (which become matrix products multidimensionally, not v*!). Not sure of the performance of that, though. Didn't ever come to need matrices(or operations on them) though.

Re: What little functions/macros do you use?

Regarding check-type I was actually alluding to situations where optimisations have been applied/declared, like safety 0, or speed 3. Ah, yes, I forgot that check-type presents a restart to fix the value, that's neat. The regexp idea would be cool, but then I'd have to learn how to write and read regexp. :o

Also, I like your idea of defining a ^ macro, but which other macros would you use it for? I think flet and labels, etc. would need a three+ element collection clause or some kind of delimiter to deal with the function bodies.

The way I feel about with-easy-arrays (nice suggestions for names and improvements - I'll take them on board) is that they are just lexical bindings for the symbol in function position. But if it is prone to or lead to problems, confusion, etc., then I'm all ears. ;)

Also, the 1 based indices is a personal preference thing, for me, I think it's my background in mathematics, and the my mental train of thought from "first" to "1st".
blog.metalight.net

Re: What little functions/macros do you use?

I quite enjoy these ones.

An augmentation of unwind-protect makes it easy to e.g. open sockets or X displays, initialize them, and clean up if unsuccessful:
(defmacro abnormal-protect (protected &body cleanup)
  (with-gensyms (done)
    `(let ((,done nil))
       (unwind-protect
	    (prog1 ,protected
	      (setf ,done t))
	 (unless ,done ,@cleanup)))))
I think this one comes from Scheme, or possibly some SRFI or something. It makes it easy to bind variables and perform checks on them while binding:
(defmacro and-let* (clauses &body body)
  (labels ((fix-tail (tail)
	     (if (and (listp tail) (eq (car tail) 'and))
		 (cdr tail)
		 (list tail)))
	   (compile-clauses (clauses)
	     (let ((clause (car clauses))
		   (rest (cdr clauses)))
	       (let ((tail (if rest (compile-clauses rest) `(progn ,@body))))
		 (cond ((and (listp clause) (symbolp (car clause)))
			`(let (,clause)
			   (and ,(car clause)
				,@(fix-tail tail))))
		       ((and (listp clause) (listp (car clause)))
			`(and ,(car clause) ,@(fix-tail tail)))
		       ((symbolp clause)
			`(and ,clause ,@(fix-tail tail)))
		       (t (error "Illegal clause ~S in ~S" clause 'and-let*)))))))
    (compile-clauses clauses)))
And finally, how comes CL doesn't come with a built-in definition of WHILE?
(defmacro while (condition &body body)
  `(loop (if (not ,condition)
	     (return))
      ,@body))

Re: What little functions/macros do you use?

To be honest, i never really used unwind-protect can't really say much about unwind-protect.

Suggest the following for and-let*, with here when-let from alexandria:
(defmacro when-let-n (clauses &body body)
  "Do body if all variables in clauses non-nil"
  `(when-let ,(car clauses)
     ,@(if (null (cdr clauses))
          body
         `((when-let-n ,(cdr clauses) ,@body)))))
Dolda wrote:And finally, how comes CL doesn't come with a built-in definition of WHILE?
Probably aversion with code based on side-effects. Probably not entirely ill-considered. There is a reason DO is much more strict about it. Unfortunately WHILE and UNTIL will probably conflict with iterate, although it should be easy to make a macro that defers some of iterates symbols to keywords. (I don't use iterate anymore btw)
Kohath wrote:The regexp idea would be cool, but then I'd have to learn how to write and read regexp.
To be honest, i don't really know them. Just use wildcards '*' and '?', but that would still be handy; (ap '("PRINT" "HASH")) is longer than (ap "PRINT*HASH"), actually pretty marginal(even with stars automatically at the edges), probably should have said it.. Btw, those two aren't exactly the same, the two words need to be in the correct order for the latter.

There really isn't any source of confusion in how you arranged things in with-easy-arrays, just a little pet worry of mine. Sometimes it is just a personal preference, just like you liked 1ref, 1elt, don't think those personal preferences are very productive, by the way. It may be a distraction, especially in dealing with other people's code.

How about this macro
(defmacro def-setf-fun (name (&rest args) &body body)
  (with-gensyms (to)
    `(progn (defun ,name (,@args) ,@body)
            (defun (setf ,name) (,to ,@args)
              ,@(butlast body)
              (setf ,(car(last body)) ,to)))))

(let ((a 4))
  (def-setf-fun set-a () a))
Something bugged me about it, but now i cannot fathom nor remember what, i think i'll try using it again..

Re: What little functions/macros do you use?

So, and-let*, I presume as in http://srfi.schemers.org/srfi-2/srfi-2.html, cool, I get it, I'll try using it. Jasper, that seems like a nice implementation, except it can't handle non-variable/binding clauses.

I think the symbols named 'until and 'while might conflict, but you should be able to work around that if you really want, because neither loop nor iterate have function bindings for them.
Jasper wrote:There really isn't any source of confusion in how you arranged things in with-easy-arrays, just a little pet worry of mine. Sometimes it is just a personal preference, just like you liked 1ref, 1elt, don't think those personal preferences are very productive, by the way. It may be a distraction, especially in dealing with other people's code.
I think that they shine (true, my preference :)) when I want to write some bits of array processing code in mathematical style, and since I don't have an editor that can do LaTeX style code rendering :cry:, I'm pretty happy with things like this :mrgreen:. Having said that, perhaps they're not what you were looking for when you started the post :oops:.

About def-setf-fun, I looked at it and went - cool! I think it's great for the simple case, like some other language's getters and setters, but I can't think of a situation when I want to put anything else in body (but that doesn't mean such situations don't exist).
Dolda wrote:And finally, how comes CL doesn't come with a built-in definition of WHILE?
I have got a while in my utilities file, but I rarely use it. For me it hasn't been fear, but just that loop and other tools do a better job, one way being to provide the 'state' variables to use destructively. So I use things that kindof look like (in a loose CLHS sense :)):
(loop [with state = blah] while condition do stuff do other-stuff)
;; or
(iter [(with state = blah)] (while condition) multiple forms to do stuff)
Note that while could be replaced by until if that removes a not, it's also defined in both loop and iterate.

Re: What little functions/macros do you use?

I can see your point about (loop while (...)) does the job of while. I guess I just avoid keyworded LOOPs like the plague. I find the syntax so un-Lisp-like. :)

Re: What little functions/macros do you use?

Kohath wrote:Having said that, perhaps they're not what you were looking for when you started the post :oops:.
They are little function/macros you use, aren't they? It fits the bill..

About def-setf-fun; you can put a docstring/declarations/assertions and such in there, but also just because there is no real reason not to give that freedom.

I rarely use LOOP, sometimes if i need to collect in a way mapcar and such doesn't allow me, i use
(defmacro collecting ((&key (init '(list)) (onto (gensym))
                                 (collect 'collecting) (append 'appending)
                                 (last (gensym)) (append-1 (gensym)))
                      &body body)
  "Collect everything asked to, return result. (Also, appending)
If you want to use two different collectings, you need to provide the\
 collect argument.(To avoid namespace collision, and to separate the two.)"
  `(let ((,onto ,init) ,last)
     (declare (ignorable ,onto))
     (labels ((,append-1 (collected)
                (if (null ,onto)
                   (setf ,onto collected
                           ,last (last ,onto))
                   (setf (cdr ,last) collected
                         ,last (last ,last))))
                (,append (&rest appended)
                 (dolist (a appended)
                    (,append-1 a)))
              (,collect (&rest collected)
                (,append-1 collected)))
       ,@body)
     ,onto))
It looks a little involved, mostly to make the adding of elements to the end efficient. I have this idea that it is good that mapcar and such can list things back for you, but for more complicated iterators, like over quad trees, it is silly to put the plumbing of the accumulating in the functions iterating over them. Btw i changed it a little before posting it here, made the argument list &key, made the code more something i like now. Of course i also have similar accumulating, summing, etcetera macros. (And if it gets too nested, i denest it.)

That doesn't cover stuff like iterating by CDDR, though, then i often resort to DO, which isn't very neat.

One little problem i don't have a satisfactory macro for is defvars. I mean, you can declaim types of them, but then you have to enter values accordingly. I just found DEFINE-SYMBOL-MACRO, so i guess i could try make a macro that replaces the symbol with a setf-able function that automatically converts arbitrary input to the type the variable is declaimed too. Perhaps 'variable-setf-hook'. That doesn't fix anything when the variable is changed locally in LET, though which for me is the majority of cases..

Re: What little functions/macros do you use?

I sometimes use a handy macro which allows me to construct lists in order (without need to be reversed).
Also, it has a nice feature - keeps size of the list - no need to #'length at the end when you need it.
And the best features at the end - it gives you a hand on last and previous to last elements which
is very handy when you plan to destructively add stuff to the end, without copying anything.
Also - it allows you to supply a list to work on as an argument, when you need to use it on something already made.
(defun before-last (list)
  (if (cddr list)
      (before-last (cdr list))
      list))

(defmacro nconcing ((&key (init nil)
                          (into 'nconc-result)
                          (call 'nconc-it)
                          (count nil)
                          (last nil)
                          (before-last nil))
                    &body body)
  (let ((head-sym (gensym "HEAD"))
        (tail-sym (gensym "TAIL")))
    `(let* ((,head-sym (cons nil ,init))
               (,tail-sym (last ,head-sym))
               (,into (cdr ,head-sym))
               ,@(when count `((,count (length ,init))))
               ,@(when last `((,last nil)))
               ,@(when before-last `((,before-last (before-last ,init)))))
       (flet ((,call (x)
                ,@(when before-last
                        `((setf ,before-last 
                                (unless (eq ,head-sym ,tail-sym)
                                  ,tail-sym))))
                (rplacd ,tail-sym (setf ,tail-sym (list x)))
                (setf ,into (cdr ,head-sym))
                ,@(when last `((setf ,last ,tail-sym)))
                ,@(when count `((incf ,count)))))
         ,@body))))
before-last is used only when you supply list as an argument and you require to get hands on before to last element.

Re: What little functions/macros do you use?

karol.skocik wrote:
(defun before-last (list)
  (if (cddr list)
      (before-last (cdr list))
      list))
You can use (last list 2) instead:
CL-USER> (last '(1 2 3 4 5 6) 2)
(5 6)

Re: What little functions/macros do you use?

gugamilare wrote:
karol.skocik wrote:
(defun before-last (list)
  (if (cddr list)
      (before-last (cdr list))
      list))
You can use (last list 2) instead:
CL-USER> (last '(1 2 3 4 5 6) 2)
(5 6)
Thanks! Didn't know that.
Karol

Re: What little functions/macros do you use?

Hmm, never really needed the previous of the last of the list. Counting is a nice touch, but i do prefer give things one purpose, of course you could do:
(collecting (:onto your-list)
  (let ((cnt 0) (before-last (last your-list 2)))
    (flet ((collecting (element)
             (setq cnt (+ cnt 1)
                   before-last (or (cdr before-last) (last your-list 2)))
             (collecting element))) ;Since it is a flet, defers to the collecting created from macro collecting.
      ....)
That is a bunch longer though, but then again, the user can make his/her own macros to do this. collecting-with-count, collecting-with-before-last or something.. Btw, both the name of the macro and the name of the flet is collecting, it works, but now i think about it, is an accident waiting to happen!

Btw, how do you prevent lisp whining about the return of collecting to be not accessible sometimes? Hmm, maybe it might be confusing about collecting that it returns what it collected, as opposed to the last expression in the body in the first place..

Re: What little functions/macros do you use?

Jasper wrote:Hmm, never really needed the previous of the last of the list. Counting is a nice touch, but i do prefer give things one purpose, of course you could do:
(collecting (:onto your-list)
  (let ((cnt 0) (before-last (last your-list 2)))
    (flet ((collecting (element)
             (setq cnt (+ cnt 1)
                   before-last (or (cdr before-last) (last your-list 2)))
             (collecting element))) ;Since it is a flet, defers to the collecting created from macro collecting.
      ....)
That is a bunch longer though, but then again, the user can make his/her own macros to do this. collecting-with-count, collecting-with-before-last or something.. Btw, both the name of the macro and the name of the flet is collecting, it works, but now i think about it, is an accident waiting to happen!

Btw, how do you prevent lisp whining about the return of collecting to be not accessible sometimes? Hmm, maybe it might be confusing about collecting that it returns what it collected, as opposed to the last expression in the body in the first place..
I use before-last to remove last element quickly as a list post-processing or other manipulating of the list's tail without traversing. http://github.com/ks/X.FDATATYPES/blob/ ... c-ctx.lisp has some uses of that.
Also, these last, before-last and count are expanded only when macro user uses them. The link above has some uses of all 3 at the same time, so I guess separating each functionality into specific macro would prevent usage of their combinations. But, like I said - their functionality is there only when needed.

Re: What little functions/macros do you use?

I guess my contentions that it should be one-purpose is rather petty, so i added those features to collecting (and collect is now the name of the collector inside.) There are still a lot of naming conventions differing.. nconcing vs collecting, into vs onto, conc-it vs collect etcetera. I also have the keyword :ret; whether to return the collected result. (can save a line, not sure if it is that nice though.)

Just to make my macro-set closer in terms to that of Iterate, i made a little iterator to iterate in parallel. Basically a form and a body, where in the form you specify how to iterate in paralel with expressions like (:do var init change) (:until until), (:range var from to &optional (by 1)), (:list var list &optional (by 'cdr)), (:array ...) ~73 lines plus newer collecting.(and there is a macro to add those things) I don't see loose macros doing things handily in parallel together. Example:
(collecting (:ret t)
  (do-parallel ((:range i 1 +5) (:range j 1 +5))
    (collect (list i j))));Gives (1 1) (2 2) (3 3) (4 4) (5 5) possibilities
I don't think i have any more macros to mention. Did still want to say that i don't like long docstrings like Kohath did with the With-arrefers, nor long commented bits with your life story ontop of source files.(Unless it is a one-file package, perhaps) The thing is that if you accept those, you might accepting long code too, and it rather distracts from the code.

Extensive/wordy documentation is fine, but you can use little side-files for that, and that Documentation is also setf-able.(well done CL!) So you can do that in separate files aswel.

Re: What little functions/macros do you use?

I guess this one is also useful sometimes:
Beware - it uses my let-star library. To remove dependency - replace `(let* ((,dim-syms (array-dimensions ,matrix)))
with `(destructuring-bind (,dim-syms) (array-dimensions ,matrix) ....)
(defmacro do-matrix-indices (indices matrix &body body)
  (let ((indices-length (length indices)))
    (assert (and (not (zerop indices-length))
                 (every #'symbolp indices)
                 (eql indices-length (length (remove-duplicates indices))))
            nil "invalid indices, expected unique symbols")
    (let ((dim-syms (mapcar (lambda (i) (gensym (format nil "~A-" i))) indices)))
      (labels ((rec (rem-indices rem-dim-syms)
                 (if rem-dim-syms
                     `(dotimes (,(car rem-indices) ,(car rem-dim-syms))
                        ,@(list (rec (cdr rem-indices) (cdr rem-dim-syms))))
                     `(progn ,@body))))
        `(let* ((,dim-syms (array-dimensions ,matrix)))
           (declare (dynamic-extent ,@dim-syms))
           ,(rec indices dim-syms))))))

Re: What little functions/macros do you use?

I should probably add that one to the(possibly)parallel iterators thingy.

But what is the Dynamic-extent for? From what i read, it declares the variables value not usable outside the body. I guess that would make a difference, but not sure if for those integers, i mean, they're copied when you pass them, right? Looking at the examples in clhs you are not supposed to do with variables declared such, it does behave bugged, but i don't seem to be able to generate an error.

So i guess for macros in general this declaration could be a bit of a surprise.. but since integers are passed by-value should prevent any such thing happening in do-matrix-indices.

Re: What little functions/macros do you use?

Jasper wrote: But what is the Dynamic-extent for? From what i read, it declares the variables value not usable outside the body. I guess that would make a difference, but not sure if for those integers, i mean, they're copied when you pass them, right? Looking at the examples in clhs you are not supposed to do with variables declared such, it does behave bugged, but i don't seem to be able to generate an error.
The dynamic-extent is only for gensymed variables holding dimensions of the matrix. Since the user of the macro can't access them in any way (export them outside of the scope of the declaration) I sort of thought that's a good idea :)
But, compilers who can't stack allocate those variables ignore that declaration anyway, so that the declaration shouldn't do any harm.
And compiler notes can be muffled for those who are annoyed by notes complaining inability to stack allocate.

Re: What little functions/macros do you use?

Here's one I find helpful:
(defun make-keyword (sym)
  (intern (symbol-name sym) :keyword))

(defun catsyms (&rest symbols)
  (intern (format nil "~{~S~}" symbols)))

(defmacro deferror (error-name report-format &rest slot-names)
  "Defines error conditions. 
  Condition object slots are used as format arguments in the order they appear in.
  Also automatically defines appropriate reader functions for condition slots."
  (with-gensyms (condition stream)
    `(define-condition ,error-name (error)
       ,(loop for slot-name in slot-names
              collect (list slot-name 
                            :initarg (make-keyword slot-name)
                            :reader (catsyms error-name '- slot-name)))
       (:report (lambda (,condition ,stream)
                  (format ,stream
                          ,report-format
                          ,@(loop for slot-name in slot-names
                                  collect (list (catsyms error-name '- slot-name) 
                                                condition))))))))
It's for quickly and concisely defining new error conditions. You use it like this:
(deferror shader-compile-error "~@(~A~) shader compile failed.~%Shader output: ~A~%" type output)
Then you can just throw errors with the normal error forms. I find myself using much better error signalling now, because defining appropriate errors is easier.

Re: What little functions/macros do you use?

Those look like good ones. I am a little annoyed at times by INTERN too, for instance, it is annoying that you cant just re-intern symbols, you have to get symbol-name all the time. Same for the package, you can't just refer to it with a string/symbol, you have to get the actual package. CL sometimes seems to have the idea a little to use functions as a tool for the user to define the types(for instance ELT for sequences(more general), NTH for lists, AREF for arrays), don't think that is the best approach, or that CL applies it consistently. (For instance, string-downcase works on symbols)

To try get intern to work for me better i guess i am going to try
(defun intern* (name &optional (package *package*))
  "More flexible interning."
  (typecase name
    (string
     (intern name (typecase package
		    (package            package)
		    ((or symbol string) (find-package package)))))
    (symbol
     (intern* (symbol-name name) package))))
There are valid uses, but also some abuses of altering symbols. For instance changing symbols and defining functions with those names is bad practice; people might collide with those. Better to use a hash table with functions, or methods with first argument EQL to something, or (even)a separate package, though that seems a little crazy.

The error macro looks good too, ah apparently you enter a symbol into the first argument of ERROR to call the error by that name. Feel silly i didn't even know that..