这是我在Lisp程序中的第二次正确尝试,作为Mythender(一个自由分布的桌面RPG)的骰子。但它有几个问题:
当它加载时,我会收到提示以确认包的创建。当然这个文件应该创建它吗?
当我尝试使用LispWorks应用程序构建器独立构建它时,它会给出一个错误,说我正在尝试在编译时调用CAPI函数,但我不知道它在哪里。
我收到了一些与我讨论过的关于(null())部分的lisp人员的负面评论,这些部分意味着函数没有返回,所以没有任何意义在堆栈上留下任何东西 - 这是正确的或不?有没有更好的方法呢?
欢迎任何一般性建议。
(defpackage :mythender (:add-use-defaults t) (:use "CAPI"))
(in-package :mythender)
(defun d6 () (the fixnum (+ 1 (random 6))))
(defun d6s (count)
(declare (type fixnum count))
(the list (loop for x from 1 to count collecting (d6))))
(defun d6over (count threshold)
(declare (type fixnum count threshold))
(the fixnum (count-if
(lambda (x) (> threshold x))
(d6s count))))
(defvar *storm* 3)
(defvar *thunder* 3)
(defvar *lightning* 0)
(declare (ftype (function) printstate))
(defun printstate ()
(print *storm*)
(print *thunder*)
(print *lightning*)
(the null ()))
(defun roll ()
(incf *lightning* (d6over *thunder* 3))
(incf *thunder* (d6over *storm* 3))
(the null ()))
(defun damage (threshold)
(setf *thunder* (d6over *thunder* threshold))
(the null ()))
(defun doroll (&rest args)
(roll)
(update-interface)
(the null ()))
(define-interface mythender-interface () ()
(:panes
(roll-button push-button :data "Roll" :callback #'doroll)
(damage-button push-button :data "Damage")
(storm-pane display-pane :title "Storm:" :title-position :left)
(thunder-pane display-pane :title "Thunder:" :title-position :Left)
(lightning-pane display-pane :title "Lightning:" :title-position :left))
(:layouts
(main-layout column-layout '(storm-pane thunder-pane lightning-pane buttonlayout))
(buttonlayout row-layout '(roll-button damage-button))))
(defvar *interface*)
(defun update-interface-slot (slotname value)
(declare (type string slotname) (type fixnum value))
(setf (display-pane-text (slot-value *interface* slotname)) (write-to-string value))
(the null ()))
(defun update-interface ()
(update-interface-slot 'storm-pane *storm*)
(update-interface-slot 'thunder-pane *thunder*)
(update-interface-slot 'lightning-pane *lightning*)
(the null ()))
(defun start ()
(setf *interface* (make-instance 'mythender-interface))
(display *interface*)
(the null (update-interface)))
答案 0 :(得分:3)
您的构建问题的答案必须等到您告诉我们构建语句和错误消息。
你的上一个问题:
(declare (ftype (function) printstate))
(defun printstate ()
(print *storm*)
(print *thunder*)
(print *lightning*)
(the null ()))
众所周知,它是一种功能。无需声明。声明类似的类型,在普通的Common Lisp中只有编译器可能忽略的优化提示的目的。只有CMUCL(以及像SBCL和SCL这样的派生编译器)实际上对声明的类型做了更多。
没有人在Lisp中编写这样的代码。最好省略类型。请记住:Lisp不是静态类型语言。
(defun printstate ()
(print *storm*)
(print *thunder*)
(print *lightning*)
(values))
使用(values)
会导致函数不返回值。这通常是首选,而不是返回NIL
。
如果您想在运行时以有意义的方式实际检查类型,请使用ASSERT
,CHECK-TYPE
和/或DEFMETHOD
。
(defun d6s (count)
(declare (type fixnum count))
(the list (loop for x from 1 to count collecting (d6))))
只是:
(defmethod d6s ((n integer))
"Returns a list of n dice rolls."
(loop repeat n collect (d6)))
不要忘记用人类可读的形式描述你的函数的语义。