1

Here' a function I have.

(defun add-word-2 (n line)
    (let ((temp-word (make-array 0 :element-type 'character
                 :fill-pointer 0
                 :adjustable t)))
      (vector-push-extend (char line n) temp-word)
      (loop 

        (if (or (char= #\newline (char line (+ n 1)))
                (char= #\space (char line (+ n 1))))
            ((vector-push-extend temp-word *word-array-2*)(return-from add-word-2 n)) 
            ((incf n)(vector-push-extend (char line n) temp-word))))))

I believe it's getting down to the bottom inside the if function after an evaluation to false. The error I get is:

Error: Illegal function object: (INCF N).
[condition type: TYPE-ERROR]

Is this a scope issue, does the n still exist inside the let function? Not really sure what that error means.

2 Answers 2

3

You get the error because the first position in a list that gets evaluated is expected to be a function name. For example in your else branch:

((incf n) (vector-push-extend (char line n) temp-word))

(incf n) should be a function name for this to be legal, but it obviously isn't. If you want to put a sequence of expressions where only a single one is allowed, the usual solution is progn. So your else branch would become:

(progn
  (incf n)
  (vector-push-extend (char line n) temp-word))

Though in this case, you could make use of the fact that (incf n) returns the new value of n, so you could also just write:

(vector-push-extend (char line (incf n)) temp-word)

The then branch should need a progn, too.

EDIT: alternative implementation of the whole function

After I wrote my answer above, I read your explanation in a comment what the function is supposed to do. How about implementing that like this?

(defun add-word-3 (start line)
  (let ((end (position-if (lambda (char) (member char '(#\Newline #\Space)))
                          line
                          :start start)))
    (vector-push-extend (subseq line start end) *word-array-2*)
    end))
Sign up to request clarification or add additional context in comments.

2 Comments

That bottom function is beyond me, currently. I would have to learn more before understanding it. This is for a class and I don't want to copy anyone's work :).
OK, that's great that you don't want to just copy your homework! A little explanation to help you understand nonetheless: the idea of the function at the end of my answer is to not copy the characters one by one, but instead find the position of the next space or newline (with position-if), and then take the whole substring at once (with subseq).
1
  1. In Lisp, each set of brackets is significant. You cannot add extra brackets willy-nilly. In particular, if you see double opening brackets outside of a let form's variable bindings, you are probably doing something wrong.
  2. In the first branch of your if, you probably need to use progn.
  3. In the second branch of your if, the (+ n 1) is in the wrong place. Instead, change the (char line n) to (char line (+ n 1)).

Thus:

(if (or ...)
    (progn
     (vector-push-extend temp-word *word-array-2*)
     (return-from add-word-2 n))
    (vector-push-extend (char line (+ n 1)) temp-word))

Having said this, I have no idea what your function is trying to do, so the above is just a best guess. ;-)

3 Comments

I actually meant (incf n), where (+ n 1) is. I changed it up top. I get the same error, though.
the function is pulling words out of line (a string) one character at a time and adding them to the word-array-2 array. The line might contain more than one word, so I return the index of the line once a space or newline is reached. I don't want to read the whole line because I'm pulling others strings out of the line based on other criteria.
Okay, re incf. Then you have to use progn there too. (If you want to use more than one expression in if, you have to use progn.) I haven't read your second explanation yet, I'll get back to it. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.