December 06, 2019
On Friday, 6 December 2019 at 18:53:22 UTC, Jonathan Marler wrote:
> On Friday, 6 December 2019 at 18:25:20 UTC, Craig Dillabaugh wrote:
>> On Friday, 6 December 2019 at 08:47:59 UTC, Paolo Invernizzi wrote:
>>> On Thursday, 5 December 2019 at 22:28:53 UTC, Adam D. Ruppe
>> clip
>>>
>>> Yesterday happened to me to translate a modest size python script into D, to incorporate it in a product, and it was a pleasant experience.
>>>
>>> The port was really really easy ... but I'm starting to miss list comprehension ...
>>>
>>> Anyway, point taken!
>>
>> Wouldn't it be fairly easy to write some sort simple library that gives you list comprehensions in D.  It wouldn't be a nice as the python syntax, but it should be doable no?
>
> You could do that, or you could use a UFCS chain as well.  More flexible than list comprehensions.

Maybe you are both right ... and maybe I've written too much Python code in the past years and indeed, UFCS chains are a killer future of D: every list comprehension was turned into a nice UFCS chain.

Let's forget about that: the point is still taken by D, converting python code in D code is a pleasant experience!


December 07, 2019
On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
>
> Maybe you are both right ... and maybe I've written too much Python code in the past years and indeed, UFCS chains are a killer future of D: every list comprehension was turned into a nice UFCS chain.
>
> Let's forget about that: the point is still taken by D, converting python code in D code is a pleasant experience!

https://dev.to/jessekphillips/map-reduce-in-d-25nm

This was my very brief comparison of List comprehension vs Ds libraries.
December 07, 2019
On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
> Maybe you are both right ... and maybe I've written too much Python code in the past years and indeed, UFCS chains are a killer future of D: every list comprehension was turned into a nice UFCS chain.
>
> Let's forget about that: the point is still taken by D, converting python code in D code is a pleasant experience!

What I miss though is creating ranges with something like python's generator functions.
December 07, 2019
On Saturday, 7 December 2019 at 09:59:01 UTC, Tobias Pankrath wrote:
> What I miss though is creating ranges with something like python's generator functions.

Implement C++ stackless coroutines, perhaps?

It will eventually be important to have something compatible in order to interface well.

December 07, 2019
On Saturday, 7 December 2019 at 09:59:01 UTC, Tobias Pankrath wrote:
> On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
>> Maybe you are both right ... and maybe I've written too much Python code in the past years and indeed, UFCS chains are a killer future of D: every list comprehension was turned into a nice UFCS chain.
>>
>> Let's forget about that: the point is still taken by D, converting python code in D code is a pleasant experience!
>
> What I miss though is creating ranges with something like python's generator functions.

You can use std.range.generate with any random closure:

  import std.stdio;

  void main() {
      import std.range : take, zip, generate;

      auto multiples(int n) {
          int i;
          return generate!({
              return i += n;
          });
      }

      foreach (p; zip(multiples(2), multiples(3)).take(5)) {
          writeln(p[0], " ", p[1]);
      }
  }

Or use std.concurrency to get the same control flow:

  void main() {
      import std.range : take, zip;
      import std.concurrency : Generator, yield;

      auto multiples(int n) {
          return new Generator!int({
              int i;
              while (true) yield (i += n);
          });
      }

      foreach (p; zip(multiples(2), multiples(3)).take(5)) {
          writeln(p[0], " ", p[1]);
      }
  }

December 07, 2019
On Saturday, 7 December 2019 at 10:17:46 UTC, mipri wrote:
> On Saturday, 7 December 2019 at 09:59:01 UTC, Tobias Pankrath wrote:
>> [...]
>
> You can use std.range.generate with any random closure:
>
>   import std.stdio;
>
>   void main() {
>       import std.range : take, zip, generate;
>
>       auto multiples(int n) {
>           int i;
>           return generate!({
>               return i += n;
>           });
>       }
>
>       foreach (p; zip(multiples(2), multiples(3)).take(5)) {
>           writeln(p[0], " ", p[1]);
>       }
>   }
>
> Or use std.concurrency to get the same control flow:
>
>   void main() {
>       import std.range : take, zip;
>       import std.concurrency : Generator, yield;
>
>       auto multiples(int n) {
>           return new Generator!int({
>               int i;
>               while (true) yield (i += n);
>           });
>       }
>
>       foreach (p; zip(multiples(2), multiples(3)).take(5)) {
>           writeln(p[0], " ", p[1]);
>       }
>   }

Didn't know std.concurrency.Generator, thanks!

With std.range.generate I don't know how to signal exhaustion/emptyness of a range. For simple infinite use cases it's cool though.
December 07, 2019
On Saturday, 7 December 2019 at 10:49:37 UTC, Tobias Pankrath wrote:
> On Saturday, 7 December 2019 at 10:17:46 UTC, mipri wrote:
>>
>> You can use std.range.generate with any random closure:
>>
>>   import std.stdio;
>>
>>   void main() {
>>       import std.range : take, zip, generate;
>>
>>       auto multiples(int n) {
>>           int i;
>>           return generate!({
>>               return i += n;
>>           });
>>       }
>>
>>       foreach (p; zip(multiples(2), multiples(3)).take(5)) {
>>           writeln(p[0], " ", p[1]);
>>       }
>>   }
>>
>> [...]
>
> Didn't know std.concurrency.Generator, thanks!
>
> With std.range.generate I don't know how to signal exhaustion/emptyness of a range. For simple infinite use cases it's cool though.

You can use Nullable (or Optional from dub) and a bit of post-processing to get a finite range:

import std;

void main()
{
    auto seq(int start, int end)
        in (start <= end)
    {
        int i = start;
        return
            generate!({
                if (i >= end) { return Nullable!int.init; }
                else { return nullable(i++); }
            })
            .until!(n => n.isNull)
            .map!(n => n.get);
    }

    writeln(seq(10, 20).array);
}

December 09, 2019
On 12/7/19 4:28 AM, Jesse Phillips wrote:
> On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
>>
>> Maybe you are both right ... and maybe I've written too much Python code in the past years and indeed, UFCS chains are a killer future of D: every list comprehension was turned into a nice UFCS chain.
>>
>> Let's forget about that: the point is still taken by D, converting python code in D code is a pleasant experience!
> 
> https://dev.to/jessekphillips/map-reduce-in-d-25nm
> 
> This was my very brief comparison of List comprehension vs Ds libraries.

"In the first situation filtering came before the operation, here it will ultimately be useless because it operates on the square of a number which is always even."

You sure about that? ;)

-Steve
December 10, 2019
On Monday, 9 December 2019 at 16:33:30 UTC, Steven Schveighoffer wrote:
> On 12/7/19 4:28 AM, Jesse Phillips wrote:
>> On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
>>> [...]
>> 
>> https://dev.to/jessekphillips/map-reduce-in-d-25nm
>> 
>> This was my very brief comparison of List comprehension vs Ds libraries.
>
> "In the first situation filtering came before the operation, here it will ultimately be useless because it operates on the square of a number which is always even."
>
> You sure about that? ;)
>
> -Steve

Yes because anything else is filtered out.

I must have been thinking about addition :)
December 10, 2019
On Tuesday, 10 December 2019 at 02:23:21 UTC, Jesse Phillips wrote:
> On Monday, 9 December 2019 at 16:33:30 UTC, Steven Schveighoffer wrote:
>> On 12/7/19 4:28 AM, Jesse Phillips wrote:
>>> On Friday, 6 December 2019 at 20:09:46 UTC, Paolo Invernizzi wrote:
>>>> [...]
>>> 
>>> https://dev.to/jessekphillips/map-reduce-in-d-25nm
>>> 
>>> This was my very brief comparison of List comprehension vs Ds libraries.
>>
>> "In the first situation filtering came before the operation, here it will ultimately be useless because it operates on the square of a number which is always even."
>>
>> You sure about that? ;)
>>
>> -Steve
>
> Yes because anything else is filtered out.
>
> I must have been thinking about addition :)

---
new_range  = [i * i for i in range(5)   if i % 2 == 0]
---
import std.range;
auto new_range = iota(5)
                 .filter!(i => i % 2)
                 .map!(i => i * i);

These produce different results, is that intended? I think the filter should be

`filter!(i => i % 2 == 0)`

For your use case it makes no difference if you map first or filter first. It might be useful to show a case where it does matter to highlight how the UFCS allows D to give a more natural order of the chained operations.

Cheers,
Norm