Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.postscript > #2095

Re: map and higher order functions

From Carlos <angus@quovadis.com.ar>
Newsgroups comp.lang.postscript
Subject Re: map and higher order functions
Date 2014-11-16 01:37 +0100
Organization A noiseless patient Spider
Message-ID <20141116013757.0dacc25d@samara.DOMA> (permalink)
References <20141030172728.0983c6bc@samara.DOMA> <95798773-17c6-41d3-8d80-06d1784a7e95@googlegroups.com> <20141102001537.515de3e5@samara.DOMA> <1cc8e78b-6698-4bab-b63c-9475cc63a5c3@googlegroups.com>

Show all headers | View raw


[luser- -droog <mijoryx@yahoo.com>, 2014-11-15 00:43]
[...]
> There is a possible problem here. Since `bind` applies to all
> subarrays, and the user-proc has been embedded directly into this
> array.
> 
> instead of
> 
> >                 //proc exec
> 
> it might be better to do
> 
>                   //mydict /proc get exec
> 
> so the procedure is not directly embedded.
> 
> Applying `bind` would break code that tries to use operator names as
> variables, like
> 
>     {
>         /length 5 def
>         length dup mul % length^2
>         ...
>     }
> 
> The executable name `length` in the second line would be replaced by
> the postscript operator if `bind` were applied.

I didn't think of that. The problem is worse, because the string is
tokenized at the time /map is executed, and by that moment the user
could have already redefined some operators (presumably he wouldn't do
that at library loading time).

    /length 5 def [ 1 2 3 ] { length add } map

So, basically, inside /map, the code surrounding "<userproc> exec"
should be bound before any operator is redefined, but the "<userproc>"
should be left as-is.

One solution can be to write the code as usual (not in a string), using
placeholders for the objects. That way, it would be bound at definition
time. When /map is called, the placeholders are replaced with the
objects. Basically, doing the "({ //x }) token" thing by hand, just so
everything that isn't a //name can be bound at definition time.

Here is a new version of map that uses that approach, plus two helper
procedures:

% <array/string> <proc> map <new array/string>
/map {
    4 dict begin
        /,proc exch def
        /,arr exch def
        /,res ,arr length
             ,arr type /stringtype eq { string } { array } ifelse
        def
        /,i 1 array def
        {
            0 1 /,arr length 1 sub { % for
                dup /,i 0  3 -1 roll  put
                /,arr exch get
                /,proc exec
                /,res /,i 0 get  3 -1 roll  put
            } for
            /,res
        } deepcopy dup currentdict replaceall
    end exec
} bind def

% copies array recursively
% <array> deepcopy <new array>
/deepcopy {
    dup xcheck exch
    dup length array copy
    dup length 1 sub 0 exch 1 exch { % for       % a i
        2 copy 2 copy get dup type /arraytype eq % a i a i e ?
        { % ifelse
            deepcopy put
        }
        {
            pop pop pop
        } ifelse
        pop
    } for
    exch { cvx } if
} bind def

% recursively replaces elements in <array> found in <dict>
% <array> <dict> replaceall -
/replaceall {
    1 index length 1 sub  0 1  3 -1 roll { % for 0 1 length-1
        3 copy  3 -1 roll  exch    % a d i d a i
        get                        % a d i d e
        2 copy known               % a d i d e ?
        % ifelse
        {                          % a d i d e
            get                    % a d i v
            3 index  3 1 roll      % a d a i v
            put
        } % else
        {                          % a d i d e
            dup type /arraytype eq % a d i d e ?
            { exch replaceall }
            { pop pop } ifelse
            pop
        } ifelse                   % a d
    } for
    pop pop
} bind def

Carlos.
-- 

Back to comp.lang.postscript | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

map and higher order functions Carlos <angus@quovadis.com.ar> - 2014-10-30 17:27 +0100
  Re: map and higher order functions ken <ken@spamcop.net> - 2014-10-30 16:57 +0000
    Re: map and higher order functions Carlos <angus@quovadis.com.ar> - 2014-10-30 19:55 +0100
      Re: map and higher order functions ken <ken@spamcop.net> - 2014-10-31 12:17 +0000
  Re: map and higher order functions Ross Presser <rpresser@gmail.com> - 2014-10-30 20:30 -0700
    Re: map and higher order functions Carlos <angus@quovadis.com.ar> - 2014-11-01 23:58 +0100
  Re: map and higher order functions luser- -droog <mijoryx@yahoo.com> - 2014-10-30 22:56 -0700
    Re: map and higher order functions Carlos <angus@quovadis.com.ar> - 2014-11-02 00:15 +0100
      Re: map and higher order functions luser- -droog <mijoryx@yahoo.com> - 2014-11-15 00:43 -0800
        Re: map and higher order functions Carlos <angus@quovadis.com.ar> - 2014-11-16 01:37 +0100
          Re: map and higher order functions luser- -droog <mijoryx@yahoo.com> - 2014-11-21 00:17 -0800
          Re: map and higher order functions luser- -droog <mijoryx@yahoo.com> - 2015-02-27 00:59 -0800

csiph-web