[plt-scheme] Abstracting Visitors (is in Java)

From: wooks . (wookiz at hotmail.com)
Date: Thu Jan 4 11:51:36 EST 2007

Hmmm I'll try again. I suppose the measly indentation didn't help the 
readability.

The initial question I asked is now moot since the code I was asking how to 
abstract was removed after I applied the right design recipe template.

What I have is a class that runs filters on an object called MyFile which 
has two attributes - a name and a file size.

The PatternMatch filter Visitor filters the name against a lightweight 
regular expression parser written by yours truly.

The SizeFilter filters the MyFiles by file size.

I have managed to abstract out common functionality into a filter function. 
The last 2 parameters of are the calling expression and a lambda that 
implements the boolean function.

   private static Object filter(Object first, AList rest, IList visitor, 
ILambda op) {
      final AList getTheRest = ((AList)rest.accept(visitor));
      return ((Boolean)op.execute()).booleanValue() ?
         new AList.Cons(first, getTheRest) :
         getTheRest;

The PatternMatch Visitors contributes  the predicate for the filter by 
calling it and passing the lambda expression

new ILambda() {
            public Object execute() {
               return new PatternMatch(pattern.toString(), 
((MyFile)first).name).match();
            }
         });


   public static class PatternMatchV extends Filter implements IList  {
      AList pattern;
      PatternMatchV(AList pattern) {
         this.pattern = pattern;
      }
      
//________________________________________________________________________
      public Object forCons(final Object first, final AList rest) {
         //Pattern Matching Filter
         return filter(first, rest, this, new ILambda() {
            public Object execute() {
               return new PatternMatch(pattern.toString(), 
((MyFile)first).name).match();
            }
         });
      }
   }

The Size filter does same but of course invokes with a different lambda

new ILambda() {
            public Object execute() {
               return maxFileSize?
                  size > fileSize:
                  size < fileSize;
            }
         });

If maxFileSize is false it looks for files smaller than the fileSize 
otherwise it looks for files bigger than fileSize


   public static class SizeV extends Filter implements IList {
      long fileSize;
      boolean maxFileSize;
      SizeV(long fileSize, boolean maxFileSize) {
         this.fileSize = fileSize;
         this.maxFileSize = maxFileSize;
      }
      
//__________________________________________________________________________
      public Object forCons(final Object first, final AList rest) {
         //File size filter
         final long size = ((MyFile)first).size;
         return filter(first, rest, this, new ILambda() {
            public Object execute() {
               return maxFileSize?
                  size > fileSize:
                  size < fileSize;
            }
         });
      }
   }
}

Some observations. I spent the best part of the week looking for one bug. 
Eventually I found it had been caused because I was using Cons where I 
needed Append and thus was passing a nested instead of a flat list.

With Scheme this would have been apparent from the results I got. With Java 
you get a classCastException - not very helpful when you've had to put a 
bazillion casts in the code hence why it took so  long to find.

There are no destructive assignment statements in the code and all the 
non-Visitor code has been written tail recursively (I haven't figured out 
how to do the equivalent with a Visitor yet).
Good you say... yeah well given a deep enough directory structure I get a 
stack overflow!!

Haven't yet thought about what the fate of my so called filter higher order 
function will be in situations that require the Lambda to take arguments.

The fold idea is interesting. I was wondering whether that could be done. I 
find Java  obfuscates the isomorphism between what little I know of OO and 
FP. That makes things unnecessarily hard.

Wondering whether threading the code will solve my stack overflow problem 
(searching each subdirectory in a different thread), not sure how to bring 
it all together later?





>From: Noel Welsh <noelwelsh at yahoo.com>
>To: "wooks ." <wookiz at hotmail.com>, plt-scheme at list.cs.brown.edu
>Subject: Re: [plt-scheme] Abstracting Visitors (is in Java)
>Date: Thu, 4 Jan 2007 06:15:47 -0800 (PST)
>
>Interesting question.  If I understand the code correctly
>(and that's no sure thing; I found the code very difficult
>to read (Java's fault -- excessive casting etc)) there are
>two possible implementations:
>
>   !. Pass in the action to perform in the case of the empty
>list
>
>   2. Delegate this decision to the subclass (use an
>abstract method)
>
>Do the 1st and you've just about implemented fold.  The 2nd
>I consider more OO style, but you end up writing classes
>that are really functions, as you need to have a new class
>for every possible action
>
>The interplay between OO and FP is certainly interesting!
>
>N.
>
>--- "wooks ." <wookiz at hotmail.com> wrote:
>
> > However there is more that could be abstracted. Both
> > forCons methods start
> > with
> >
> >       return first instanceof Cons ?
> >         new Cons(((Cons)first).accept(this),
> > ((AList)rest.accept(this))):
> >
> > to deal with the case of nested lists.
> >
> > I thought of hoisting that test into an abstract forCons
> > class and then
> > calling it via a super method in which case it would
> > become
> >
> >       if ( first instanceof Cons)
> >         return new Cons(((Cons)first).accept(this),
> > ((AList)rest.accept(this)));
> >
> > but what would I return if the If statement failed?
>
>
>Email: noelwelsh <at> yahoo <dot> com   noel <at> untyped <dot> com
>AIM: noelhwelsh
>Blogs: http://monospaced.blogspot.com/  http://www.untyped.com/untyping/
>
>__________________________________________________
>Do You Yahoo!?
>Tired of spam?  Yahoo! Mail has the best spam protection around
>http://mail.yahoo.com

_________________________________________________________________
MSN Hotmail is evolving – check out the new Windows Live Mail 
http://ideas.live.com



Posted on the users mailing list.