(Setq make-trees 2)
устанавливает значение переменной make-trees
в 2, затем возвращает 2.
Я не вижу причины для макроса в том, что вы описываете.Правда ли, что ваш make-trees
создает одно случайное дерево, которое можно интерпретировать как программу?Просто определите это как функцию с defun
.Я думаю о чем-то вроде этого:
(defun make-tree (node-number)
(if (= node-number 1)
(make-leaf)
(cons (get-random-operator)
(mapcar #'make-tree
(random-partition (- node-number 1))))))
Let
и setq
делают совершенно разные вещи.Setq
присваивает значение существующей переменной, тогда как let
создает новую лексическую область с несколькими лексическими привязками.
Я думаю, что вы должны представить больше своего кода;в настоящее время ваш вопрос не имеет большого смысла.
Обновление:
Я исправлю отступ в вашем фрагменте, чтобы прояснить ситуацию:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings))))
(list (trees tree-bindings evaluated-trees)))
Теперь, как написано ранее, let*
устанавливает лексические привязки.Они находятся только в пределах своего тела:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings)))
;; here trees, tree-bindings, and evaluated-trees are bound
) ; end of let* body
;; here trees, tree-bindings, and evaluated trees are not in scope anymore
(list (trees tree-bindings evaluated-trees)))
Эта последняя строка также является ложной.Если бы эти имена были связаны, было бы возвращено список из одного элемента, который был бы результатом оценки функции trees
с tree-bindings
и evaluated-trees
в качестве аргументов.
Вы можете получить то, что хотитекак это:
(setq sample
(let* ((trees (make-trees 2))
(tree-bindings (bind-trees trees))
(evaluated-trees (eval-fitness tree-bindings)))
(list trees tree-bindings evaluated-trees)))
Еще одно обновление:
Цель макросов - исключить повторяющийся код, когда это удаление невозможно с помощью функций.Одно из частых применений - при работе с местами, и они также необходимы для определения новых управляющих конструкций.Пока вы не видите, что что-то не может работать как функция, не используйте для этого макрос.
Вот код, который может вам помочь:
(defun make-tree-lambda (depth)
(list 'lambda '(x)
(new-tree depth)))
(defun make-tree-function (lambda-tree)
(eval lambda-tree))
(defun eval-fitness (lambda-form-list input-output-list)
"Determines how well the lambda forms approach the wanted function
by comparing their output with the wanted output in the supplied test
cases. Returns a list of mean quadratic error sums."
(mapcar (lambda (lambda-form)
(let* ((actual-results (mapcar (make-tree-function lambda-form)
(mapcar #'first input-output-list)))
(differences (mapcar #'-
actual-results
(mapcar #'second input-output-list)))
(squared-differences (mapcar #'square
differences)))
(/ (reduce #'+ squared-differences)
(length squared-differences))))
lambda-form-list))
(defun tree-fitness (tree-list input-output-list)
"Creates a list of lists, each inner list is (tree fitness). Input
is a list of trees, and a list of test cases."
(mapcar (lambda (tree fitness)
(list tree fitness))
tree-list
(eval-fitness (mapcar #'make-tree-lambda tree-list)
input-output-list)))