Few things II

BCS ao at pathlink.com
Sat Aug 11 08:34:23 PDT 2007


Reply to bearophile,

> Oskar Linde:
> 
>> Many times people have been posting improvements to the built in AA.
>> The problem is proving that the improvements really are better for
>> the general case. The hardest part has proven to be defining the
>> "general case".<
>> 
> I understand. We may collect a large repository of code/snippets that
> use AAs, so they can be tuned against that repository.
> 
> -----------------
> 
> BCS:
> 
>> D's opApply syntax IMO seems much cleaner and easier to understand.<
>> 
> I can't agree (but I know Python much more than D, so I am biased),
> yield of Python is very simple :-) Here are some examples 

[dropped python code]

> I know you can do those things with D too, this is an example of a
> translation from Python that uses yield to D, a lazy generator of all
> the permutations of a sequence, algorithm from Phillip Paul Fuchs,
> modified:
> 

[dropped D code]

> (If you spot problems in that D code you are encouraged to say it, I
> am a newbie of D still).

I don't see anything that is a problem (I don't follow the details though). 
I'll put a copy at the end that has some edits, mostly for code space and 
editablility.

> 
> They do similar things, but I can't see how you can say that opApply
> of D "seems much cleaner and easier to understand" than Python yield
> :-)
>

Maybe I under-spoke, the opApply is much more transparent. the system is 
doing, and hiding, a lot less complexity. IMO a system hiding to much complexity 
is not a good thing. Also, opApply is working within the existing constraints 
of the language.
 
>> OTOH you can fake it quiet well with an delegate that stores most of
>> it's state in an object.<
>> 
> Something quite similar to a working version of your code is the
> builtin Python function iter(), that given an iterable (like an array,
> an iterable object, etc) return a lazy iterable object that allows to
> scan its elements in a flexible way (I have created some similar
> functions with D). But iter() doesn't replace yield.
> 
> Bye and thank you for the answers,
> bearophile




|Xpermutations!(TyItem) xpermutations(TyItem)(TyItem[] items, bool copy=true)
|{
|  if(copy)
|    return new Xpermutations!(TyItem, true)(items);
|  else
|    return new Xpermutations!(TyItem, false)(items);
|}
|
|class Xpermutations(TyItem, bool copy)
|{
|  int[] range(int stop)
|  {
|    int[] result;
|    if (stop > 0)
|    {
|      result.length = stop;
|      for (int i = 0; i < stop; i++)
|        result[i] = i;
|    }
|    return result;
|  }
|
|  TyItem[] items;
|  bool copy;
|
|  this(TyItem[] items, bool copy=true)
|  {
|    this.items = items.dup;
|    this.copy = copy;
|  }
|
|  int opApply(int delegate(ref TyItem[]) dg)
|  {
|    TyItem[] items2 = items;
|
|    static if(copy) items2 = items.dup;
|    if (int result = dg2(items2)) return result; // yield items2
|
|    int n = items.length;
|    int i = 1;
|    auto p = range(n + 1);
|    TyItem aux;
|
|    while (i < n)
|    {
|      p[i] -= 1;
|      int j = (i & 1) ? p[i] : 0;
|      aux = items[j];
|      items[j] = items[i];
|      items[i] = aux; // swap
|      
|      static if(copy) items2 = items.dup;
|      if (int result = dg2(items2)) return result; // yield items2
|      
|      i = 1;
|      
|      while (p[i] == 0)
|      {
|        p[i] = i;
|        i++;
|      }
|    }
|  return 0;
|  }
|}





More information about the Digitalmars-d mailing list