13
\$\begingroup\$

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.

\$\endgroup\$
0

9 Answers 9

2
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ Accepting for now :) \$\endgroup\$
    – cat
    Commented Dec 27, 2016 at 16:56
  • \$\begingroup\$ Yeah, good to know there's still fans of D here. \$\endgroup\$
    – Adalynn
    Commented Dec 27, 2016 at 22:38
2
\$\begingroup\$

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. ;)

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
3
  • \$\begingroup\$ Does auto work when building an associative array with the KeyType[ValueType] syntax? \$\endgroup\$
    – Alex A.
    Commented Feb 27, 2016 at 23:30
  • \$\begingroup\$ @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 \$\endgroup\$
    – cat
    Commented Feb 27, 2016 at 23:39
  • \$\begingroup\$ @AlexA. auto arr = ["a": true, "b": 6]; works, the keys and values must be of compatible types \$\endgroup\$
    – cat
    Commented Feb 28, 2016 at 16:43
1
\$\begingroup\$

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

\$\endgroup\$
1
  • \$\begingroup\$ It's those dots \$\endgroup\$ Commented Feb 28, 2016 at 1:25
1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ Can you use char* in place of string to save a byte? \$\endgroup\$
    – Alex A.
    Commented Feb 28, 2016 at 1:36
  • \$\begingroup\$ @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++ \$\endgroup\$
    – cat
    Commented Feb 28, 2016 at 1:40
  • 1
    \$\begingroup\$ OIC. Never used D, just guessing. \$\endgroup\$
    – Alex A.
    Commented Feb 28, 2016 at 1:41
1
\$\begingroup\$

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

\$\endgroup\$
4
  • \$\begingroup\$ Function templates for golfing the types? T f(T)(T a,T b){return a + b} should infer T as int in f(5); \$\endgroup\$
    – fede s.
    Commented May 5, 2016 at 19:35
  • \$\begingroup\$ @fedes. Hello, friend! Yes, you are exactly correct (but I think/hope "untyped" lambdas will be shorter than typed function expressions). \$\endgroup\$
    – cat
    Commented May 5, 2016 at 19:48
  • \$\begingroup\$ 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 \$\endgroup\$
    – fede s.
    Commented May 5, 2016 at 19:52
  • \$\begingroup\$ @fedes. Aw, why thank you! :P that implies you do too (but I haven't spent enough time in front of Smalltalk, yet anyways :) ) \$\endgroup\$
    – cat
    Commented May 5, 2016 at 20:01
1
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
5
  • \$\begingroup\$ If the question ask to output an integer wouldn't int main(){return output} be shorter? \$\endgroup\$ Commented Feb 28, 2016 at 1:44
  • \$\begingroup\$ @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 \$\endgroup\$
    – cat
    Commented Feb 28, 2016 at 1:45
  • \$\begingroup\$ @dev-null however, yes, in that case that it should not be written to stdout but returned, it would be shorter \$\endgroup\$
    – cat
    Commented Feb 28, 2016 at 1:45
  • 3
    \$\begingroup\$ Usually you are allowed to return / output the most convenient way for your language. But I guess D only support exit codes from 0-255? \$\endgroup\$ Commented Feb 28, 2016 at 1:48
  • \$\begingroup\$ @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. \$\endgroup\$
    – cat
    Commented Feb 28, 2016 at 1:50
0
\$\begingroup\$

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.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.