quickly finding a cons cell

J

Jimka

Guest
Is there a clever way in SKILL to do somthing which sort of mixes
the functionality of (foreach map....) with exists?

I want the test applied to the cons cell, not to the car of the cons
cell.

As (foreach .... ) is to (exists ...)
(foreach map ...) is to what?

The exists function does not take an optional mapping function similar
to foreach, but IF IT DID this is what i'd like to do.

(exists map sub '(1 2 3 4 5 6 7) ((cadr map) > 3))
---> (3 4 5 6 7)

What's the most efficient/fastest way to do this?

-jim
 
On 16 Apr 2006 03:27:57 -0700, "Jimka" <jimka@rdrop.com> wrote:

Is there a clever way in SKILL to do somthing which sort of mixes
the functionality of (foreach map....) with exists?

I want the test applied to the cons cell, not to the car of the cons
cell.

As (foreach .... ) is to (exists ...)
(foreach map ...) is to what?

The exists function does not take an optional mapping function similar
to foreach, but IF IT DID this is what i'd like to do.

(exists map sub '(1 2 3 4 5 6 7) ((cadr map) > 3))
---> (3 4 5 6 7)

What's the most efficient/fastest way to do this?

-jim
Probably:

(prog ()
(foreach map sub '(1 2 3 4 5 6 7)
(when (greaterp (cadr map) 3) (return sub))
)
)

I expect you can convert that into a macro yourself ;-> but here it is anyway:


(defmacro abExistsExtend (mapFunc var lst @rest body)
`(prog ()
(foreach ,mapFunc ,var ,lst
(when
,(if (cdr body) `(progn ,@body) (car body))
(return ,var)
)
)
)

e.g.

(abExistsExtend map sub '(1 2 3 4 5 6 7) ((cadr sub)>3))

Regards,

Andrew.
 
On Tue, 18 Apr 2006 09:28:19 +0100, Andrew Beckett
<andrewb@DcEaLdEeTnEcTe.HcIoSm> wrote:
I expect you can convert that into a macro yourself ;-> but here it is anyway:


(defmacro abExistsExtend (mapFunc var lst @rest body)
`(prog ()
(foreach ,mapFunc ,var ,lst
(when
,(if (cdr body) `(progn ,@body) (car body))
(return ,var)
)
)
)
I also just found this example that I wrote in 1999 - Jim, I suspect it was you
that asked me this then, because I can't imagine anyone else asking it!

/* exists_map.il

Author A.D.Beckett
Group Custom IC (UK), Cadence Design Systems Ltd.
Language SKILL
Date Nov 02, 1999
Modified
By

A version of exists, which assigns the loop variable
to the cdr of the list each time (like map).

***************************************************

SCCS Info: @(#) exists_map.il 11/02/99.22:35:08 1.3

*/

(defmacro exists_map (loop lst expr)
`(let ((,loop ,lst))
(while (and ,loop (null ,expr))
(setq ,loop (cdr ,loop))
)
,loop
)
)


(defmacro exists_map2 (loop lst expr)
`(prog ()
(map (lambda (,loop) (when ,expr return(,loop))) ,lst)
)
)

/* this one doesn't work...
(defmacro exists_map4 (loop lst expr)
`(let (_ret)
(map (lambda (,loop)
(when ,expr
(setq _ret (cons (car ,loop) (cdr ,loop)))
(rplacd ,loop nil)
))
,lst)
_ret
)
)

*/

; when seems slightly faster in the loop - and and outside is faster!
; this version throws an error when it's done, which is caught for
; the return value
(defmacro exists_map3 (loop lst expr)
`(car (errset
(and (map (lambda (,loop) (when ,expr (err ,loop))) ,lst) nil)))
)

(defun test_map ()
(let (data)
(for i 1 3000 (setq data (cons i data)))
(profile 'time)
;(for i 1 1000 (exists_map3 x data car(x)<30))
(for i 1 4000 (exists_map2 x data nil))
(profileSummary)
(profileReset)
)
)

; 3000 list, 4000 times, nil condition
; exists_map3 23.43
; exists 6.08
; exists_map 45.37
; exists_map2 23.39



So looks like I did a fair bit of profiling at the time.

Andrew.
Andrew Beckett
Principal European Technology Leader
Cadence Design Systems, UK.
 
yes these are good solutions but the use of prog/return
is not supported in scheme mode unfortunately... not sure
why not but it is documented so.

otherwise the other solutions seem to require that the entire
list be traversed... or am i misreading it?
 
can the prog/return be replaced with some sort of goto? i know that
go is supported in SKILL but i've never used it? Perhaps the macro
could generate a label/go pair using gensym????
 
On 23 Apr 2006 06:26:28 -0700, "Jimka" <jimka@rdrop.com> wrote:

yes these are good solutions but the use of prog/return
is not supported in scheme mode unfortunately... not sure
why not but it is documented so.

otherwise the other solutions seem to require that the entire
list be traversed... or am i misreading it?
Hi Jim,

No, the other solutions I posted don't traverse the whole list - one uses a
while/cdr loop - and stops when it reaches the match. The other uses errset/err
to jump out.

Andrew.
Andrew Beckett
Principal European Technology Leader
Cadence Design Systems, UK.
 
On 23 Apr 2006 06:28:19 -0700, "Jimka" <jimka@rdrop.com> wrote:

can the prog/return be replaced with some sort of goto? i know that
go is supported in SKILL but i've never used it? Perhaps the macro
could generate a label/go pair using gensym????
go() (yuck, I feel dirty even mentioning it) only works within a prog(), so that
doesn't really help you..

BTW, I tried the first solution (using prog/return) in SKILL++, and it worked.
Perhaps prog() doesn't give all the lexical scoping advantages that let() does,
so perhaps that's why it's not "supported" in SKILL++?

Andrew.
Andrew Beckett
Principal European Technology Leader
Cadence Design Systems, UK.
 

Welcome to EDABoard.com

Sponsor

Back
Top