What little functions/macros do you use?

Discussion of Common Lisp
Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: What little functions/macros do you use?

Post by Jasper » Tue Apr 13, 2010 3:43 am

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.

karol.skocik
Posts: 10
Joined: Tue Sep 22, 2009 4:50 pm

Re: What little functions/macros do you use?

Post by karol.skocik » Tue Apr 13, 2010 4:43 am

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.

Main
Posts: 2
Joined: Wed Aug 20, 2008 8:17 am

Re: What little functions/macros do you use?

Post by Main » Sun May 09, 2010 10:47 pm

Here's one I find helpful:

Code: Select all

(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:

Code: Select all

(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.

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: What little functions/macros do you use?

Post by Jasper » Wed May 12, 2010 3:09 am

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

Code: Select all

(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..

Post Reply