keyword-macro, should at least be fairly obvious, it does exactly what defmacro does, but binds it after (keyword-macro bound-to ....) (it is useless, it's point it to show how it can vary, there are less useless variations) I didn't specify how the last way, going via a renamed function, works, but it is straightforward; you just mess with the symbol-name and re-intern it.
dlweinreb wrote:One very important principle is to never use a macro when all you need is a function.
Easily said; you can do just about everything with functions, but it isn't always readily apparent. And sometimes macros can clean it up a little. Like do-something-before-fun vs do-something-before. I doubt though, that many people would write the first.
LML2 certainly spits in the face of this principle. (Not sure about LML, i don't get how LML2 claims to be able to be faster than LML, i don't see an issue) GIL doesn't, it is all-functions, but not sure if this might slow it down.(I should see if i can get GIL served in the macro-sense too, though perhaps i can use existing definitions)I still haven't written a LML2 vs GIL comparison yet, i probably should.
LML2 could do the 'same thing', without macros. What i will tell you here is similar to how GIL works, but applied to
LML. There, I, B, P and such could be functions.(you only have to funcall them after) You can make those return a function from, say P, and calling that function will then write the input. The arguments might be functions, like from B, or strings, which it will just print.
The only real disadvantage to this is that you have to depend on the compile to expand (funcall (lambda ()..)) that effectively ensues. Of course, the compile being able to
not expand it could be space saver. And
in principle the (funcall (lambda()..))s should be inlinable, just like the macro. (And perhaps one could do optimizations with def-compiler-macro too)
At this point i can't really argue you cannot store intermediate results if they were macros; you could still use the macros inside a lambda. However what if you want to be able to output different results from combine it with the *way* thing, you cannot; the macros can't use that special variable, but the function approach can. In the case of GIL, this is *lang*, the output language, with values like :info(gathers info on text, links, sections, indexing of words), :txt, :html, :latex(undertested, latex can be such a pain in ass), :clg(under development). But i am not entirely satisfied my approach is well-enough thought out, and if it is, it is pointless if people won't use it. (Hence, as i said, i should be writing that comparison, i guess what i wrote here goes part of the way.)
I guess you could do your example the following way:
Code: Select all
;foo is just a function, call-callback is just funcall.
(defun bars-way (a-foo)
(lambda ()
(format t "Executing callback of ~a~%" obj)
(funcall a-foo)
(format t "Execution finished.~%"))))
And then your example goes:
Code: Select all
(let ((a-foo (lambda () (print "Hello world!"))))
(funcall a-foo) => first result
(funcall (bars-way a-foo)) => second result
So an sich i don't really see the point there. However, it is nice to have (type)names on stuff. Guess a named-lambda might do that, if CLOS could see that name. (minding that limitations of clos shouldn't be internalized

) Hmm, one could make a macro(this one a bit ugly, name isn't thought out)
Code: Select all
(defmacro clos-identifyable-lambda (name args &body body)
(let ((class-name (intern (symbol-name name) (find-package :package-just-for-this-purpose))))
(unless (find-class class-name)
(defclass ,class-name () ((fun :initarg :fun :type function))))
`(make-instance ',class-name :fun (lambda ,args ,@body))))
And then define caller-functions.
I should really be trying weblocks, btw. Presumably it does also divide things into pages, and then pages have standard elements. Since this is about different ways of doing things, i can give one for that too. In GIL there are SECTIONs, somewhat like Latex sections. These have a level. (according to header level in HTML, not sure if that is wise

) You can set a level to determine if a section should have it's own page, like an html file, so if this level is 'triggered' you have a function/object from the SECTION function, which will be put into a function *handle-page*, which can attach whatever it wants to the page, like a sidebar with menu. (hmm *page-hook* might be better name) (Now am looking at it, the function that is supposed to be stored in *handle-page* should have different arguments though.)
Wow this post seems almost excessively coherent. I mean it goes from dlweinrebs comment about macros to LML2 to how LML implemented with functions is similar to GIL, to how gil:*lang* is an example of *way* and macros don't seem to be able to use special variables like that, to another way of doing gugamilares example, to how the same two different ways may be occuring in weblocks vs gil.(And how i made my little websites.)