www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 9550] New: Repeat!fun(size_t n)

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9550

           Summary: Repeat!fun(size_t n)
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: daniel350 bigpond.com


--- Comment #0 from Daniel Cousens <daniel350 bigpond.com> 2013-02-19 23:45:50
PST ---
Unless I'm missing something, after several separate discussions on the D IRC,
I could not find a way to run a function 'n' times lazily for a range without
doing hackery's like this:

iota(100).map!(x => uniform(0, 76));

The use case is where you want to repeat an (impure) function n times lazily.
A possible example:

auto five_random_ints = take(recurrence!(uniform!int), 5)

or

auto five_random_ints = repeat!(uniform!int)(5);

If there is an idiomatic way to do this already that I am missing, sorry for
taking up your time.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 19 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9550


monarchdodra gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |monarchdodra gmail.com


--- Comment #1 from monarchdodra gmail.com 2013-02-20 00:16:07 PST ---
Isn't what you are asking for a special case of sequence that discards any and
all input?

//----
int fun(T)(T/+Tuple!()+/, uint n)
{
    static int i;
    return ++++i;
}

void main()
{
    auto a = sequence!fun();
    writeln(a.take(10));
}
//----
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
//----

In this case "T" is a tuple containing the empty state, and n is the iteration
count.

Apart from the fancy sig, it's what you are asking for.

Given that the signature of "fun" isn't specified yet, we could special case
sequence for sequences that have no initial state, to simply call fun(n) (as
well as be more efficient). 

I think it would be a good idea. So I'll look into doing that. PS: could you
link the mentioned discussion, it could help.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9550



--- Comment #2 from Daniel Cousens <daniel350 bigpond.com> 2013-02-20 00:31:05
PST ---
(In reply to comment #1)
 Isn't what you are asking for a special case of sequence that discards any and
 all input?
 
 //----
 int fun(T)(T/+Tuple!()+/, uint n)
 {
     static int i;
     return ++++i;
 }
 
 void main()
 {
     auto a = sequence!fun();
     writeln(a.take(10));
 }
 //----
 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
 //----
 
 In this case "T" is a tuple containing the empty state, and n is the iteration
 count.
 
 Apart from the fancy sig, it's what you are asking for.
 
 Given that the signature of "fun" isn't specified yet, we could special case
 sequence for sequences that have no initial state, to simply call fun(n) (as
 well as be more efficient). 
 
 I think it would be a good idea. So I'll look into doing that. PS: could you
 link the mentioned discussion, it could help.

Granted, that is what I'm asking for, but it seems as hackish (if not more confusing) then the iota solution. The sequence solution does not sound very intuitive given the fact the output would change on each retrieval/take from the range. The discussions have been over a many conversations, as I have run into this problem several times now, and finally resolved it isn't just something I have missed in phobos. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 20 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=9550



--- Comment #3 from monarchdodra gmail.com 2013-02-20 01:15:30 PST ---
(In reply to comment #2)
 (In reply to comment #1)
 Isn't what you are asking for a special case of sequence that discards any and
 all input?
 
 //----
 int fun(T)(T/+Tuple!()+/, uint n)
 {
     static int i;
     return ++++i;
 }
 
 void main()
 {
     auto a = sequence!fun();
     writeln(a.take(10));
 }
 //----
 [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
 //----
 
 In this case "T" is a tuple containing the empty state, and n is the iteration
 count.
 
 Apart from the fancy sig, it's what you are asking for.
 
 Given that the signature of "fun" isn't specified yet, we could special case
 sequence for sequences that have no initial state, to simply call fun(n) (as
 well as be more efficient). 
 
 I think it would be a good idea. So I'll look into doing that. PS: could you
 link the mentioned discussion, it could help.

Granted, that is what I'm asking for, but it seems as hackish (if not more confusing) then the iota solution. The sequence solution does not sound very intuitive given the fact the output would change on each retrieval/take from the range. The discussions have been over a many conversations, as I have run into this problem several times now, and finally resolved it isn't just something I have missed in phobos.

FYI, sequence caches it's result, so if you just call front twice in a row, you *won't* get different values for each front. map *doesn't* cache its result, so you *will* get different results if you call front twice in a row. As for intuitiveness, I personally prefer "sequence" over "map", but that may be because I actually use sequence and recurrence, so I'm more used to it. A third alternative you could use is, instead of iota, you may want to consider using repeat: //---- int fun(int) { static int i; return ++++i; } void main() { auto a = repeat(0).map!fun(); writeln(a.take(10)); } //---- The "advantage" this approach is that you define the range *mechanics* (repeat+map) first, and then build the bounds on top of that (take). Since take is infinite, there are chances it'll run faster too (operations such as length/empty will be easier to compute, since carried by the "top", as opposed to the "bottom"). //-------- But enough off-topic. You opened an enhancement request. Could you maybe formalize your need a bit more, tell us in more detail what the semantics of the range you are trying to build are? How you would use such a range? This would help us better address the issue. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 20 2013