Tips for golfing in D2

10

3

What general tips do you have for golfing in D? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to D (e.g. "remove comments" is not an answer). Please post one tip per answer.

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

Answers

1

Look, no parens!

D's functions and template functions can be called as values, methods (won't help), and properties.

I can't believe no one has said this yet. I'll list the ones that save bytes:

  • fun() and fun!()() shorten to fun (assuming there is no variable fun).
  • fun(par) shortens to par.fun (assuming par has no property/method fun, as well as par not being an expression like 5+2).
  • fun!(T)() shortens to fun!T
  • fun!(T)(par) shortens to par.fun!T (assuming par has no property/method fun)

And with objects:

  • new cls() shortens to new cls (More JavaScript anyone?)
  • obj.fun() and obj.fun!()() shorten to obj.fun
  • obj.fun!(T)() shortens to obj.fun!T

One final thing, use old versions. It allows you to use deprecated features that shorten your code. That said, best advice: D isn't good for code-golf. It is a great language, just not for code-golf.

Zacharý

Posted 2016-02-27T23:13:07.447

Reputation: 5 710

Accepting for now :) – cat – 2016-12-27T16:56:59.043

Yeah, good to know there's still fans of D here. – Zacharý – 2016-12-27T22:38:49.680

1

D is JavaScript.


Obviously not. But, when dealing with float, double and real, nan is a value which must be handled, and, as specified by IEEE 754, NaN does not compare equal with itself.

writeln(double.nan == double.nan); // false

Meaning,

writeln(value!=value); // only true for nan

is way shorter than

import std.math;
writeln(isNaN(value));

Obviously, always use math.isNaN for real code. ;)

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

0

D has type inference and an auto keyword. If the object is not int, then auto is probably shorter.

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

Does auto work when building an associative array with the KeyType[ValueType] syntax? – Alex A. – 2016-02-27T23:30:14.517

@AlexA. auto asd = ["a":1, "b": 2]; works, but since KeyType[ValueType] would go in the place of the auto keyword, I don't know if that will always work with types for which literals can't be constructed – cat – 2016-02-27T23:39:03.930

@AlexA. auto arr = ["a": true, "b": 6]; works, the keys and values must be of compatible types – cat – 2016-02-28T16:43:58.537

0

If the question requires a full program, the module declaration is surprisingly unnecessary.

*cough* Java, anyone? *clears throat* Actually, D's module system is older than Java's.

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

0

D is great at method chaining, but:

str.toLower.strip().split("").sort();

is the same as

sort(split(strip(str.toLower),""));

and usually the non-chained one is shorter, which I just realised, which lets me shorten my answer to Manage Trash So :D

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

It's those dots – CalculatorFeline – 2016-02-28T01:25:51.327

0

Like C/C++, main can be int or void, but void main(){} will always be shorter than int main(){return my_func_returning_int;}.

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

If the question ask to output an integer wouldn't int main(){return output} be shorter? – andlrc – 2016-02-28T01:44:28.123

@dev-null if the question asks for a full program writing an integer to stdout then import std.stdio;void main(){write(7);} is what's needed. I doubt a question would mandate the program return a number because many languages can't set return codes – cat – 2016-02-28T01:45:07.513

@dev-null however, yes, in that case that it should not be written to stdout but returned, it would be shorter – cat – 2016-02-28T01:45:40.747

2Usually you are allowed to return / output the most convenient way for your language. But I guess D only support exit codes from 0-255? – andlrc – 2016-02-28T01:48:08.593

@dev-null actually, POSIX only supports exit codes up to 255. I don't know about Windows, but on Unix / Linux an exit code over 255 wraps around, because of overflow. – cat – 2016-02-28T01:50:23.480

0

D, as a multiparadigm (Object Functional) systems programming language, seems to embrace TIMTOWTDI, or There Is More Than One Way To Do It.

Case in point, writing the program's argv:

import std.stdio, std.array, std.algorithm;

void main(string[] args) {
    for(int i=0;i<args.length;writeln(args[i++])){};

    foreach(a;args)writeln(a);

    each!writeln(args);
}

Note the C-style for-loop requires {} as the empty block and will not accept a semicolon or nothing as a blank statement, in this case. Usually, or ; are no-ops.

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

Can you use char* in place of string to save a byte? – Alex A. – 2016-02-28T01:36:20.657

@AlexA. function D main parameters must be main() or main(string[] args) moreover, char is literally one character, char* is a pointer to literally one character and char[] is an array of character literals (strings are different). D != C || C++ – cat – 2016-02-28T01:40:22.607

1OIC. Never used D, just guessing. – Alex A. – 2016-02-28T01:41:43.577

0

D has a few types of C#-style lambda expressions, which can be assigned and stand alone:

(int a,int b)=>a*b;

auto a=(int a,int b)=>a*b;

However, unlike C#, the signature's types are still needed because D doesn't have Haskell-level type inferencing.

https://dlang.org/spec/expression.html#Lambda

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

Function templates for golfing the types? T f(T)(T a,T b){return a + b} should infer T as int in f(5); – fede s. – 2016-05-05T19:35:29.933

@fedes. Hello, friend! Yes, you are exactly correct (but I think/hope "untyped" lambdas will be shorter than typed function expressions). – cat – 2016-05-05T19:48:39.620

Ah, ofc! When I decide to take yet another look on D, who do I find? :D I objectively declare you have good taste on languages – fede s. – 2016-05-05T19:52:44.217

@fedes. Aw, why thank you! :P that implies you do too (but I haven't spent enough time in front of Smalltalk, yet anyways :) ) – cat – 2016-05-05T20:01:30.037

0

Calling a function on an object with no other arguments

reverse(x);

can nearly always be shortened to

x.reverse;

to shave a byte or more.

This is because the . makes the LHS an implicit first argument, and templating lets us choose the right function for the args.

cat

Posted 2016-02-27T23:13:07.447

Reputation: 4 989

Dots are good? This is confusing... – CalculatorFeline – 2016-03-03T03:14:23.867

@CatsAreFluffy when there are no args. When there's another argument, the x.reverse(y, z) is longer because of the dot – cat – 2016-03-03T14:37:11.553

1x.reverse(y,z) and reverse(x,y,z) have the same byte count. – Zacharý – 2016-11-08T21:13:18.533

@ZacharyT Uh, yeah... – cat – 2016-11-08T21:36:08.973

Were you comparing x.reverse(y, z) to x.reverse? – Zacharý – 2016-11-08T21:44:20.107

@ZacharyT I believe I was comparing counting sheep to a lack of coffee -- that is, it was probably me not thinking properly ;) – cat – 2016-11-08T21:47:25.173