Page 3 of 3

Re: What little functions/macros do you use?

Posted: Tue Apr 13, 2010 3:43 am
by Jasper
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?

Posted: Tue Apr 13, 2010 4:43 am
by karol.skocik
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?

Posted: Sun May 09, 2010 10:47 pm
by Main
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.

Re: What little functions/macros do you use?

Posted: Wed May 12, 2010 3:09 am
by Jasper
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..