www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Tuple unpacking example, and to!

reply bearophile <bearophileHUGS lycos.com> writes:
Once in a while it's positive to show simple usages and comparisons. This is a
little comparison that shows why tuple unpacking is handy, from real-life
programming.
This is just a little thing, but such things pile up one over the other to make
a language more handy than another one.


Python V.2.x:
foo, bar, baz = map(int, readline().split())


Python V.3.x:
foo, bar, baz = list(map(int, readline().split()))


D2 + Phobos:
long[] foo_bar_baz = array(map!(to!(long, string))(readln().split()));
assert(foo_bar_baz.length == 3);
long foo = foo_bar_baz[0];
long bar = foo_bar_baz[1];
long baz = foo_bar_baz[2];


If the to!() template arguments are split in two nested templates then that
code can compile with a syntax like this, that's  a bit more readable and
simpler to write:

long[] foo_bar_baz = array(map!(to!long)(readln().split()));


This test program works:

import std.stdio: writeln;
import std.conv: to;
import std.algorithm: array, map;

template to_(Tout) {
    Tout to_(Tin)(Tin x) {
        return to!(Tout, Tin)(x);
    }
}
void main() {
    string[] data = ["1", "2", "3"];
    int[] arr = array(map!(to_!int)(data));
    writeln(arr);
}


But then unfortunately when you want specify manually both types of to_ this
doesn't compile:

writeln((to_!(string))!(string)("10"));

DMD returns:
test.d(18): C style cast illegal, use cast(string)"10"
test.d(18): C style cast illegal, use cast(to_!(string))!cast(string)"10"


and you have to use an auxiliary alias:

alias to_!(int) to_int;
writeln(to_int!(string)("10"));


You can't solve this problem with an alias:

alias to to_;

That causes the error:
test.d(10): Error: alias test.to_ conflicts with template test.to_(Tout) at
test.d(5)


But this works:

import std.stdio: writeln;
import std.conv: to;
import std.algorithm: array, map;

template to_(Tout) {
    Tout to_(Tin)(Tin x) {
        return to!(Tout, Tin)(x);
    }
}
Tout to_(Tout, Tin)(Tin x) {
    return to!(Tout, Tin)(x);
}
void main() {
    string[] data = ["1", "2", "3"];
    int[] arr = array(map!(to_!int)(data));
    writeln(arr);
    writeln(to_!int("10"));
    writeln(to_!(int, string)("20"));
}


So I can suggest this as a little enhancement for Phobos2. (Later on this I can
even put a patch in Bugzilla).

Bye,
bearophile
May 08 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Doing the Google Code Jam with both Python and D shows me that both languages
are not optimal for this purpose (but both can be used).

Like other online programming contests this asks the programmer to invent
correctly working algorithms in a very short time. Some of the algorithms can
require multi-precision integers too, and generally you need a good amount of
brain power and focus to find the algorithm solutions. Often you are not smart
enough to find the solutions, so you are always on just one leg.

Compared to other online contests Google Code Jam is also data-driven: all
tests are divided in two parts, one with a small input set and one with a large
input set. A slow algorithm/language can be enough for the small data set, but
your algorithm and language must be fast if you want to find the answer in the
max time allowed (8 minutes).

Python is excellent to invent the algorithm that solves the problem, there is
no compilation stage (on the other hand the programs are usually small enough,
so with DMD the compilation time is quite small. So I think it's mostly a
psychological thing), there are no types that you have to put in the code that
can distract what you are doing, you don't have to import libs to do most
things, you can write very little code and build your solution progressively,
sometimes even starting from the interactive command line shell, and you have
much less things to worry about, like integer overflows, slicing arrays, etc.
The very clean syntax allows you to focus on just the semantics of the
algorithm.

D, especially D2 with Phobos2 is not bad, and it's fast enough, but when you
invent a new algorithm you want to give 101% of your brain to invention of the
algorithm that solves the problem, and not to problems like integer overflows,
unsafe slicing (slicing more than the length of the array, this is not a
problem in Python, but requires stupid extra tests in D), leading/trailing
spaces not ignored by the to!long, missing tuple unpacking, and so on and on.

So Python is good to invent the algorithm and write a working program, but
often even using Psyco it's often too much slow to give a fast enough solution
for the large data set. D is fast enough for the big data set, and it's not bad
for programming in general, but you need to put more brain in writing the D
code and you have to write more code and you quite often can put more bugs in
the code (for example caused by conversion from signed to unsigned numbers
because of a silly unsigned array length). And generally you don't want to
waste time to write a first solution in Python and to translate it to D2 to
solve the large data set.

I have seen people solve all problems in C++ in a short enough time, so maybe
all those problems are just mine, and I am just less intelligent/expert than
them. Yet, good tools can increase people "intelligence".

D and Python are not the only languages I know, but the others I know are even
less fit for purpose.

So to perform a contest like Google Code Jam I am unhappy with all languages I
currently know :-( Maybe the Boo language (for dotnet, but hopefully in future
for JavaVM too) can be fitter for this kind of contest.

Bye,
bearophile
May 09 2010
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
 So I can suggest this as a little enhancement for Phobos2. (Later on this I
can even put a patch in Bugzilla).
http://d.puremagic.com/issues/show_bug.cgi?id=4168
May 09 2010