coreutils with D trials, wc, binary vs well formed utf

btiffin btiffin at myopera.com
Tue May 25 19:05:33 UTC 2021


On Tuesday, 25 May 2021 at 18:03:29 UTC, Imperatorn wrote:

> Nice that you're also hopeful about the future for D ☀️ I also 
> think slow steady growth is the best.
>
> We just need to focus and D will be great 🍀

D is already great. It just needs to take over (a larger chunk 
of) the world. ;-)

Now for some more noob level questions.  I modified Robert's 
entry to include totals.

(Gee, I hope I'm not stepping into copyright issues - the code 
has no explicit license, and I've haven't yet figured out what 
the default assumption is in the dlang.org terms of service.  If 
this is stepping out of bounds, I'll edit out the copied sources).

```d
/++ wc word counting +/
/+ Tectonics: gdc -o wc wc.d +/
module wc;

import std.stdio : writefln, File;
import std.algorithm : map, fold, splitter;
import std.range : walkLength;
import std.typecons : Yes;
import std.uni : byCodePoint;

struct Line {
    size_t chars;
    size_t words;
}

struct Output {
    size_t lines;
    size_t words;
    size_t chars;
}

Output combine(Output a, Line b) pure nothrow {
    return Output(a.lines + 1, a.words + b.words, a.chars + 
b.chars);
}

//Line toLine(char[] l) pure {
//   return Line(l.byCodePoint.walkLength, l.splitter.walkLength);
//}

Line toLine(char[] l) pure {
    import std.array : array;
    import std.algorithm : filter;
    import std.utf : byDchar, replacementDchar;

    auto valid = l.byDchar.filter!(c => c!=replacementDchar).array;
    return Line(valid.byCodePoint.walkLength, 
valid.splitter.walkLength);
}

void main(string[] args) {
    Output tot;

    foreach (int i, string fn; args) {
        if (i == 0) continue;
        auto f = File(fn);
        Output o = f
          .byLine(Yes.keepTerminator)
          .map!(l => toLine(l))
          .fold!(combine)(Output(0, 0, 0));

        writefln!"%7u %7u %11u %s"(o.lines, o.words, o.chars, fn);

        tot.lines += o.lines;
        tot.words += o.words;
        tot.chars += o.chars;
    }
    if (args.length > 2) {
        writefln!"%7u %7u %11u %s"(tot.lines, tot.words, 
tot.chars, "total");
    }
}
```

This is no longer a branchless piece of code, but still a joy to 
toyol with.

Oh, and a by the by.  I use a portmanteau of *toy* and *tool* for 
*toyol*.  A toy tool toiled for the joy of it. *because inventing 
words is fun*.

I also like to add a Tectonics line to sources; the commands used 
to build given the source listing, using this rather archaic 
definition of tectonics from the dict databases.

```text
"Tectonics" gcide "The Collaborative International Dictionary of 
English v.0.48"
Tectonics \Tec*ton"ics\, n.
1. The science, or the art, by which implements, vessels,
dwellings, or other edifices, are constructed, both
agreeably to the end for which they are designed, and in
conformity with artistic sentiments and ideas.
[1913 Webster]
```

One last by the by, I usually go by the nickname Bluey, and sign 
as Blue.

The question.  Is there a more concise D idiom for adding the 
Output struct fields into the total?  Or is it three separate 
statements?

Ok, one more question.  Can the foreach loop that scans the 
argument list be folded into a chain somehow?  *I'm not there yet 
in D learning, but might as well try and choose an idiomatic 
path, if possible*.

Have good,
Blue


More information about the Digitalmars-d-learn mailing list