Page 1 of 1

Should there be a backquote in newLISP?

Posted: Thu Aug 30, 2007 2:48 am
by kinghajj
In other LISPs, there is a backquote, which temporarily "undos" a quote. Here's an example:

Code: Select all

(setq foo "bar")
(setq bar '(1 2 3 ,foo foobar)) ; => (1 2 3 "bar" foobar)
This would be really useful when writing macros. For example, here's a macro for "unless" that uses backquotes.

Code: Select all

(define-macro (unless condition)
  (let ( (body (args)) )
    (eval '(if (not ,condition) ,body))))

Posted: Thu Aug 30, 2007 3:09 am
by kinghajj
I saw in a search of the forums that Lutz doesn't like backquotes, so I've come up with a possible solution.

I've implemented a backquote-like feature with a macro.

Code: Select all

; takes an item from the template and decides whether to evaluate it or not.
; if the item starts with an "@" and is a symbol, then return the evaluation
; of that item without the "@", or else just return the item as given.
(define (template-replace s)
	(if (and (starts-with (string s) "@") (symbol? s))
		(eval (sym (1 (string s)))) s))

; templating macro for newLISP.
; example:
;   (setq foo "bar")
;   (template (1 2 @foo foo)) ; => (1 2 "bar" foo)
(define-macro (template tmp)
	(map template-replace tmp))
This way "backquotes" (or, in this case, @-signs) are only enabled when the user wants them. If I re-write this in C, could it be added to newLISP?

Posted: Thu Aug 30, 2007 3:58 am
by Lutz
'expand and 'letex can also be used to implement template functionality ;)

Lutz

Posted: Thu Aug 30, 2007 11:51 am
by Jeff
I also created a macro template function. I missed the backtick from other lisps too:

Code: Select all

(define-macro (template)
  (let ((form (args 0)) (syms (rest (args))))
       (if (symbol? form) (set 'form (eval form)))
       (cond ((empty? syms) form)
             (true
               (begin (nth-set (form (ref '_ form)) (eval (first syms)))
                      (if (rest syms)
                          (eval (cons 'template (cons form (rest syms))))
                          form))))))

(set 'test-fn '(define (_) (println _)))

(set 'some-var "hello")

(set 'expanded
  (template test-fn (sym (format "print-%s" some-var))
                    some-var))

(println expanded)
(eval expanded)
(print-hello)
It uses underscores and replaces underscore symbols serially.