我是个口齿不清的初学者,我决定写一个Telegram机器人作为测试项目。在这里,我遇到了一些意想不到的行为
let
该代码采用.asd格式,其中一个文件包含以下代码。它的重要部分要注意:
-
long-poll-updates
函数基本上是一个循环。
-
致电
read-updates
在里面
长轮询更新
功能
-
致电
check-integrity
在里面
阅读更新
功能。
-
checks
let形式的变量。
在主循环的每次迭代中,我都会执行以下操作
(prin1 checks)
看到一些我很难抬头或理解的东西。在循环的第一次迭代中,它会打印出我分配给它的值。每次新的迭代都不会重新分配
nil
返回值,但使用前一次迭代操作留下的相同精确值。
(defun long-poll-updates ()
"Main loop. Repeatedly sends requests to get updates."
; Sets a variable for storing the last processed updates's ID.
(let ((offset 0)) (loop
(let* ((api-answer (get-updates-request offset))
(parsed-plist (jonathan:parse
(flexi-streams:octets-to-string api-answer))))
;; Read response and modify offset parameter to get next updates.
(let ((response-data (read-updates parsed-plist)))
(when (getf response-data :has-results)
(setf offset
(1+ (getf response-data :last-update-id)))))))))
(defun read-updates (response-plist)
"Reads the incoming long poll response:
checks for response validity/errors,
proceeds to an appropriate action."
(let ((response-data (check-integrity response-plist)))
(cond ((getf response-data :has-ok)
(cond ((getf response-data :is-ok)
;; Evaluate updates on successful poll
(cond
((getf response-data :has-results)
(setf (getf response-data :last-update-id)
(eval-updates response-plist)))
(t
(log-data "No results received."))))
(t (log-errors response-plist))))
(t (log-data "Received malformed JSON-response while long polling.")))
response-data))
(defun check-integrity (response-plist)
"Runs checks for valid JSON received, success/faliure and presence of new updates.
Returns a plist of checks passed/failed."
(let ((checks '(:has-ok nil
:is-ok nil
:has-results nil)))
(prin1 checks)
(loop :for (indicator value) on response-plist by #'cddr
;; If successful response:
:when (eql indicator :|ok|)
:do (progn
(setf (getf checks :has-ok) t)
(when (eql value t)
(setf (getf checks :is-ok) t)))
;; If any results:
:when (and (eql indicator :|result|)
(listp value)
(< 0 (length value)))
:do (setf (getf checks :has-results) t))
checks))
我想我希望每次调用函数时,函数的代码都会重新计算,甚至没有意识到这一点。然而,在代码运行之前,编译器似乎会将数据计算到某个永远不会离开内存的实体。有人能告诉我一个我在这里处理的更大的想法吗?
我看到lisp的方式真的是“理论优先”,我很少发现人们以一种块状和杂乱的方式(或者当你刚接触lisp,但之前有编码经验时,无论是什么样子)来记录他们在处理它时所面临的问题。我觉得这很奇怪,但这不是重点。