LINUX.ORG.RU

Как тестировать чужой код когда он не совсем укладывается в spec языка

 ,


1

2
(defun is-var (expr)
  "is this a variable (i.e. starts with ?)"
  (and (symbolp expr) (eql (char (symbol-name expr) 0) #\?)))

(defun find-vars (expr)
  "returns a list of all the variables in expr"
  (if (consp expr) (append (find-vars (car expr)) (find-vars (cdr expr))) ;; Kак этот append работает?
    (if (is-var expr) (list expr) nil)))

тестирую append

CL-USER 2 > (append 'Z '(a sd))
Error: Z (of type SYMBOL) is not of type LIST.

CL-USER 3 : 1 > (append (car '(1 2 3)) (cdr '(1 2 3)))
Error: 1 (of type FIXNUM) is not of type LIST.

CL-USER 17 > (append (car '(s d f)) (cdr '(1 2 3)))
Error: S (of type SYMBOL) is not of type LIST.

А ведь тут работает, почему?

CL-USER 13 > (find-vars '?)
(?)

CL-USER 16 > (find-vars '(s d ?))
(?)



Последнее исправление: saufesma (всего исправлений: 3)

Ответ на: комментарий от monk

Тут (append (find-vars …) (find-vars …)). find-vars возвращает список.

Да тут видно, что рекурсия, а вопрос остался открытым, я усложнил задачу, и как видно код отбрасывает все кроме "?"

CL-USER 3 > (find-vars '(s d ? c v))
(?)

CL-USER 4 > (find-vars '(1 2 3 4))
NIL

Попробовал посмотреть вот так

(defvar my-var)
(setq my-var nil)
(defun test-find-vars (expr)
  "returns a list of all the variables in expr"
  (if (consp expr)
      (push (append (find-vars (car expr)) (find-vars (cdr expr))) my-var)
      (progn
       (if (is-var expr) (list expr) nil)
      myvar)))

с таким выходом

CL-USER 9 > (test-find-vars '(1 2 3 4))
(NIL)

CL-USER 10 > (test-find-vars '(1 2 3 4 ?))
((?) NIL)

CL-USER 11 > (test-find-vars '(? 1 2 3 4 ?))
((? ?) (?) NIL)

CL-USER 12 > (test-find-vars '(? 1 2 ? 3 4 ?))
((? ? ?) (? ?) (?) NIL)

а как сюда внутрь заглянуть

(append (find-vars …) (find-vars …)).
как is-var передаётся список с "?" ?

Ткрзают меня смутные сомнения, а не посредством ли (find-vars (car expr)) is-var получает "?" ? Как?

(consp expr)
плучает (car expr)
передает его is-var
is-var проверяет и если это ? создаёт список

затем 
(consp expr)
передается (cdr expr)

тогда append нужен чтобы кого-то обмануть?
теперь было-бы неплохо объяснить почему в my-var nil, или это моё nil
(setq my-var nil)

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 4)
Ответ на: комментарий от saufesma

а как сюда внутрь заглянуть

Так и заглядывай

(find-vars '(s d ? c v))
==
(append (find-vars 's) (find-vars '(d ? c v)))
;; (find-vars 's) = nil
==
(find-vars '(d ? c v))
==
(find-vars '(? c v))
==
(append (find-vars '?) (find-vars '(c v)))
;; (find-vars '?) = '(?)
==
(append '(?) (find-vars '(c v)))
==
(append '(?) (find-vars '(v)))
==
(append '(?) (find-vars nil))
==
'(?)
monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Не наводи тень на плетень, я уже заглянул

(find-vars '(d ? c v))
(consp (find-vars (car '(d ? c v))
(is-var 'd => nil

(find-vars '(? c v))
(consp (find-vars (car '(? c v))
(is-var '? => (list '?)

И всетаки что же делает append?

saufesma
() автор топика
Ответ на: комментарий от monk

И всетаки что же делает append?

Я не про мануал, а про его присутствие в коде ведь my-var то пустой?

no-such-file, ados

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 1)
Ответ на: комментарий от saufesma

ведь my-var то пустой

Почему пустой?

> (test-find-vars '(1 2 3 4))
(NIL)

> (test-find-vars '(1 2 3 4 ?))
((?) NIL)

> (test-find-vars '(? 1 2 3 4 ?))
((? ?) (?) NIL)

> (test-find-vars '(? 1 2 ? 3 4 ?))
((? ? ?) (? ?) (?) NIL)

> my-var
((? ? ?) (? ?) (?) NIL)
monk ★★★★★
()
Ответ на: комментарий от monk
 my-var
((? ? ?) (? ?) (?) NIL)

не понимаю пока как это там оказалось?

append в коде складывает результат от первого элемента с результатом от остальных.

так поэтому я и ожидаю

my-var
(? 1 2 ? 3 4 ?)) должны повторяться

но никак не

 my-var
((? ? ?) (? ?) (?) NIL)

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 1)
Ответ на: комментарий от saufesma

не понимаю пока как это там оказалось?

Ты пишешь:

(push (append (find-vars (car expr)) (find-vars (cdr expr))) my-var)

что эквивалентно

(push (find-vars expr) my-var)

То есть при каждом запуске в my-var добавляется значение последнего вычисления (find-vars expr).

monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

там в коде косяк был отловил косяк Было


CL-USER 14 > (defun test-find-vars (expr)
  "returns a list of all the variables in expr"
  (if (consp expr)
      (push (append (find-vars (car expr)) (find-vars (cdr expr))) my-var)
      (progn
       (if (is-var expr) (list expr) nil)
      myvar))) <<<<<<<<<<<<<<<<
стало
CL-USER 14 > (defun test-find-vars (expr)
  "returns a list of all the variables in expr"
  (if (consp expr)
      (push (append (find-vars (car expr)) (find-vars (cdr expr))) my-var)
      (progn
       (if (is-var expr) (list expr) nil)
      my-var)))<<<<<<<<<<<<<<<<<<<<<<

CL-USER 15 > (setq my-var nil)
NIL

CL-USER 16 > (test-find-vars '(? 1 2 ? 3 4 ?))
((? ? ?)) 

CL-USER 17 > my-var
((? ? ?))<<---почему?

То есть при каждом запуске в my-var добавляется значение последнего вычисления (find-vars expr).

Добавляется только (find-vars (cаr expr)), а куда делся (find-vars (cdr expr))?

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 5)
Ответ на: комментарий от saufesma
(test-find-vars '(? 1 2 ? 3 4 ?))
==
;; (consp '(? 1 2 ? 3 4 ?)) = t
(push (append (find-vars (car expr)) (find-vars (cdr expr))) my-var)

Добавляется только (find-vars (cаr expr)), а куда делся (find-vars (cdr expr))?

???

(cаr expr) = '?
(cdr expr) = '(1 2 ? 3 4 ?)
(find-vars (cdr expr)) = '(? ?)

добавилось ’(? ? ?)

P.S. тестируй лучше на (find-vars ’(?a 1 2 ?b 3 4 ?c)) == ’(?a ?b ?c), чтобы было очевидней из какой ветки какое значение.

monk ★★★★★
()
Ответ на: комментарий от monk
(cаr expr) = '?
(cdr expr) = '(1 2 ? 3 4 ?)
(find-vars (cdr expr)) = '(? ?) здесь я спёкся, не понимаю

P.S. тестируй лучше на (find-vars ’(?a 1 2 ?b 3 4 ?c)) == ’(?a ?b ?c), чтобы было очевидней из какой ветки какое значение.

Может через несколько дней пойму?

saufesma
() автор топика
Ответ на: комментарий от monk
> (find-vars '(1 2 ? 3 4 ?))

в том то и дело, что я вижу это как резултат  

(is-var (find-vars (cаr expr)) (list expr))
(? ?) 

каким-то образом оказавшимся в my-var

и ни коим образом не действия append

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 2)
Ответ на: комментарий от monk

Накидываю мысли

CL-USER 31 > (defun test-find-vars (expr)
  "returns a list of all the variables in expr"
  (if (consp expr)
      (push (append (find-vars (car expr)) (find-vars (cdr expr))) my-var) <<<<<<<<<<<<
      (progn
       (if (is-var expr) (list expr) nil)
      my-var1))) <<<<<<<<<
TEST-FIND-VARS

CL-USER 34 > (setq my-var nil)
NIL

CL-USER 35 > (setq my-var1 nil)
NIL

CL-USER 36 > (test-find-vars ’(?a 1 2 ?b 3 4 ?c))
((?A ?B ?C))

CL-USER 37 > my-var
((?A ?B ?C)) вот куда остальное девается?

CL-USER 38 > my-var1
NIL
saufesma
() автор топика
Ответ на: комментарий от saufesma

и ни коим образом не действия append

(cаr expr) = '?
(cdr expr) = '(1 2 ? 3 4 ?)
(find-vars '?) = '(?)
(find-vars '(1 2 ? 3 4 ?)) == '(? ?)
my-var == (append '(?) '(? ?)) == '(? ? ?)
monk ★★★★★
()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk
(find-vars '?) = '(?)
(find-vars '(1 2 ? 3 4 ?)) == '(? ?)
my-var == (append '(?) '(? ?)) == '(? ? ?) больше похоже на лукавство которое объясняет выхлоп функции, но до меня не доходит куда цифры делись?

хотя

(if (is-var expr) (list expr) nil)
                       ^^^ вот это место куда результат складывает?

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 1)
Ответ на: комментарий от monk
(cаr expr) = '?
(cdr expr) = '(1 2 ? 3 4 ?)
(find-vars '?) = '(?)
(find-vars '(1 2 ? 3 4 ?)) == '(? ?)
my-var == (append '(?) '(? ?)) == '(? ? ?) там даже пример такой есть, где-то

с такими вещами я в Racket столкнулся и так и не понял как это работает

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 1)
Ответ на: комментарий от saufesma

Вот же я расписал, куда лишнее девается: Как тестировать чужой код когда он не совсем укладывается в spec языка (комментарий)

вот это место куда результат складывает

Не складывает, а возвращает.

(find-vars ’1) = nil, (find-vars ’?) = ’(?). А дальше из этих результатов общий собирается.

monk ★★★★★
()
Ответ на: комментарий от monk

А дальше из этих результатов общий собирается.

А в моём мозгу это выглядит как бугалтерия

(append (find-vars '?) здесь кредитуем
(find-vars '(c v))) а тут дебетуем
;; (find-vars '?) = '(?)
а параллельность этих действий в одном и том же месте у меня в голове пока не укладывается, надо ещё повошькаться с кодом.

saufesma
() автор топика
Последнее исправление: saufesma (всего исправлений: 1)