Hi Brad,
thanks for your time. As I said, I have rewritten this piece a hundred
times. Sometimes right, many times wrong... happened to send a wrong
implementation.
My first idea was something like this:
iter product(iterableA, iterableB) {
for a in iterableA {
for b in iterableB {
yield (a,b);
}
}
}
iter power(iterable, size: int) {
if(size<1) then return;
else if(size==1) {
for elem in iterable {
yield (elem,);
}
}
else {
for tuple in power(iterable,size-1) {
for elem in iterable {
yield ((...tuple),elem);
}
}
}
}
If tuples size must be known at compile time, this explains a lot. Makes
sense, I'm still in a gray area between C and Python mindset here, but this
clarifies my issue.
Many thanks,
2015-03-09 1:15 GMT-03:00 Brad Chamberlain <[email protected]>:
> Oh, here's one other idea for you (again with the apology that I haven't
> spent enough time with your code to figure out its goal...):
>
> It may be that if you were to change 'size' from a regular-old variable
> to a 'param' (compile-time-known value, similar to a C++ template function)
> that things might work better. Specifically, this would essentially permit
> each instantiation of power() by a unique value of 'size' to yield a
> different type (e.g., a case with size==1 could yield a 1-tuple, a case
> with size==2 could yield a 2-tuple, etc.).
>
> -Brad
>
>
> ------------------------------
> *From:* Brad Chamberlain
> *Sent:* Sunday, March 08, 2015 8:37 PM
> *To:* Victor Chaves
> *Subject:* RE: Fwd: Iterator inheritance
>
> Hi Victor --
>
> I've unfortunately only got a few minutes tonight and then will be
> traveling tomorrow.
>
> I believe it's the case that recursive iterators need to have the types
> that they yield declared in Chapel currently and that that's what this pair
> of errors is telling you (I think the second "error" should really be
> considered a note elucidating on the first case). I was able to get a bit
> further in compilation by declaring a return type, but I'm a little worried
> that power() may not have a well-defined static return type by Chapel's
> definition (specifically, is it supposed to be building up a bigger and
> bigger tuple on each yield? In Chapel a tuple variable's size must be
> known at compile-time, so that would be problematic in terms of declaring
> the return type. Or, maybe I'm not spending enough time thinking about
> what power/product are really doing.
>
> If I'm correct, you may want to build up a linked list instead of trying
> to use tuples for this case...
>
> Oh, the second problem I ran into (before worrying about the potential
> lack of a static well-defined type) is that when an iterator is invoked
> outside of a loop (as your call to power() is), the result is an array of
> all the things returned by the iterator. So part of the reason that your
> compiler can't resolve the return type is that the first yield is returning
> a 1-tuple of the iterable's element type while the second yield is return
> an array of ... whatever product returns. I got around that case by
> writing that version as:
>
> for p in product(...) do
> yield p;
>
> and that's when I started worrying that you're still trying to yield
> different types in the different branches.
>
> You may want to post to chapel-users to get more information while I"m
> on the road,
> -Brad
>
>
> ------------------------------
> *From:* Victor Chaves [[email protected]]
> *Sent:* Sunday, March 08, 2015 7:24 PM
> *To:* Brad Chamberlain
> *Subject:* Re: Fwd: Iterator inheritance
>
> Many thanks, Brad.
>
> You suggestion worked every time until now. But I'm still facing some
> problems with iterators.
>
> I'm trying to implement some iterator utilities:
>
> iter product(iterableA, iterableB) {
> for a in iterableA {
> for b in iterableB {
> yield (a,b);
> }
> }
> }
>
> iter power(iterable, size: int) {
> if(size<1) then return;
> else if(size==1) {
> for elem in iterable {
> yield (elem,);
> }
> }
> else {
> yield product(iterable,power(iterable,size-1));
> }
> }
>
> The `product` iterator worked just fine, out of the box.
>
> The `power` iterator is beating me to death. I spent 2 hours writing it
> in many different ways, but I could never get rid of these two errors at
> the same time (most of the time, both occur):
>
> `jane.chpl:86: error: unable to resolve return type of function 'power'
> jane.chpl:86: In iterator 'power':
> jane.chpl:94: error: called recursively at this point`
>
> The first error looks clear to me to be my fault, but the second error
> doesn't even looks like an error to me. I've written recursive iterators
> before, so I don't really understand why I'm getting this now.
>
> Thanks,
>
>
> 2015-03-04 18:41 GMT-03:00 Brad Chamberlain <[email protected]>:
>
>>
>> Hi Victor --
>>
>> You're not doing anything wrong, and are unfortunately running into a bug
>> in our implementation, listed in the STATUS file as: "Iterator methods may
>> not obey dynamic dispatch". The reason that the wording here is vague is
>> that it's not entirely clear to us (to me anyway) under what conditions the
>> bug manifests itself. For example, if I insert an "for i in 1..limit" in
>> each of your iterators, it seems to work.
>>
>> I'm reasonably certain that the bug relates to an issue with iterator
>> inlining, and that if you compile with --no-inline-iterators, things should
>> work OK (at least, for your test program, things work for me). Please give
>> a shout if you find cases in which the --no-inline-iterators flag doesn't
>> seem to help.
>>
>> Apologies for this bug which has been around longer than I'd care to
>> admit. I'll see if we can get someone on it for the upcoming release.
>>
>> -Brad
>>
>>
>>
>>
>> On Wed, 4 Mar 2015, Victor Chaves wrote:
>>
>> Hi,
>>>
>>> I'm trying to choose dynamically which iterator to use, so I'm using
>>> class
>>> inheritance with iterators inside them, like this:
>>>
>>> class Abstract {
>>> iter Iterator(limit: int) {
>>> yield 0;
>>> }
>>> }
>>>
>>>
>>> class Concrete : Abstract {
>>> iter Iterator(limit: int) {
>>> yield 1;
>>> }
>>> }
>>>
>>> But if I write
>>> var myclass : Abstract = new Concrete();
>>>
>>> myclass.Iterator(n) yields 0 instead of 1.
>>>
>>> Is there something I'm missing? Isn't Iterator supposed to get overriden?
>>>
>>> Thanks.
>>>
>>> --
>>> Victor Chaves
>>> Engenharia de Computação
>>> Instituto Militar de Engenharia
>>>
>>
>
>
> --
> Victor Chaves
> Engenharia de Computação
> Instituto Militar de Engenharia
>
--
Victor Chaves
Engenharia de Computação
Instituto Militar de Engenharia
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users