taruss
3/11/2016 8:00:00 PM
On Friday, March 11, 2016 at 7:22:26 AM UTC-8, Toh Zikai wrote:
> Hi I am new to lisp. So I have a function like this
>
> (defun find-closest-in-grid (radar type pos-x pos-y)
> (labels ((distance (x y)
> (+ (abs (- x pos-x))
> (abs (- y pos-y)))))
This distance measure also looks a bit odd. Did you mean to use Euclidean distance instead? In other words, do you want (5,0) to be closer than (3,3)?
> (destructuring-bind (width height)
> (array-dimensions radar)
> (let ((best nil)
> ((best-distance (+ width height))))
> (loop for x from 0 below width
> do (loop for y from 0 below height
> do (loop for element in (aref radar x y)
> do (when (eql (type-of element) type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
You almost certainly don't want to do this. TYPE-OF will return one valid type
of the object that is its element, but it may not be the one that you expect,
and it can be different between implementations.
For example, in SBCL (TYPE-OF 1) ==> BIT
That may surprise you.
A better choice would be the TYPEP predicate, which understands about type
hierarchies and will be a better test to use. TYPE-OF is mainly useful for
debugging purposes rather than type testing, because it is too fragile.
(TYPEP 1 'BIT) => T
(TYPEP 1 'INTEGER) => T
(TYPEP 1 'FLOAT) => NIL
Now, we don't know what types of objects you are storing in the list of items
in your (aref radar x y) and why, but oftentimes if you are doing your own
type dispatch in code, it may be a sign that you should instead be using the
CLOS object system's built-in type dispatch instead. That may or may not be
the case here, depending on exactly what you are trying to accomplish.
You might find it useful to take advantage of CLOS for some of what you are
doing, and define a class for RADAR and make things like find closest be
methods that dispatch on that class. But that would require knowing more
about what you are actually doing.
> (when (<= (distance x y) best-distance)
> (setf best (list x y))
> (setf best-distance (distance x y))))))))
> best)))
>
> But I wish to change the header to only have two parameters, (defun find-closest-in-grid (radar type) while keeping the rest of the code the same. How should I go about doing it? Thanks.