-3

I am very new to LISP and was having some trouble using a manipulating arrays. There aren't many resources on it since it seems Lists are more widely used. I have the following code where I am attempting to look through an array and return the spot that the minimum value occurs (I don't know if my formatting is correct):

(defun FIND-MIN(x) 
(setq ctr (aref x 0)) (setq pos 1) (setq finalpos 1)  
(loop while (< pos (array-total-size x)) 
    do 
    (
        (if (< ctr (aref Z pos))
            (progn
                (setq ctr pos)
                (setq finalpos pos))
    (incf pos) 
    )
) 
    finalpos
)

My reasoning behind this is to first create some variables, ctr which is set to the first position by default and tracks the minimum value, a position counter (pos) to keep track of where I am in the array, and a finalpos variable to store where the minimum value occurs. Then I will loop until pos gets to the end of the array. At every step it checks if the element is smaller than ctr and if it is ctr is updated and finalpos is updated. pos is then incremented to continue the array. After each element is checked the program will return finalpos, which should be the location of the smallest element.

The error that I get from this is:

- SYSTEM::%EXPAND-FORM: (SETQ CTR (AREF X 0)) should be a lambda expression

I didn't think I needed a lambda expression since aref is just grabbing a single value (the first one) and pulling a single value is aref's job. Also please point out if my logic is flawed because this new language is very different to any that I have used before. Any and all help is greatly appreciated!

  • Also, typical style does not leave trailing parenthesis on their own lines. But this would not cause a syntax error as you saw. – verdammelt Sep 14 '16 at 02:00
  • You're trying to apply `(setq ctr (aref x 0))` as a function to the arguments `(setq pos 1)`, `(setq finalpos 1)`, `(loop ...)`, and `finalpos`. You should probably review the Lisp syntax in a nearby book. (I recommend [Practical Common Lisp](http://www.gigamonkeys.com/book/).) – molbdnilo Sep 14 '16 at 02:09
  • @molbdnilo I removed the extra parenthesis at the front and back of the program as I realized the extra wrapping that I was doing. I edited my original post. Is that the error that you were describing? That did serve to fix the error at that specific spot but a new error showed up asking for a lambda like before: SYSTEM::%EXPAND-FORM: (IF (< CTR (AREF Z POS)) (SETQ CTR POS) (SETQ FINALPOS POS)) should be a lambda expression. – Tim Strayer Sep 14 '16 at 02:31
  • @TimStrayer You're applying `(if (< ctr (aref Z pos)) (setq ctr pos)(setq finalpos pos))` to `(setq pos pos+1) `; you need a sequencing `progn` in the `do`. Your next problem will probably be that Lisp doesn't have infix operators, and that the variable `pos+1` isn't defined. But there are good free books online, like the one I mentioned. – molbdnilo Sep 14 '16 at 02:54
  • @molbdnilo Made the changes that you suggested. progn now follows my if statement and the increment to pos is now (incf pos). I edited my original post so the changes can be seen there. Still get the same error of: **SYSTEM::%EXPAND-FORM: (IF (< CTR (AREF Z POS)) (PRONG (SETQ CTR POS) (SETQ FINALPOS POS)) (INCF POS)) should be a lambda expression** and I am unsure of how to fix such an error – Tim Strayer Sep 14 '16 at 03:08
  • You have a `do ((if ...))`. Here the standard evaluation rules apply but the inner `(if ...)` is not a valid expression to have in this place. `(X)` is valid if `X` is a symbol which denotes a function (a global or a flet/labels), or if `X` is a literal lambda form. Besides, you are using `SETQ` all over the place instead of using `LET` bindings. Your function modifies global variables, which makes your code not reentrant (and those variables are undeclared, so your is not even guaranteed to work according to the language specification). Regarding min: `(lambda (s) (reduce #'min s))`. – coredump Sep 14 '16 at 05:44
  • You don't bind variables with `setq`: you create bindings with `let` or a related form. Unfortunately Python and its ilk have almost destroyed people's understanding about this. –  Sep 14 '16 at 13:19

1 Answers1

0

You have a syntax error in your defun form. Specifically you've wrapped the body of the defun in a set of parenthesis. This is incorrect. The form of a defun is:

(defun NAME (ARGS) [DOCUMENTATION] BODY)

(CLHS reference).

The body will be a series of forms; you've wrapped that series of forms in parenthesis which is confusing the compiler/interpreter.

(I won't comment upon style until we have syntactically correct code.)

verdammelt
  • 922
  • 10
  • 22
  • I removed the extra parenthesis at the front and back of the program as I realized the extra wrapping that I was doing. I edited my original post. Is that the error that you were describing? That did serve to fix the error at that specific spot but a new error showed up asking for a lambda like before: SYSTEM::%EXPAND-FORM: (IF (< CTR (AREF Z POS)) (SETQ CTR POS) (SETQ FINALPOS POS)) should be a lambda expression. Hopefully this will be as easy to solve as the extra wrapping parenthesis were – Tim Strayer Sep 14 '16 at 02:30
  • Same problem; but now in the `do` clause of `loop`. – verdammelt Sep 14 '16 at 12:37