[EDIT:
я просто понял, что я перепутался на обработке arguement,
так что мое «решение» сломано
, если не будет по крайней мере, три список дается my-defun
после списка параметров ,
Я положил (я думаю) фактическое рабочее решение в конце.
]
Я действительно понял это!
это не слишком сложно,
даже для новыхb.
(
я имею в виду,
я не удивлюсь, если ужасные вещи будут происходить, если один на самом деле пытались использовать его в «реальном коде»,
потому реберных случаев или что-то,
, но это работая проверка концепции
)
во всяком случае, вот определение my-defun
макро,
работает, как я описал в eg4
в моем вопросе:
(
пожалуйста, никто редактировать странное форматирование -
я понимаю, что это нестандартный,
, но это действительно помогает newbs прочитать сложный новый материал.
Я имею в виду,
, если другой новыйb, как я когда-либо читал это,
Я думаю, что это поможет им значительно.
)
(defmacro my-defun (name params withsymbol withlist &body body)
(cond
((equal withsymbol 'with)
; (print 'withsymbol_set_to_) ;diagnostic
; (print withsymbol) ;diagnostic
; (print 'withlist_set_to_) ;diagnostic
; (print withlist) ;diagnostic
; (print ;diagnostic
`(defun ,name ,params
(let ,withlist
(progn ,@body)
)
)
;) ;diagnostic
)
(t
; (print 'withsymbol_not_set_to_with_but_) ;diagnostic
; (print withsymbol) ;diagnostic
; (print 'withlist_set_to_) ;diagnostic
; (print withlist) ;diagnostic
; (print ;diagnostic
`(defun ,name ,params
(progn ,withsymbol ,withlist ,@body)
)
;) ;diagnostic
)
)
)
первый тест, с with
:
(my-defun demo4 (x)
with (
(a 1)
(b 2)
)
; this prints!
(print a)
(print b)
(print x)
)
(demo4 "hi")
; this correctly gets a "no value" error!
(print a)
(print b)
(print x)
выход:
1
2
"hi"
выход с диагностическими линиями раскомментирована:
WITHSYMBOL_SET_TO_
WITH
WITHLIST_SET_TO_
((A 1) (B 2))
(DEFUN DEMO4 (X) (LET ((A 1) (B 2)) (PROGN (PRINT A) (PRINT B) (PRINT X))))
1
2
"hi"
второе испытание, без with
:
(так он действует точно так же, как обычный defun
)
(my-defun demo4 (x)
; (this stuff also prints)
(print "i am not the withsymbol")
(print "this is not the withlist")
; this prints!
(print "symbol 'a would have no value")
(print "symbol 'b would have no value")
(print x)
)
(demo4 "hi")
; this correctly gets a "no value" error!
'(print a)
'(print b)
'(print x)
выход:
"i am not the withsymbol"
"this is not the withlist"
"symbol 'a would have no value"
"symbol 'b would have no value"
"hi"
выход с диагностическими линиями раскомментирована:
WITHSYMBOL_NOT_SET_TO_WITH_BUT_
(PRINT "i am not the withsymbol")
WITHLIST_SET_TO_
(PRINT "this is not the withlist")
(DEFUN DEMO4 (X)
(PROGN (PRINT "i am not the withsymbol") (PRINT "this is not the withlist") (PRINT "symbol 'a would have no value")
(PRINT "symbol 'b would have no value") (PRINT X)))
"i am not the withsymbol"
"this is not the withlist"
"symbol 'a would have no value"
"symbol 'b would have no value"
"hi"
минимально различные примеры:
использованием defun
с let
и использованием my-defun
с with
(просто хотел глазное яблоко, в какой степени результат выглядит стоит свеч XD)
( defun demo (x)
(let (
(a 1)
(b 2)
)
(print a)
(print b)
(print x)
)
)
(my-defun demo (x)
with (
(a 1)
(b 2)
)
(print a)
(print b)
(print x)
)
ФАКТИЧЕСКИ рабочего раствора (I НАДЕЖДА):
(defmacro fun (name params &rest rest)
(let (
(withsymbol (car rest))
(withlist (car (cdr rest)))
(body (cdr (cdr rest)))
)
; (p withsymbol ) ;;debug
; (p withlist ) ;;debug
; (p body ) ;;debug
(cond
((equal withsymbol 'with)
; (print 'BRANCH_A) ;;debug
; (print ;;debug
`(defun ,name ,params
(let* ,withlist
(progn ,@body)
)
)
;) ;;debug
)
(t
; (print 'BRANCH_B) ;;debug
; (print ;;debug
`(defun ,name ,params
(progn ,@rest)
)
;) ;;debug
)
)
)
)
;; for debugging
(defmacro p (symbol)
`(format t "~A ~A~%" ',symbol ,symbol)
)
хотя t шляпа была самой ранней рабочей версией кода, , так что, возможно, я испортил ее, не заметив, переименовывая переменные не полностью или что-то в этом роде.
самого последний код, который я на самом деле просто тестированием является более сложным:
;; used in debug
(defmacro p (symbol)
`(format t "~A ~A~%" ',symbol ,symbol))
(defmacro mac-or-fun (which-one name params rest)
(let (
(withsymbol (car rest))
(withlist (car (cdr rest)))
(body (cdr (cdr rest)))
)
; (p withsymbol ) ;;debug
; (p withlist ) ;;debug
; (p body ) ;;debug
(cond
((equal withsymbol 'with)
; (print 'BRANCH_A) ;;debug
; (print ;;debug
`(,which-one ,name ,params
(let* ,withlist
(progn ,@body)
)
)
;) ;;debug
)
((equal withsymbol 'omwith)
; (print 'BRANCH_A) ;;debug
; (print ;;debug
`(,which-one ,name ,params
(omlet ,withlist
(progn ,@body)
)
)
;) ;;debug
)
(t
; (print 'BRANCH_B) ;;debug
; (print ;;debug
`(,which-one ,name ,params
(progn ,@rest)
)
;) ;;debug
)
)
)
)
(defmacro fun (name params &rest rest)
`(mac-or-fun defun ,name ,params ,rest))
(defmacro mac (name params &rest rest)
`(mac-or-fun defmacro ,name ,params ,rest))
;; for use in tests
(defun ps (&rest stringlist)
(format t "~A~%" (eval `(concatenate 'string ,@stringlist))))
(defparameter *vs-use-count* 0)
(defmacro vs (&rest title)
(setf *vs-use-count* (+ 1 *vs-use-count*))
(ps "
SECTION " (write-to-string *vs-use-count*) " " (write-to-string title) " -"
)
)
;;;tests
(progn
(vs fun works with "with")
(fun f()
with ((a 1))
(print a)
)
(f)
(vs fun works with "nil")
(fun f()
()
)
(print(f))
(vs original fun test with "with")
(fun demo4 (x)
with (
(a 1)
(b 2)
)
; this prints!
(print a)
(print b)
(print x)
)
(demo4 "hi")
; these would correctly gets a "no value" error!
'(print a)
'(print b)
'(print x)
(vs original fun test with no "with")
(fun demo4 (x)
; (this stuff also prints)
(print "i am not the withsymbol")
(print "this is not the withlist")
; this prints!
(print "symbol 'a would have no value")
(print "symbol 'b would have no value")
(print x)
)
(demo4 "hi")
; these would correctly gets a "no value" error!
'(print a)
'(print b)
'(print x)
(vs mac works with "with")
(mac m()
with ((a 1))
(print a)
)
(m)
(vs mac works with "nil")
(mac m()
()
)
(print(m))
)
;;; more stuff,
;;; leading up to the macro `omlet`,
;;; which is used in `mac-or-fun`
(fun pair-up (l)
with (
(a (car l) )
(b (car (cdr l)) )
(l-past-b (cdr (cdr l)) )
)
(cond
(
(equal 2 (length l))
(list l)
)
(t
(cons (list a b) (pair-up l-past-b))
)
)
)
(fun crack-1 (eggs)
with (
(paired-list (pair-up eggs))
(paired-list (loop for (k v) in paired-list collect `(,k ',v)))
)
paired-list
)
(fun crack-2 (eggs)
with (
(key-name (car eggs))
(value-name (car (cdr eggs)))
(eggs (cdr (cdr eggs)))
(paired-list (pair-up eggs))
(keys-list (loop for pair in paired-list collect (first pair)))
(values-list (loop for pair in paired-list collect (second pair)))
(key-name-keys (list key-name keys-list))
(value-name-values (list value-name values-list))
(paired-list (append paired-list (list key-name-keys value-name-values)))
(paired-list (loop for (k v) in paired-list collect `(,k ',v)))
)
paired-list
)
(fun crack (eggs)
(if
(and
(equal '- (car eggs))
(oddp (length eggs))
)
(crack-2 (cdr eggs))
(crack-1 eggs)
)
)
(mac omlet (eggs &body body)
with ((to-let (crack eggs)))
`(let ,to-let (progn ,@body))
)
(mac lemego (&rest eggs)
with ((to-set (crack eggs)))
(loop for (name value) in to-set
do (eval `(setf ,name ,value))
)
)
;;; more tests
(progn
(vs omlet 1)
(omlet (
x a
y b
z c
)
(print x )
(print y )
(print z )
)
(vs omlet 2)
(omlet (
- names digits
one 1
two 2
three 3
)
(print one )
(print two )
(print three )
(print names )
(print digits )
)
(vs fun with omwith 1)
(fun f()
omwith (
x a
y b
z c
)
(print x )
(print y )
(print z )
)
(f)
(vs fun with omwith 2)
(fun f()
omwith (
- names digits
one 1
two 2
three 3
)
(print one )
(print two )
(print three )
(print names )
(print digits )
)
(f)
(vs lemego 1)
(lemego
x a
y b
z c
)
(print x )
(print y )
(print z )
(vs lemego 2)
(lemego
- names digits
one 1
two 2
three 3
)
(print one )
(print two )
(print three )
(print names )
(print digits )
)
«синтаксис' let' заставляет вас использовать дополнительные слои, круглых скобок и обернуть всю функцию тело в наружном слой, , который просто затрудняет чтение и запись без причины ». Вам не хватает важного момента: обертка их в круглых скобках не оставляет никаких сомнений в их объеме. Если ваши функции дойдут так долго, что «дополнительный слой парнеров» является проблемой, то вы делаете что-то не так;) –
hmmm ... я считаю, что этот аргумент очень неубедительный в этом случае? я понял это и отправил его как ответ на мой собственный вопрос. я положил mindif, используя оба способа в конце, чтобы помочь глазному яблоку, насколько он стоит того, что было (вы можете скопировать их каждый в буфер и быстро перевернуть назад, чтобы действительно визуально выделить различия), и ... я все еще подумайте, что это имеет смысл, вы знаете? нет сомнений в объеме, потому что он просто завершает 'let' и подходит к концу вызова' my-defun'. –