Adam Turoff on Tue, 7 Mar 2000 01:24:03 -0500 (EST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: Funky code thing (index-rindex) (fwd)


Forwarded message:
> From: abigail@delanet.com
> Date: Tue, 7 Mar 2000 01:11:28 -0500
> To: Mark-Jason Dominus <mjd@plover.com>
> Cc: phl@lists.pm.org
> Subject: Re: Funky code thing (index-rindex)
> Reply-To: abigail@delanet.com
> 
> On Mon, Mar 06, 2000 at 10:54:45PM -0500, Mark-Jason Dominus wrote:
> > 
> > Here's the thing I wanted to show, but I couldn't remember what it
> > was:
> > 
> >         sub handle_parens {
> >           my ($t, $code, $o, $c) = @_;
> >           $o = '(' unless defined $o;
> >           $c = ')' unless defined $c;
> >         
> >           while ('true') {
> >             last if (my $cp = index  $t, $c)      < 0;
> >             last if (my $op = rindex $t, $o, $cp) < 0;
> >             $code->(substr($t, $op, $cp-$op+1));
>                                               ^ Or perhaps: length $c?
> >           }
> >         
> >           return $t;
> >         }
> > 
> > The thing I actually wanted to show was the
> > 
> >         last if (my ... )
> > 
> > in the middle, but when I got home and saw the context, I thought
> > folks might be interested to see the whole thing.  
> > 
> > There are at least four features of note:
> > 
> > 1. This shows the new method for handling strings with nested
> >    delimiters that I mentioned this evening.  If you give it the
> >    string 
> > 
> >         (1 (2) (3 (4)) 5)
> > 
> >    it will invoke $code on (2), then (4), then (3 ...), then (1 ... 5),
> >    in that order.  Short descrition:  The parentheses groups get
> >    handled in left-to-right order of their *close* parentheses.
> 
> Yes, it's a recursive algorithm made sequential, except that you forget
> about the stack and seek back in the string to find the opening delimiter.
> 
> > 2. last if (my ... ) < 0 ;
> > 
> >    Clever innovation or horrid obfuscation?
> 
> Somewhere in between. ;-)
> 
> > 3. while ('true') { ... }
> > 
> >    Idiomatic or idiotic?
> 
> My first reaction was "cute", immediately followed by "but it means the
> same as: while ('false') { ... }". Perhaps not a good idea.
> 
> I like to write my "infinite loop"s as bare blocks with a redo.
> 
> > 4. Notice the way that $t gets modified.  $code is supposed to look
> >    something like this:
> > 
> >         sub { $_[0] = '...' }
> > 
> >    The $_[0] is aliased to the actual argument, which is a substr()
> >    call.  Thus assigning to $_[0] down in the $code actually modifies
> >    $t back in handle_parens.  What do people think of this?  I found
> >    it rather convenient to use, and had the idea that maybe other
> >    people would be able to use it easily without having to know how it
> >    was implemented.  What verdict do you folks have?  Do you find it
> >    sweet, sour, bitter, or salty?
> 
> Dubious. It's an action at a distance, and it makes it easy to break your
> program by just looking at the sub and rewriting (parts of it) in such a
> way the trick doesn't work anymore. On the other hand, it is kind of cool.
> 
> 
> Note also that this approach is quadratic in the length of the string, due
> to the repeatedly seeking back and forth. But then, since you probably want
> to remove the parens before futher processing, you're doing quadractic work
> anyway.
> 
> 
> If you don't modify the string, preprocessing the string and creating
> a double linked list of positions of opening and closing delimiters
> would turn it into a linear algorithm. But it would look way less cool.
> Not to mention that with modern computers, you won't notice the quadratic
> behaviour unless you have real long strings.
> 
> 
> I just realized there's a danger if you want to generalize this to
> delimiters longer than one character. Suppose you do this, and your
> opening and closing delimiters are '/*' and '*/', then with a substring of
> '/*/*', you will find the '*/' as closing delimiter, find the overlapping
> '/*' as opening delimiter, and call the closure with '/*/' as substring.
> 
> 
> 
> Abigail
> 

**Majordomo list services provided by PANIX <URL:http://www.panix.com>**
**To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**