Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.postscript > #2817
| From | Carlos <angus@quovadis.com.ar> |
|---|---|
| Newsgroups | comp.lang.postscript |
| Subject | Re: decoupled for-loop/iterator-variable construct |
| Date | 2016-09-17 15:04 +0200 |
| Organization | A noiseless patient Spider |
| Message-ID | <20160917150434.53428155@samara.DOMA> (permalink) |
| References | <5a5eafe0-89fc-4a5f-b450-06b8db73c61e@googlegroups.com> <74bb3f1c-0602-46b6-b8cb-d2d78a237e68@googlegroups.com> |
[luser droog <luser.droog@gmail.com>, 2016-09-14 22:58]
> external iterator
That's a great idea. I started to play with it, and I found it makes
a lot of things easier. I generalized it to a makeiterator function:
% obj1...objn n procnext procnext? -> userprocnext userprocnext?
You pass to it:
- some objects you need to keep track of the iteration
- n, the number of objects
- a proc, which gets those objects and returns the next iteration
item(s) and a new set of objects with the updated iteration status
- another proc, which receives the objects and returns whether there
are more items
and it returns two procs that don't take any arguments:
- one that returns the next iteration item(s)
- and one that returns true or false, whether there is a next iteration
item
For example, a function to create "for" iterators like yours would be
constructed this way:
% start inc end -> next next?
/foriter {
3
% i inc end -> i i+1 inc end
{ 2 index 2 index add 3 1 roll }
% i inc end -> t|f
{ exch 0 lt { gt } { lt } ifelse }
makeiterator
} def
GS> 1 3 6 foriter
GS<2> /next? exch def /next exch def
GS>next =
1
GS>next? =
true
GS>next =
4
GS>next?
false
I struggle writing functions that take procs and execute them inside
loops without stack or dictionary interference. With external iterators
that problem doesn't exist anymore! You just have to yield the next
value, and let "{ } loop" take care of the looping.
With a little syntactic sugar (the function "done") to hide the
details they almost look like control structures:
GS>(External iterators are great) 9 eachslice { == } done
(External )
(iterators)
( are grea)
I think this idea can be extended to filters and mappers. I'll get into
it when I get tired of writing all kind of iterators :)
Here is the code of makeiterator and done, and a couple of iterators:
% obj1...objn n nextproc next?proc -> unextproc unext?proc
/makeiterator {
4 dict begin
/next?proc exch def /nextproc exch def
array astore /arr exch def
/unext? [
/arr load /aload cvx /pop cvx
/next?proc load /exec cvx
] cvx def
[ /unext? load /exec cvx /not cvx { exit } /if cvx
/arr load /aload cvx /pop cvx /nextproc load /exec cvx
/arr load /astore cvx /pop cvx ] cvx
/unext? load
end
} def
% next next? proc -> -
/done {
exch pop
% { next proc } loop
[ 3 1 roll /exec cvx exch 1 index ] cvx
loop
} def
% start inc end -> next next?
/foriter {
3
% i inc end -> i i+1 inc end
{ 2 index 2 index add 3 1 roll }
% i inc end -> t|f
{ exch 0 lt { gt } { lt } ifelse }
makeiterator
} def
% arr -> n n?
/eachwithindex {
0 2
% arr i -> arr[i] i arr i+1
{ 2 copy get 1 index 4 2 roll 1 add }
% arr i -> t|f
{ exch length lt }
makeiterator
} def
% arrayn ... array1 n -> nextproc next?proc
/eachinparallel {
% get minimum length
1 dict begin
/n exch def
dup length 1 1 n { index length 2 copy gt { exch } if pop } for
0 n % an...a1 len idx n
n 3 add
end
% an...a1 len i n -> an[i]...a1[i] an...a1 len i+1 n
{ 2 dict begin
/n exch def /i exch def
n -1 1 { index i get n 2 add 1 roll } for
i 1 add n
end
}
% an...a1 len i n -> t|f
{ 3 1 roll gt
exch { exch pop } repeat
}
makeiterator
} def
% arr slicesize -> next next?
/eachslice {
0 3
% arr n i -> arr[i..i+n] arr n i+1
{ 3 copy exch getinterval 4 1 roll
1 index add }
% arr n i -> t|f
{ add exch length le }
makeiterator
} def
--
Back to comp.lang.postscript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-06-23 21:04 -0700
Re: decoupled for-loop/iterator-variable construct jdaw1 <jdawiseman@gmail.com> - 2016-09-11 16:49 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-11 20:58 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-13 18:52 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-14 22:58 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-14 23:01 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-14 23:02 -0700
Re: decoupled for-loop/iterator-variable construct Carlos <angus@quovadis.com.ar> - 2016-09-17 15:04 +0200
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-18 14:10 -0700
Re: decoupled for-loop/iterator-variable construct Carlos <angus@quovadis.com.ar> - 2016-09-19 15:03 +0200
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-19 10:56 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-19 11:35 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-09-19 11:42 -0700
Re: decoupled for-loop/iterator-variable construct luser droog <luser.droog@gmail.com> - 2016-10-01 13:59 -0700
csiph-web