why ; ?

bearophile bearophileHUGS at lycos.com
Mon May 5 08:08:06 PDT 2008


Tomasz Sowinski Wrote:

As you say such things of D probably aren't going to change, but with some careful design most (I think all) of those problems can be solved.
And you can even go all the way :-)

This is a little old D example code of mine:

import std.stdio, std.stream, std.string, std.ctype, std.gc;

void traduct(char[] n, char[] digits, int start, char[][] words, char[][][char[]] gdict) {
    if (start >= digits.length)
        writefln(n, ": ", words.join(" "));
    else {
        auto found_word = false;
        for(auto i = start; i < digits.length; i++)
            if (digits[start .. i+1] in gdict) {
                found_word = true;
                foreach(hit; gdict[digits[start .. i+1]])
                    traduct(n, digits, i+1, words ~ [hit], gdict);
            }
        if (!found_word && (!words || (words && !std.ctype.isdigit(words[words.length-1][0]))))
            traduct(n, digits, start+1, words ~ [digits[start..start+1]], gdict);
    }
}

void main() {
    std.gc.disable();
    auto gtable = maketrans("ejnqrwxdsyftamcivbkulopghzEJNQRWXDSYFTAMCIVBKULOPGHZ",
                            "0111222333445566677788899901112223334455666777888999");

    size_t line_start;
    char[][][char[]] gdict;
    auto input_dict = cast(char[])std.file.read("dictionary.txt");

    foreach (current_pos, c; input_dict)
        if (c == '\n') { // words with DOS newlines too
            auto word = input_dict[line_start .. current_pos].strip();
            // word isn't a string, it's just a reference (start-end index) to
            //   the input_dict string, despite being stripped.
            gdict[word.translate(gtable, "\"")] ~= word;
            line_start = current_pos+1;
        }
    auto word = input_dict[line_start .. input_dict.length].strip();
    if (word.length > 0)
        gdict[word.translate(gtable, "\"")] ~= word;

    foreach(char[] n; new BufferedFile("input.txt"))
        traduct(n, n.removechars("/-"), 0, [], gdict);
}


The alternative version without ; and braces may look unusual for C programmers:


import std.stdio, std.stream, std.string, std.ctype, std.gc

void traduct(char[] n, char[] digits, int start, char[][] words, char[][][char[]] gdict):
    if (start >= digits.length):
        writefln(n, ": ", words.join(" "))
    else:
        auto found_word = false
        foreach(i; range(start, digits.length)):
            if (digits[start .. i+1] in gdict):
                found_word = true
                foreach(hit; gdict[digits[start .. i+1]]):
                    traduct(n, digits, i+1, words ~ [hit], gdict)
        if (!found_word && (!words || (words && !std.ctype.isdigit(words[words.length-1][0])))):
            traduct(n, digits, start+1, words ~ [digits[start..start+1]], gdict)

void main():
    std.gc.disable()
    auto gtable = maketrans("ejnqrwxdsyftamcivbkulopghzEJNQRWXDSYFTAMCIVBKULOPGHZ",
                            "0111222333445566677788899901112223334455666777888999")

    char[][][char[]] gdict
    foreach(char[] w; new BufferedFile("dictionary.txt")):
        gdict[w.translate(gtable, "\"")] ~= w.dup

    foreach(char[] n; new BufferedFile("input.txt")):
        traduct(n, n.removechars("/-"), 0, [], gdict)


It seems some people have tried that:

http://www.imitationpickles.org/pyplus/
http://blog.micropledge.com/2007/09/nobraces/
http://micropledge.com/projects/nobraces

But they use very simple means, so they fail in certain situations.
To solve the problem better a pymeta (OMeta parser) may be useful:
http://washort.twistedmatrix.com/

Bye,
bearophile



More information about the Digitalmars-d mailing list