[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Changing a lisp function from a 4 parameter function to a 2 parameter function (VACUUM AGENT

Toh Zikai

3/11/2016 3:22:00 PM

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)))))
(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)
(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.
4 Answers

Kaz Kylheku

3/11/2016 3:34:00 PM

0

On 2016-03-11, Toh Zikai <tohzkai@gmail.com> 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)
[...]
> 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.

Since if the code is the same, it continues to refer to pos-x and pos-y
variables. So I'm guessing you don't just want to remove them, but
rather give them default values, and let the function be called
as if it had only two arguments?

(defun find-closest-in-grid (radar type &optional (pos-x 0) (pos-x y))
...)

taruss

3/11/2016 8:00:00 PM

0

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.

Kaz Kylheku

3/12/2016 2:02:00 AM

0

On 2016-03-11, taruss@google.com <taruss@google.com> wrote:
> 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)?

There is also Platonic allegorical distance: cast shadows on the side of
a cave by the light of a fire, and measure the distance among them
rather than the real objects.

rpw3

3/12/2016 7:35:00 AM

0

<taruss@google.com> wrote:
+---------------
| 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)?
+---------------

Maybe he (or the original author of the code?) is using
Manhattan distance instead of Euclidean because it's a bit
cheaper to compute? ...and the exact metric used is perceived
to not matter too much in the appplication in question?
I mean, the function name *is* "find-closest-IN GRID"... ;-}


-Rob

-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <http://rpw...
San Mateo, CA 94403