Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Carlos Newsgroups: comp.lang.postscript Subject: Re: functional ps? was: Re: html generator Date: Sat, 1 Apr 2017 23:33:24 +0200 Organization: A noiseless patient Spider Lines: 104 Message-ID: <20170401233324.3184776f@samara.DOMA> References: <3f057c06-9f44-4f91-9912-361bd7667bbe@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Injection-Info: mx02.eternal-september.org; posting-host="5f0dd43b60fb178179ff38c515766e30"; logging-data="11289"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+SG+B3dvuYAfRAkx/WfyUoVyelMKM+EyY=" X-Newsreader: Claws Mail 3.14.1 (GTK+ 2.24.31; x86_64-pc-linux-gnu) Cancel-Lock: sha1:uOmKFwQk0E4XkSxZx2FzZJPosjg= Xref: csiph.com comp.lang.postscript:3032 [luser droog , 2017-03-31 23:48] [...] > Subsequent iterations and conversations have steered the project > somewhat away from the object-orientation paradigm (although of > course that will be important in the js of the resulting page) > towards being more 'functional'. So the following is a grab-bag > of stuff which is my attempt to rewrite some postscript without > following my usual style. > > Any comments (positive or negative) appreciated. > > > $ cat toolbox.ps > > /toolbox-main { > 4 5 6 {a b c} BEGIN I find this unnecessary. What's the advantage over << /a 4 /b 5 /c 6 >> begin? For assigning parameters, I prefer your idiom ({ c b a } { exch def } forall), or a better abstraction, maybe something like /pythagorean-distance { x0 y0 x1 y1 } { ... } defn [...] > /backward-for-loop { % a proc > exch backwards % proc a n-1 -1 0 > 5 -1 roll % a n-1 -1 0 proc > for > } def I had to change this to: /backwards-for-loop { % a proc exch backwards % proc a n-1 -1 0 4 -1 roll % a n-1 -1 0 proc for } def [...] > % array-of-strings join string > % array-of-arrays join array > % string* n join string > % array* n join array > % > /join { > dup is_integer { array astore } if > join-elements > } def I like this implementation, it's well factored and easy to follow. I never seem to be able to do that, I always put everything in one function. > > /join-elements { % a > dup element-lengths-sum % a n > 1 index new-same-type-as-first % a a' > exch put-by-intervals % a' > } def > > /element-lengths-sum { % a > 0 exch { length add } forall % n > } def > > /type-constructor << > /arraytype {array} > /stringtype {string} > /nulltype {string} > >> def > > > /new-same-type-as-first { % n a > %pstack/ = > first type % n a[0] > %pstack/ = > type-constructor exch get exec % a a' > } def > > /first { dup length 0 eq { pop null }{ 0 get } ifelse } def > > /put-by-intervals { % a' a > 0 exch { % a' pos a[i] > put-element-and-update-position % a' pos a[i] > } forall % a' pos' > pop % a' > } def > > /put-element-and-update-position { % a' pos a[i] > 3 copy putinterval % a' pos a[i] > length add % a' pos' > } def > > /is_integer { type /integertype eq } def > /is_array { type /arraytype eq } def > /is_dict { type /dicttype eq } def > /is_null { type /nulltype eq } def > /is_zero { dup is_integer { 0 eq }{ false } ifelse } def > > /main where { pop }{ toolbox-main } ifelse --