Thread overview
Would this function benefit from functional programming?
Nov 21
monkyyy
Nov 21
monkyyy
November 21

I use this pattern very frequently throughout my code

void displayHex()
{
    foreach(r; 0..rows)
    {
        foreach(c; 0..columns)
        {
            writeln("...");
            foreach(p; 0..6)
            {
                writeln("...");
            }
        }
    }
}

And I was wondering if it would be worthwhile to convert it to functional programming. I saw a talk by Mr. Bright who did something like, a.c.d(3).e.f

But his example was understandably terse. I believe the map function can take the place of the foreaches? Also I've been unable to find examples of writeln being used. I'm not interested in speeding up the code or making it more understandable. Just making it more compact. Maybe what I'm really asking is if functional programming is not appropriate in all scenarios.

November 21

On Thursday, 21 November 2024 at 00:34:50 UTC, WhatMeWorry` wrote:

>

I use this pattern very frequently throughout my code

void displayHex()
{
    foreach(r; 0..rows)
    {
        foreach(c; 0..columns)
        {
            writeln("...");
            foreach(p; 0..6)
            {
                writeln("...");
            }
        }
    }
}

And I was wondering if it would be worthwhile to convert it to functional programming. I saw a talk by Mr. Bright who did something like, a.c.d(3).e.f

But his example was understandably terse. I believe the map function can take the place of the foreaches? Also I've been unable to find examples of writeln being used. I'm not interested in speeding up the code or making it more understandable. Just making it more compact. Maybe what I'm really asking is if functional programming is not appropriate in all scenarios.

row.iota.each!(
   cols.iota.each!((c){
     writeln("...");
     iota(6).each!(a=>writeln("..."));
})});

iota is a bad name for counter, and map has an unnecessary restriction on void functions; but this is a travail conversion

November 21

On Thursday, 21 November 2024 at 00:34:50 UTC, WhatMeWorry` wrote:

>

Maybe what I'm really asking is if functional programming is not appropriate in all scenarios.

Heres a rule of thumb: Avoid functional programming if you should use goto

November 21

On Thursday, 21 November 2024 at 00:34:50 UTC, WhatMeWorry` wrote:

>

I use this pattern very frequently throughout my code

We can't help you by seeing your pseudocode. Because when we look at your code, instead of 3 loops, 2 loops or even a single loop using HOFs is enough. I'm posting the following pieces of code in case it helps someone:

import std;
enum { rows = 1, columns = 2 }

void main()
{
  // with HOFs
  iota(rows * columns).each!(c => repeat("...",6).writefln!"...\n%-(%s\n%)");

  displayX(); // equivalent
}

Equivalent:

void displayX()
{
  foreach(c; 0..rows * columns)
  {
    writeln("title");
    foreach(p; 0..6)
    {
      writeln("lines");
    }
  }
}

SDB@79

November 21

On Thursday, 21 November 2024 at 00:34:50 UTC, WhatMeWorry` wrote:

>

Just making it more compact.

Python itertools has product, I use it from time to time and it can definitely make code more compact.

auto product(R1, R2)(R1 r1, R2 r2)
{
    return r1.map!((i) => zip(repeat(i), r2.save())).joiner()
}

product(iota(rows), iota(columns).each!(bind!( (row, col){
  // Do stuff with the values
}

foreach(row, col; product(iota(rows), iota(columns)){...}

It's debatable whether this is nicer, especially when D still has suboptimal tuple support and boilerplate like 'bind' is needed, but it might be worth thinking about when you can chain more than a simple each call behind it.