5 ms·
Does someone know offhand why these HTML generators are macros and not just functions? If I need to RTFSC that's fine, but thought I'd ask in case it's a quick
by vegashacker 17y ago
Does someone know offhand why these HTML generators are macros and not just functions? If I need to RTFSC that's fine, but thought I'd ask in case it's a quick answer.
- pmarin 17y agoJust try to imitate the behaviour of this library in your favorite language. I tried in Tcl, simulating macros with upvar, uplevel and even with sugar and is not easy to get the same result. http://tverdeforge.googlepages.com/ahtml.tcl.txt http://tverdeforge.googlepages.com/ahtml.tcl.txt
- vegashacker 17y agoNot sure I buy it. My favorite language is Scheme (specifically, PLT Scheme). You'll find no macros below: (define (whitepage . content) `(html (body ,@content))) (define (para) `(p)) (define (link prose url) `(a ((href ,url)) ,prose)) (define (prbold text) `(strong ,text)) So the example from the Arc link (whitepage "Hello world!" (para) (link "Click here" "http://news.ycombinator.com") "for" (prbold "more stuff")) yields (html (body "Hello world!" (p) (a ((href "http://news.ycombinator.com")) "Click here") "for" (strong "more stuff"))) which is a valid expression that PLT's web server will render as a web page.
- gms 17y agoJudging by the HTML macros he talks about in ANSI Common Lisp, they had to be macros since they output HTML to file using a bunch of FORMAT calls. Since side-effects were involved and the calls had to be evaluated at specific points before and after other such calls, they had to be macros.
- vegashacker 17y agoAh ha! Thanks, gms. But this brings us to the question... are we getting anything by using side-effecty print statements to make web pages? I don't see it. I think I vastly prefer building up my markup functionally, and then handing it off to the web server when done. Plus, with the PLT way, you avoid writing macros. And a wise man once wrote, "It's considered to be bad style to use [macros] when they're not necessary." ;) Okay...I'll leave my "Are we getting anything" question there, but it probably shouldn't be answered. Or at least not here. It's essentially the pure-functional versus side-effect debate. To be fair, you get benefits from both, and both have downsides that the others are better at.
- gms 17y agoYes I prefer your approach too (I use a similar approach with the Elisp I use to publish posts on my blog). You are also right that one shouldn't use a macro where a function would do. When looking at PG's approach in ACL, it's worth remembering that he came up with it more than 10 years ago, and consider it in that context. The surrounding ecosystem for web development was a lot more primitive back then (which serves to highlight how impressive his idea is/was).
- pmarin 17y agoBut your result is not html. In the Arc library the arguments of the tags, like whitepage are any expression and only tag the stdout (you can redirect the output to another port). For example: (= a 1) (whitepage (= b (+ a 1)) (pr b)) And you obtain: <html><body bgcolor=#ffffff alink=#0000be>2</body></html>
- antiismist 17y agoFor the uvar example you could get could get close (from news.arc): (mac uvar (u k) `((profs* ,u) ',k)) (def user-age (u) (hours-since (uvar u created))) Without a macro you'd have to call uvar like: (uvar u 'k). For this example I'd favor 'k because it makes the behavior clearer. (Did you mean uvar instead of upvar?)
- pmarin 17y agonope, I said that I tried to write the html library in the Tcl programming language using the Tcl comands upvar and uplevel trying to simulate the lisp's macros.
- magv 17y agoIf you are using functions you have to first construct the whole page and only then render it's html. If you are using macros you may start sending the html parts before the whole page is constructed. The latter approach is advantageous if a page needs some heavy computations to generate it: with macros the user will start seeing at least something right away; plus, the browser will load CSS faster if you send that part before the computations. On the other hand if there was an error in the middle of page generation you will not be able to handle it gracefully since you've already send half of the page to the user.
- shiro 17y ago> If you are using functions you have to first construct the whole page and only then render it's html. Not necessarily... even using functions, you can create a 'lazy node' in the page graph to delay completion of calculation until the final renderer actually starts rendering the node. I guess the only advantage of using macros is that you can make page generation code without consing relatively easily. I'm not sure how necessary it is for web servers, but it may matter for extremely high-traffic sites.