amindfv
amindfv

Reputation: 8448

Equality of strings in vectors

I've defined a function in elisp to find the index of a list in a vector:

(defun vposition (e v)  
   (letrec  
      ((f (lambda (e v i)  
             (if (equal e (elt v i))  
                 i  
                 (f e v (+ i 1))))))  
      (f e v 0)))  

If I use it on numbers it's fine, but with strings, e.g. (vposition "bar" ["foo" "bar" "thing"]), I get an error:

Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p "bar")
  =("bar" "foo")

If I do, say, (vposition 3 [1 2 3]), it works as expected, and (equal "bar" "foo") works, too, so I can't isolate where the problem is. What am I missing?

Upvotes: 0

Views: 80

Answers (2)

Stefan
Stefan

Reputation: 28541

Your problem is that your calls to f don't call the function held in the local variable f, but some other function f which you presumably defined earlier by accident (and that function uses = instead of equal). When I try your code and example I get a different error:

Symbol's function definition is void: f

You can fix your code easily with:

(defun vposition (e v)  
  (letrec  
      ((f (lambda (e v i)  
            (if (equal e (elt v i))  
                i  
              (funcall f e v (+ i 1))))))
    (funcall f e v 0)))

Of course, recursion like that tends to work inefficiently in Elisp because the Elisp implementation is too naive, so you may want to use a while loop instead.

Upvotes: 2

abo-abo
abo-abo

Reputation: 20342

This one works:

(defun vposition (e v)
  (cl-labels ((f (e v i)
                (if (equal e (elt v i))
                    i
                  (f e v (+ i 1)))))
    (f e v 0)))

Upvotes: 0

Related Questions