[concurrency-interest] Concurrency-interest Digest, Vol 36, Issue 11

David J. Biesack David.Biesack at sas.com
Mon Jan 7 14:39:00 EST 2008


> From: concurrency-interest-request at cs.oswego.edu
> Date: Mon, 07 Jan 2008 12:00:02 -0500
> 
> Date: Mon, 07 Jan 2008 11:05:44 -0500
> From: Doug Lea <dl at cs.oswego.edu>
> Subject: Re: [concurrency-interest] In-progress ParallelArray changes
> 
> After a few distractions, the "version 2" ParallelArray API files
> are now available. See the usual places:
> 
> API specs:  http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/
> jar file: http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166y.jar
> CVS sources: http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166y/

cool - thanks
 
> Below is pasted reminder about main changes.
> Which forgot to mention full cascade support:
>    pa.withFilter(p1).withFilter(p1).withMapping(m1).withMapping(m2)...
> (Yes, I did once say that I wasn't going to do this, but decided
> that people were right about it being very inconvenient to do this
> manually.)

Nice; I like the chaining.
 
> Also, here are a few questions for those of you using these APIs.
> 
> 1. It is now easy to use the default global ForkJoinExecutor,
> but should it be made even easier, by supporting static factory
> methods that omit it as an argument? 

I'd prefer to see a smaller API footprint, so I recommend leaving the parameter there rather than overloading, and simply use the default executor if the caller passes null.

> 2. The prefix classes (WithFilter, WithMapping etc) do not themselves
> support support Iterable. So for example, to iterate through some,
> you'd need to do pa.withFilter(pred).all().iterator(). This is not
> done to be annoying, but because there are two perfectly reasonable
> expectations people might have about constructions like:
>    for(T e: pa.withFilter(pred)) ...
> Since iterators are sequential, should this mean to just
> sequentially evaluate filters as elements are produced, or
> should it perform a full parallel mapping first, and then produce
> the iteration elements without further processing? Currently, there
> is no way to obtain the first behavior. Should there be?

Taking a hint from Fortress and other such languages with parallel loops, where a parallel loop
    for (item <- generator)
becomes sequential with
    for (item <- sequential(generator))

could some sort of sequential operator or method be added to achieve the behavior
of delayed execution of the mappings, i.e. with a FutureTask or something?

    for(T e: pa.withFilter(p1).withFilter(p2).withMapping(m1).sequentially()) ...

instead of

    for(T e: pa.withFilter(p1).withFilter(p2).withMapping(m1).all()) ...

The returned instance would be an Iterable but would not fork. I've not played with PA enough to know if this would work, but it seems more natural from an API and client usage perspective.

I also have some general comments on the class/interface naming conventions, which differ depending on whether the signature involves a generic type parameter T or not. I don't see a strong reason for the disparity and recommend a consistent naming pattern

  <FromType>To<ToType>Mapper
  <Type>Predicate
  <Type>Comparator
  To<Type>Generator
  Mapper

such as

  Ops.IntToIntMapper   becomes Ops.TypeToIntMapper<T> with int map(T t)
  Ops.MapperFromInt<T> becomes Ops.IntToTMapper<T> with <T> map(int t)
  Ops.Mapper<T,U>      becomes Ops.TToUMapper<T,U>  with <U> map(<T> t)
  etc.

Documentation wise, for mappers, T and U should be used consistently for the input and output types and parameter names.

For example, given

  Ops.Mapper<T,U>       :: U    map(T t)
  "An object with a function accepting objects of type T and returning those of type U"

then

  Ops.MapperFromLong<T> :: T    map(long t)
  "A mapper accepting a long argument"

should be

  Ops.MapperFromLong<U> :: U    map(long t) 
  "A mapper accepting a long argument t and returning objects of type U"

Or, if there is not a strong reason for using T and U generic type names, I suggest T for a "to" type and F for a "from" type, as in

  Ops.Mapper<F,T>       :: T    map(F from)
  Ops.Predicate<F>      :: boolean evaluate(F from)
  Ops.Combiner<F,G,T>   :: T    combine(F f, G g) 

and so on.

-- 
David J. Biesack     SAS Institute Inc.
(919) 531-7771       SAS Campus Drive
http://www.sas.com   Cary, NC 27513



More information about the Concurrency-interest mailing list