Mark Green
Mark Green

Reputation: 1330

LispWorks program will not build as application

This is my second proper attempt at a Lisp program, as a dice-roller for Mythender (a freely distributed tabletop RPG). It has a couple of problems though:

Any general suggestions would also be welcome.

(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)))

Upvotes: 0

Views: 165

Answers (1)

Rainer Joswig
Rainer Joswig

Reputation: 139311

An answer to your build problem has to wait until you tell us the build statement and the error message.

Your last question:

(declare (ftype (function) printstate))
(defun printstate ()
  (print *storm*)
  (print *thunder*)
  (print *lightning*)
  (the null ()))

It's known that it is a function. No need to declare that. Declaring types like that, have in plain Common Lisp only the purpose of optimization hints to the compiler, which the compiler may ignore. Only CMUCL (and derived compilers like SBCL and SCL) actually does more with declared types.

Nobody writes such code in Lisp. Better omit the types. Remember: Lisp is not a statically typed language.

(defun printstate ()
  (print *storm*)
  (print *thunder*)
  (print *lightning*)
  (values))

Using (values) causes the function to not return a value. That's usually preferred, not returning NIL.

If you want to actually check types in a meaningful way at runtime, then make use of ASSERT, CHECK-TYPE and/or DEFMETHOD.

(defun d6s (count)
  (declare (type fixnum count))
  (the list (loop for x from 1 to count collecting (d6))))

Is just:

(defmethod d6s ((n integer))
  "Returns a list of n dice rolls."
  (loop repeat n collect (d6)))

Don't forget to describe the semantics of your function in human readable form.

Upvotes: 3

Related Questions