Re: Deciding one member of iteration chain at runtime

2023-02-17 Thread Chris Piker via Digitalmars-d-learn

On Friday, 17 February 2023 at 17:42:19 UTC, Ali Çehreli wrote:

// Two different steps
auto g1 = r.map!((int n) => n * n);
auto g2 = r.map!((int n) => n * 10);

// The rest of the algoritm
auto result = choose(condition, g1, g2)
  .array;


Now that's a handy construct.

There's many little goodies in phobos I've yet to learn, thanks 
for the tip!





Re: Deciding one member of iteration chain at runtime

2023-02-17 Thread Chris Piker via Digitalmars-d-learn

On Friday, 17 February 2023 at 17:44:20 UTC, H. S. Teoh wrote:
Here's an actual function taken from my own code, that returns 
a different range type depending on a runtime condition, maybe 
this will help you?


Thanks, this was helpful.

I keep forgetting to expand my horizons on what can be returned 
from an auto function.  I'm still unlearning C & Java.


Cheers,




Re: Deciding one member of iteration chain at runtime

2023-02-17 Thread Ali Çehreli via Digitalmars-d-learn

On 2/17/23 09:30, Chris Piker wrote:

> operatorG needs
> to be of one of two different types at runtime

std.range.choose may be useful but I think it requires creating two 
variables like g1 and g2 below:


import std.range;
import std.algorithm;

void main(string[] args) {
const condition = (args.length > 1);

// The first part of the algorithm
auto r = iota(10)
 .filter!(n => n % 2);

// Two different steps
auto g1 = r.map!((int n) => n * n);
auto g2 = r.map!((int n) => n * 10);

// The rest of the algoritm
auto result = choose(condition, g1, g2)
  .array;
}

Ali



Re: Deciding one member of iteration chain at runtime

2023-02-17 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Feb 17, 2023 at 05:30:40PM +, Chris Piker via Digitalmars-d-learn 
wrote:
[...]
> In order to handle new functionality it turns out that operatorG needs
> to be of one of two different types at runtime.  How would I do
> something like the following:
> 
> ```d
> auto virtualG;  // <-- probably invalid code, illustrating the idea
> if(runtime_condition)
>virtualG = operatorG1;
> else
>virtualG = operatorG2;
[...]
> ```
> ?
> 
> I've tried various usages of `range.InputRangeObject` but haven't been
> able to get the syntax right.  Any suggestions on the best way to
> proceed?  Maybe the whole chain should be wrapped in InputRangeObject
> classes, I don't know.
[...]

Here's an actual function taken from my own code, that returns a
different range type depending on a runtime condition, maybe this will
help you?

```d
/**
 * Expands '@'-directives in a range of strings.
 *
 * Returns: A range of strings with lines that begin with '@'
 * substituted with the contents of the file named by the rest of the
 * line.
 */
auto expandFileDirectives(File = std.stdio.File, R)(R args)
if (isInputRange!R && is(ElementType!R : const(char)[]))
{
import std.algorithm.iteration : joiner, map;
import std.algorithm.searching : startsWith;
import std.range : only;
import std.range.interfaces : InputRange, inputRangeObject;
import std.typecons : No;

return args.map!(arg => arg.startsWith('@') ?
cast(InputRange!string) inputRangeObject(
File(arg[1 .. $]).byLineCopy(No.keepTerminator)) :
cast(InputRange!string) inputRangeObject(only(arg)))
   .joiner;
}
```

Note that the cast is to a common base class of the two different
subclasses returned by inputRangeObject().

This function is used in the rest of the code as part of a UFCS chain of
ranges.


T

-- 
Long, long ago, the ancient Chinese invented a device that lets them see 
through walls. It was called the "window".


Deciding one member of iteration chain at runtime

2023-02-17 Thread Chris Piker via Digitalmars-d-learn

Hi D

I have a main "loop" for a data processing program that looks 
much as follows:

```d
sourceRange
  .operatorA
  .operatorB
  .operatorC
  .operatorD
  .operatorE
  .operatorF
  .operatorG
  .operatorH
  .copy(destination);
```
Where all `operator` items above are InputRange structs that take 
an upstream range, and the pipeline really is 9 operations deep.


In order to handle new functionality it turns out that operatorG 
needs to be of one of two different types at runtime.  How would 
I do something like the following:


```d
auto virtualG;  // <-- probably invalid code, illustrating the 
idea

if(runtime_condition)
   virtualG = operatorG1;
else
   virtualG = operatorG2;

sourceRange
  .operatorA
  .operatorB
  .operatorC
  .operatorD
  .operatorE
  .operatorF
  .virtualG
  .operatorH
  .copy(destination);
```
?

I've tried various usages of `range.InputRangeObject` but haven't 
been able to get the syntax right.  Any suggestions on the best 
way to proceed?  Maybe the whole chain should be wrapped in 
InputRangeObject classes, I don't know.


Thanks,