all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Problem with position and find (cl)
@ 2008-06-20 18:30 Marc Tfardy
  2008-06-20 19:58 ` Marc Tfardy
  2008-06-20 21:16 ` Thien-Thi Nguyen
  0 siblings, 2 replies; 12+ messages in thread
From: Marc Tfardy @ 2008-06-20 18:30 UTC (permalink / raw)
  To: help-gnu-emacs

I try with:
(member '(2) '((1) (2) (3) (4)))

and this gives a expectet results ((2) (3) (4)), but:
(find '(2) '((1) (2) (3) (4)))
or
(position '(2) '((1) (2) (3) (4)))

returns nil. Why?

regards

Marc


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-20 18:30 Problem with position and find (cl) Marc Tfardy
@ 2008-06-20 19:58 ` Marc Tfardy
  2008-06-20 20:14   ` Florian Beck
  2008-06-20 21:16 ` Thien-Thi Nguyen
  1 sibling, 1 reply; 12+ messages in thread
From: Marc Tfardy @ 2008-06-20 19:58 UTC (permalink / raw)
  To: help-gnu-emacs

Marc Tfardy schrieb:
> I try with:
> (member '(2) '((1) (2) (3) (4)))
> 
> and this gives a expectet results ((2) (3) (4)), but:
> (find '(2) '((1) (2) (3) (4)))
> or
> (position '(2) '((1) (2) (3) (4)))
> 
> returns nil. Why?

But this works:

(position '(2) '((1) (2) (3) (4)) :test (lambda (x y) (eq (car x) (car y))))

Maybe position and find (and maybe some others functions)
can not compare lists directly?

Marc




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-20 19:58 ` Marc Tfardy
@ 2008-06-20 20:14   ` Florian Beck
  2008-06-20 21:24     ` Thierry Volpiatto
       [not found]     ` <mailman.13619.1213996704.18990.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 12+ messages in thread
From: Florian Beck @ 2008-06-20 20:14 UTC (permalink / raw)
  To: help-gnu-emacs

Marc Tfardy <m-t-o___CUT__IT@web.de> writes:

> Marc Tfardy schrieb:
>> I try with:
>> (member '(2) '((1) (2) (3) (4)))

`member' tests the components: ›2‹ ist always equal (in the sense of »eq«) to ›2‹

Compare:

(memq '(2) '((1) (2) (3) (4)))
(eq 2 2)
(eq '(2) '(2))

>>
>> and this gives a expectet results ((2) (3) (4)), but:
>> (find '(2) '((1) (2) (3) (4)))
>> or
>> (position '(2) '((1) (2) (3) (4)))
>>
>> returns nil. Why?

Because  the first and the second »(2)« have the same components but are
*different* lists.

> But this works:
>
> (position '(2) '((1) (2) (3) (4)) :test (lambda (x y) (eq (car x) (car
> y))))
>
> Maybe position and find (and maybe some others functions)
> can not compare lists directly?

They can, but again, the elements are not identical. Compare:

(let* ((x '((1) (2) (3) (4)))
       (y (cadr x))
       (z '(2)))
    (message "x: %s; y:%s" (position y x) (position z x)))

y ist the same object as the cadr of x, z is an entirely new object that
happens to have the same component.


>
> Marc

-- 
Florian Beck


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-20 18:30 Problem with position and find (cl) Marc Tfardy
  2008-06-20 19:58 ` Marc Tfardy
@ 2008-06-20 21:16 ` Thien-Thi Nguyen
  1 sibling, 0 replies; 12+ messages in thread
From: Thien-Thi Nguyen @ 2008-06-20 21:16 UTC (permalink / raw)
  To: help-gnu-emacs

() Marc Tfardy <m-t-o___CUT__IT@web.de>
() Fri, 20 Jun 2008 20:30:58 +0200

   Why?

All people are animals but not all animals are people.

(info "(cl) Sequence Basics")   ;; paragraph explaining :key
(find 2 '((1) (2) (3) (4)) :key 'car)

All animals are equal but some animals are more equal than others.

(info "(cl) Sequence Basics")   ;; paragraph explaining :test
(find '(2) '((1) (2) (3) (4)) :test 'equal)

thi




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-20 20:14   ` Florian Beck
@ 2008-06-20 21:24     ` Thierry Volpiatto
       [not found]     ` <mailman.13619.1213996704.18990.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 12+ messages in thread
From: Thierry Volpiatto @ 2008-06-20 21:24 UTC (permalink / raw)
  To: Florian Beck; +Cc: help-gnu-emacs

Florian Beck <abstraktion@t-online.de> writes:

> Marc Tfardy <m-t-o___CUT__IT@web.de> writes:
>
>> Marc Tfardy schrieb:
>>> I try with:
>>> (member '(2) '((1) (2) (3) (4)))
>
> `member' tests the components: ›2‹ ist always equal (in the sense of »eq«) to ›2‹
>
> Compare:
>
> (memq '(2) '((1) (2) (3) (4)))
> (eq 2 2)
> (eq '(2) '(2))
>
>>>
>>> and this gives a expectet results ((2) (3) (4)), but:
>>> (find '(2) '((1) (2) (3) (4)))
>>> or
>>> (position '(2) '((1) (2) (3) (4)))
>>>
>>> returns nil. Why?
>
> Because  the first and the second »(2)« have the same components but are
> *different* lists.
>
>> But this works:
>>
>> (position '(2) '((1) (2) (3) (4)) :test (lambda (x y) (eq (car x) (car
>> y))))
>>
>> Maybe position and find (and maybe some others functions)
>> can not compare lists directly?
>
> They can, but again, the elements are not identical. Compare:
>
> (let* ((x '((1) (2) (3) (4)))
>        (y (cadr x))
>        (z '(2)))
>     (message "x: %s; y:%s" (position y x) (position z x)))
>
> y ist the same object as the cadr of x, z is an entirely new object that
> happens to have the same component.
>
>
position default test is 'eq, try 'equal

,----
| ELISP> (let* ((x '((1) (2) (3) (4)))
|        (y (cadr x))
|        (z '(2)))
|     (message "x: %s; y:%s" (position y x) (position z x :test 'equal)))
| "x: 1; y:1"
`----


-- 
A + Thierry
Pub key: http://pgp.mit.edu




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
       [not found]     ` <mailman.13619.1213996704.18990.help-gnu-emacs@gnu.org>
@ 2008-06-20 23:14       ` Florian Beck
  2008-06-21  2:04         ` Barry Margolin
  2008-06-21  4:57         ` Thierry Volpiatto
  2008-06-21 10:07       ` Marc Tfardy
  1 sibling, 2 replies; 12+ messages in thread
From: Florian Beck @ 2008-06-20 23:14 UTC (permalink / raw)
  To: help-gnu-emacs

Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:


> position default test is 'eq, try 'equal

Indeed, many cl-tests default to 'eq.

BTW, what is the reason for this (apart from being a language convention)?

When I try

(let ((start-time (current-time)))
  (dotimes (i 1000000)
    (position '(1) '((2) (5) (2) 2 x  4 fer fer f r e wqf (1) fr r) :test 'eq))
  (format-time-string "%S" (time-since start-time)))

with 'eq and 'equal I get the same result. So 'eq is not more efficent,
is it?


-- 
Florian Beck


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-20 23:14       ` Florian Beck
@ 2008-06-21  2:04         ` Barry Margolin
  2008-06-21  4:31           ` Florian Beck
  2008-06-21  4:57         ` Thierry Volpiatto
  1 sibling, 1 reply; 12+ messages in thread
From: Barry Margolin @ 2008-06-21  2:04 UTC (permalink / raw)
  To: help-gnu-emacs

In article <87abhfg0mn.fsf@sophokles.streitblatt.de>,
 Florian Beck <abstraktion@t-online.de> wrote:

> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
> 
> 
> > position default test is 'eq, try 'equal
> 
> Indeed, many cl-tests default to 'eq.
> 
> BTW, what is the reason for this (apart from being a language convention)?

Just because things look similar doesn't mean they're the same.  Imagine 
if you use a list like (firstname lastname) to represent people, and you 
have two John Smiths in the group.

> 
> When I try
> 
> (let ((start-time (current-time)))
>   (dotimes (i 1000000)
>     (position '(1) '((2) (5) (2) 2 x  4 fer fer f r e wqf (1) fr r) :test 
>     'eq))
>   (format-time-string "%S" (time-since start-time)))
> 
> with 'eq and 'equal I get the same result. So 'eq is not more efficent,
> is it?

For a single-element list the difference is almost negligible.  Try 
again with long lists, like 50 or 100 elements long.

-- 
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-21  2:04         ` Barry Margolin
@ 2008-06-21  4:31           ` Florian Beck
  0 siblings, 0 replies; 12+ messages in thread
From: Florian Beck @ 2008-06-21  4:31 UTC (permalink / raw)
  To: help-gnu-emacs

Barry Margolin <barmar@alum.mit.edu> writes:

> In article <87abhfg0mn.fsf@sophokles.streitblatt.de>,
>  Florian Beck <abstraktion@t-online.de> wrote:
>
>> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
>> 
>> 
>> > position default test is 'eq, try 'equal
>> 
>> Indeed, many cl-tests default to 'eq.
>> 
>> BTW, what is the reason for this (apart from being a language convention)?
>
> Just because things look similar doesn't mean they're the same.  Imagine 
> if you use a list like (firstname lastname) to represent people, and you 
> have two John Smiths in the group.

Yes, that was what I was trying to explain.

>> 
>> When I try
>> 
>> (let ((start-time (current-time)))
>>   (dotimes (i 1000000)
>>     (position '(1) '((2) (5) (2) 2 x  4 fer fer f r e wqf (1) fr r) :test 
>>     'eq))
>>   (format-time-string "%S" (time-since start-time)))
>> 
>> with 'eq and 'equal I get the same result. So 'eq is not more efficent,
>> is it?
>
> For a single-element list the difference is almost negligible.  Try 
> again with long lists, like 50 or 100 elements long.

I doesn't scale, but not that quickly:

(let ((start-time (current-time))
      (test-list (append (make-list 10000 'x) '((1)))))
  (dotimes (i 1000)
    (position '(1) test-list :test  'equal))
  (format"%.3f" (- (time-to-seconds  (current-time)) (time-to-seconds start-time) )))
      

(let ((start-time (current-time))
      (test-list (append (make-list 10000 'x) '((1)))))
  (dotimes (i 1000)
    (position '(1) test-list :test  'eq))
  (format "%.3f" (- (time-to-seconds  (current-time)) (time-to-seconds start-time) )))

This still takes more or less the same amount of time. (In my case 7.782s
and 7.689s.)

-- 
Florian Beck


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-20 23:14       ` Florian Beck
  2008-06-21  2:04         ` Barry Margolin
@ 2008-06-21  4:57         ` Thierry Volpiatto
  1 sibling, 0 replies; 12+ messages in thread
From: Thierry Volpiatto @ 2008-06-21  4:57 UTC (permalink / raw)
  To: Florian Beck; +Cc: help-gnu-emacs

Florian Beck <abstraktion@t-online.de> writes:

> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
>
>
>> position default test is 'eq, try 'equal
>
> Indeed, many cl-tests default to 'eq.
>
> BTW, what is the reason for this (apart from being a language convention)?
>
> When I try
>
> (let ((start-time (current-time)))
>   (dotimes (i 1000000)
>     (position '(1) '((2) (5) (2) 2 x  4 fer fer f r e wqf (1) fr r) :test 'eq))
>   (format-time-string "%S" (time-since start-time)))
>
> with 'eq and 'equal I get the same result. So 'eq is not more efficent,
> is it?
eq compare two objects and say if they are the same.
equal compare two objects and say if the value of these object is the
same.

,----
| ELISP> (setq A '(1 2))
| (1 2)
| 
| ELISP> (setq B '(1 2))
| (1 2)
| 
| ELISP> (eq A B)
| nil
| ELISP> (equal A B)
| t
`----

-- 
A + Thierry
Pub key: http://pgp.mit.edu




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
       [not found]     ` <mailman.13619.1213996704.18990.help-gnu-emacs@gnu.org>
  2008-06-20 23:14       ` Florian Beck
@ 2008-06-21 10:07       ` Marc Tfardy
  2008-06-21 10:38         ` Marc Tfardy
  1 sibling, 1 reply; 12+ messages in thread
From: Marc Tfardy @ 2008-06-21 10:07 UTC (permalink / raw)
  To: help-gnu-emacs

Thierry Volpiatto schrieb:
> Florian Beck <abstraktion@t-online.de> writes:
> 
>> Marc Tfardy <m-t-o___CUT__IT@web.de> writes:
>>
>>> Marc Tfardy schrieb:
>>>> I try with:
>>>> (member '(2) '((1) (2) (3) (4)))
>> `member' tests the components: ›2‹ ist always equal (in the sense of »eq«) to ›2‹
>>
>> Compare:
>>
>> (memq '(2) '((1) (2) (3) (4)))
>> (eq 2 2)
>> (eq '(2) '(2))
>>
>>>> and this gives a expectet results ((2) (3) (4)), but:
>>>> (find '(2) '((1) (2) (3) (4)))
>>>> or
>>>> (position '(2) '((1) (2) (3) (4)))
>>>>
>>>> returns nil. Why?
>> Because  the first and the second »(2)« have the same components but are
>> *different* lists.
>>
>>> But this works:
>>>
>>> (position '(2) '((1) (2) (3) (4)) :test (lambda (x y) (eq (car x) (car
>>> y))))
>>>

> position default test is 'eq, try 'equal

Thanks! It works with equal. But I have another problem.
find (and find-if) returns only first match. Is there another
function that returns all matched elements. Some example:

(find-if-all (lambda (x) (if (eq (nth 2 x) 'byte) t nil)) '((1.1 "x" 
int) (2.2 "y" byte) (3.3 "q" int) (4.4 "b" byte) (5.5 "a" float)))

should returns:
((2.2 "y" byte) (4.4 "b" byte))

I found in cl-*.el nothing like this. Any hints?

regards
Marc




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-21 10:07       ` Marc Tfardy
@ 2008-06-21 10:38         ` Marc Tfardy
  2008-06-21 12:38           ` Thierry Volpiatto
  0 siblings, 1 reply; 12+ messages in thread
From: Marc Tfardy @ 2008-06-21 10:38 UTC (permalink / raw)
  To: help-gnu-emacs

Marc Tfardy schrieb:
> Thierry Volpiatto schrieb:
>> Florian Beck <abstraktion@t-online.de> writes:
>>
>>> Marc Tfardy <m-t-o___CUT__IT@web.de> writes:
>>>
>>>> Marc Tfardy schrieb:
>>>>> I try with:
>>>>> (member '(2) '((1) (2) (3) (4)))
>>> `member' tests the components: ›2‹ ist always equal (in the sense of 
>>> »eq«) to ›2‹
>>>
>>> Compare:
>>>
>>> (memq '(2) '((1) (2) (3) (4)))
>>> (eq 2 2)
>>> (eq '(2) '(2))
>>>
>>>>> and this gives a expectet results ((2) (3) (4)), but:
>>>>> (find '(2) '((1) (2) (3) (4)))
>>>>> or
>>>>> (position '(2) '((1) (2) (3) (4)))
>>>>>
>>>>> returns nil. Why?
>>> Because  the first and the second »(2)« have the same components but are
>>> *different* lists.
>>>
>>>> But this works:
>>>>
>>>> (position '(2) '((1) (2) (3) (4)) :test (lambda (x y) (eq (car x) (car
>>>> y))))
>>>>
> 
>> position default test is 'eq, try 'equal
> 
> Thanks! It works with equal. But I have another problem.
> find (and find-if) returns only first match. Is there another
> function that returns all matched elements. Some example:
> 
> (find-if-all (lambda (x) (if (eq (nth 2 x) 'byte) t nil)) '((1.1 "x" 
> int) (2.2 "y" byte) (3.3 "q" int) (4.4 "b" byte) (5.5 "a" float)))
> 
> should returns:
> ((2.2 "y" byte) (4.4 "b" byte))
> 
> I found in cl-*.el nothing like this. Any hints?


I found some "strange" solution:

(remove-if-not (lambda (x) (if (eq (nth 2 x) 'byte) t nil)) '((1.1 "x" 
int) (2.2 "y" byte) (3.3 "q" int) (4.4 "b" byte) (5.5 "a" float)))

but with:
(fset 'find-all 'remove-if-not)
or:
(defalias 'find-all 'remove-if-not)

(a propos - what is the right method?) - it looks good and
works like expected.

Marc




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Problem with position and find (cl)
  2008-06-21 10:38         ` Marc Tfardy
@ 2008-06-21 12:38           ` Thierry Volpiatto
  0 siblings, 0 replies; 12+ messages in thread
From: Thierry Volpiatto @ 2008-06-21 12:38 UTC (permalink / raw)
  To: Marc Tfardy; +Cc: help-gnu-emacs

Marc Tfardy <m-t-o___CUT__IT@web.de> writes:

> Marc Tfardy schrieb:
>> Thierry Volpiatto schrieb:
>>> Florian Beck <abstraktion@t-online.de> writes:
>>>
>>>> Marc Tfardy <m-t-o___CUT__IT@web.de> writes:
>>>>
>>>>> Marc Tfardy schrieb:
>>>>>> I try with:
>>>>>> (member '(2) '((1) (2) (3) (4)))
>>>> `member' tests the components: ›2‹ ist always equal (in the sense
>>>> of »eq«) to ›2‹
>>>>
>>>> Compare:
>>>>
>>>> (memq '(2) '((1) (2) (3) (4)))
>>>> (eq 2 2)
>>>> (eq '(2) '(2))
>>>>
>>>>>> and this gives a expectet results ((2) (3) (4)), but:
>>>>>> (find '(2) '((1) (2) (3) (4)))
>>>>>> or
>>>>>> (position '(2) '((1) (2) (3) (4)))
>>>>>>
>>>>>> returns nil. Why?
>>>> Because  the first and the second »(2)« have the same components but are
>>>> *different* lists.
>>>>
>>>>> But this works:
>>>>>
>>>>> (position '(2) '((1) (2) (3) (4)) :test (lambda (x y) (eq (car x) (car
>>>>> y))))
>>>>>
>>
>>> position default test is 'eq, try 'equal
>>
>> Thanks! It works with equal. But I have another problem.
>> find (and find-if) returns only first match. Is there another
>> function that returns all matched elements. Some example:
>>
>> (find-if-all (lambda (x) (if (eq (nth 2 x) 'byte) t nil)) '((1.1 "x"
>> int) (2.2 "y" byte) (3.3 "q" int) (4.4 "b" byte) (5.5 "a" float)))
>>
>> should returns:
>> ((2.2 "y" byte) (4.4 "b" byte))
>>
>> I found in cl-*.el nothing like this. Any hints?
>
>
> I found some "strange" solution:
>
> (remove-if-not (lambda (x) (if (eq (nth 2 x) 'byte) t nil)) '((1.1 "x"
> int) (2.2 "y" byte) (3.3 "q" int) (4.4 "b" byte) (5.5 "a" float)))
>
> but with:
> (fset 'find-all 'remove-if-not)
> or:
> (defalias 'find-all 'remove-if-not)
>
> (a propos - what is the right method?) - it looks good and
> works like expected.
Is it something like that you are looking for ?
,----
| ELISP> (setq A '((2 "a" byte)
|                  (3.2 "b" float)
|                  (4 "c" byte)
|                  (6 "d" int)
|                  (8 "e" byte)))
| ((2 "a" byte)
|  (3.2 "b" float)
|  (4 "c" byte)
|  (6 "d" int)
|  (8 "e" byte))
| 
| ELISP> (defun find-all (item lis)
|          (let ((temp-list nil))
|            (dolist (x lis)
|              (when (equal (nth 2 x) item)
|                (push x temp-list)))
|            temp-list))
| find-all
| ELISP> (find-all 'byte A)
| ((8 "e" byte)
|  (4 "c" byte)
|  (2 "a" byte))
`----


-- 
A + Thierry
Pub key: http://pgp.mit.edu




^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2008-06-21 12:38 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-20 18:30 Problem with position and find (cl) Marc Tfardy
2008-06-20 19:58 ` Marc Tfardy
2008-06-20 20:14   ` Florian Beck
2008-06-20 21:24     ` Thierry Volpiatto
     [not found]     ` <mailman.13619.1213996704.18990.help-gnu-emacs@gnu.org>
2008-06-20 23:14       ` Florian Beck
2008-06-21  2:04         ` Barry Margolin
2008-06-21  4:31           ` Florian Beck
2008-06-21  4:57         ` Thierry Volpiatto
2008-06-21 10:07       ` Marc Tfardy
2008-06-21 10:38         ` Marc Tfardy
2008-06-21 12:38           ` Thierry Volpiatto
2008-06-20 21:16 ` Thien-Thi Nguyen

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.