From: Axel Schairer
Subject: Re: position-if trouble
Date: 
Message-ID: <fm9g12ni5pj.fsf@clair.dai.ed.ac.uk>
·····@sip.medizin.uni-ulm.de (kp gores) writes:
> i have a problem with position-if's :key

It seems to me that the problem is not specific to POSITION-IF or :KEY
but is a problem of calling an accessor on objects of an inappropriate
type.  I don't know what you're really up to, but I assume that you're
in an environment in which exactly one of PATTERN{PPML|SEMANTICS|...}
is non-NIL, call that one's value X) and you want to find the position
of the element in the list PMLLIST which has X at some place inside
the element, where the exact place for each element depends on the
type of that element.  Is this OK so far?

So what you want to do is call POSITION-IF with a predicate that
compares X to the `correct' place in each element of PMLLIST.  It
seems that you expect elements of different types in any one list (you
say LIST or VECTOR or some structure type).

However, consider the case in which PATTERNSYNTAX is non-NIL: in this
case you give POSITION-IF the :KEY function #'DICTENTRY-SYNTAX which
is then funcalled on every element in your list until POSITION-IF
finds the element you are looking for.  If your first element is a
list and the second is the one you are looking for this causes
#'DICTENTRY-SYNTAX to be funcalled on the list.  I suppose that this
is your problem.

Hope, this helps.

Cheers, Axel


> what i do is define the predicate working on my pmllist as follows:
> 
> 
>  (position-if
>            (cond                        ; define the test to perform on pmllist
>              (patternppml               ; checking for pppml
>               #'(lambda (x) (eql patternppml x)))
>              (patternsemantics          ; checking for syntax
>               #'(lambda (x) (eql patternsemantics x)))
>              (patternsyntax             ; checking for syntax
>               #'(lambda (x) (eql patternsyntax x)))
>              (patternword               ; checking for word
>               #'(lambda (x) (string-equal patternword x)))
>              )                          ; (T
> nil))                          ; test for slots of struct
>            pmllist
> 
> 
> which is working as expected.
> now i want to define the function to access my elements. again i want to
> do a cond, but this time on the element position-if currently is looking
> at.
> the element can be a structure, array or list. i thought something like
> the following could work, which it doesnt:
> 
>            :key                         ; define the accessor
>            (cond
>              (patternppml               ; checking for pppml
>               #'(lambda (x)
>                   (typecase x           ; check the pmlinfo of element at curpos
>                     (vector (pmlinfo-ppml (aref x 0)))
>                     (list (pmlinfo-ppml (first x))) ; if its a list, look inside
>                     (attributedword (attributedword-ppml x)
>                                     (pmlinfo (pmlinfo-ppml x))))))
> 
>               
>                                         ;       #'pmlinfo-ppml)
>              (patternsemantics          ; checking for syntax
>               #'dictentry-semantics)
>              (patternsyntax             ; checking for syntax
>               #'dictentry-syntax)
>              (patternword               ; checking for word
>               #'attributedword-word)
>              )                          ;   (T "pattern has no ppml,
> syntax,word or semantics!")) ; test for slots of struct
>            :from-end (minusp deltapos)
>            :start minpos
>            :end maxpos
>            ))
> 
> 
> is there a way to do this right, and if so, how?
> i played around with but didnT find a solution.
> 
> any help appreciated
> 
> regards
>   kp