Open charJe opened 3 years ago
Could you give me a more concrete example? I recently tried using a macro, and then found it to be error prone because it was strongly dependent on file loading order. But I'm sure we could add a separate deftag*, but give me an example so I understand its use case better.
Say I want all tab
tags to have a title
attribute.
(deftag tab (children &key (title (error "tab must have a title")))
<:tab title=title >
,@children
</:tab>)
Provides good run time checking, but I would prefer to catch it before that.
Got it, I think just making tag into a macro would not achieve what you're looking for. Markup doesn't use the #'tag
(the function stored in tag
) when you call <tag>
, instead it calls the function stored in (get 'tag 'markup-fn)
. #'tag was designed for convenience, and probably isn't as performant (it let's you create the same tag with s-expressions (tag :title foo (child-tag) (child-tag)
).
<tag>
expands to (make-xml-tag 'tag ...)
. In order to build what you're asking for, we could make make-xml-tag
into a macro and build some kind of extension mechanism.
Alternatively, I already have a define-compiler-macro
for make-xml-tag
: https://github.com/moderninterpreters/markup/blob/master/markup.lisp#L484. We could create an define-markup-compiler-macro
that provides an extension point to this, so that you can create custom compile time validations.
Using a compiler macro is what I originally tried, but I guess it didn't work because the tab tag isn't actually using the #'tab function.
Another scenario where defmacrotag would be useful would be for i18n. Imagine a
Currently
deftag
defines a function. Would it be possible to have something likedeftag*
that defines a macro. I mainly want this so I can require certain tags to have certain attributes (and error at compile time if the attributes are missing).