Thread overview
Alternative to C++ macro in D
Nov 03
Meta
November 03
Hi all,
I can do this in C++.
#include <iostream>
using namespace std ;

#define end };
#define log(x)  cout << x << endl
#define wait std::cin.get()


int main() {
    log("Trying to avoid the visual clutter aused by closing curly braces") ;
    string myStr = "Now, code looks more elegant" ;
    log(myStr) ;
    wait ;
end
How can i do this in D ? Especially the " #define end }; ". I've tried " alias end = } " but didn't worked.
Edit : How can add syntax highlighting and coloring in code posted on this comment ?
November 03
On Sunday, 3 November 2019 at 16:55:36 UTC, Vinod K Chandran wrote:
> Hi all,
> I can do this in C++.
> #include <iostream>
> using namespace std ;
>
> #define end };
> #define log(x)  cout << x << endl
> #define wait std::cin.get()
>
>
> int main() {
>     log("Trying to avoid the visual clutter aused by closing curly braces") ;
>     string myStr = "Now, code looks more elegant" ;
>     log(myStr) ;
>     wait ;
> end
> How can i do this in D ? Especially the " #define end }; ". I've tried " alias end = } " but didn't worked.
> Edit : How can add syntax highlighting and coloring in code posted on this comment ?

How can i edit my post ? There is no button or link to edit my post.
November 03
On Sunday, 3 November 2019 at 17:02:30 UTC, Vinod K Chandran wrote:
> On Sunday, 3 November 2019 at 16:55:36 UTC, Vinod K Chandran wrote:
>> Hi all,
>> I can do this in C++.
>> #include <iostream>
>> using namespace std ;
>>
>> #define end };
>> #define log(x)  cout << x << endl
>> #define wait std::cin.get()
>>
>>
>> int main() {
>>     log("Trying to avoid the visual clutter aused by closing curly braces") ;
>>     string myStr = "Now, code looks more elegant" ;
>>     log(myStr) ;
>>     wait ;
>> end
>> How can i do this in D ? Especially the " #define end }; ". I've tried " alias end = } " but didn't worked.
>> Edit : How can add syntax highlighting and coloring in code posted on this comment ?
>
> How can i edit my post ? There is no button or link to edit my post.

You can't, web version is just a frontend for mailing list.

Best regards,
Alexandru.
November 03
On Sunday, 3 November 2019 at 16:55:36 UTC, Vinod K Chandran wrote:
> Hi all,
> I can do this in C++.
> #include <iostream>
> using namespace std ;
>
> #define end };
> #define log(x)  cout << x << endl
> #define wait std::cin.get()
>
>
> int main() {
>     log("Trying to avoid the visual clutter aused by closing curly braces") ;
>     string myStr = "Now, code looks more elegant" ;
>     log(myStr) ;
>     wait ;
> end
> How can i do this in D ? Especially the " #define end }; ". I've tried " alias end = } " but didn't worked.
> Edit : How can add syntax highlighting and coloring in code posted on this comment ?

If this is about logging functionality, check std.experimental.log package, it contains all necessary logging functionality.

About macros there aren't any similar to preprocessor macros in c/c++, however you can replace them with three options depending on your needs:

1. Just a simple function in conjunction eith ctfe: https://tour.dlang.org/tour/en/gems/compile-time-function-evaluation-ctfe
2. string mixins: https://dlang.org/articles/mixin.html
3. template mixins: https://dlang.org/spec/template-mixin.html

I'd say number 2 should be suitable for your example given you'd like to inject statements into body of some function.

Best regards,
Alexandru.
November 03
On Sunday, 3 November 2019 at 16:55:36 UTC, Vinod K Chandran wrote:
> int main() {
>     log("Trying to avoid the visual clutter aused by closing curly braces") ;
>     string myStr = "Now, code looks more elegant" ;
>     log(myStr) ;
>     wait ;
> end
> How can i do this in D ? Especially the " #define end }; ". I've tried " alias end = } " but didn't worked.

You can't. D deliberately doesn't have a preprocessor. `#define end };` is one of the reasons.
November 03
On Sunday, 3 November 2019 at 16:55:36 UTC, Vinod K Chandran wrote:
> Hi all,
> I can do this in C++. #include <iostream>
> using namespace std ;
>
> #define end };
> #define log(x)  cout << x << endl
> #define wait std::cin.get()
>
>
> int main() {
>     log("Trying to avoid the visual clutter aused by closing curly braces") ;
>     string myStr = "Now, code looks more elegant" ;
>     log(myStr) ; mixin template cToD(string code)

`log` and `wait` are straightforward. Just write a function:

import std.stdio;
void log(T)(T x) { writeln(x); }
void wait() { readln(); }

However, you can't do things like `#define end }`. The D language intentionally disallows doing stuff like this. If you *really* want to do this, you can sort of emulate it with mixins:

mixin template cToD(string code)
{
    import std.array: replace;
    mixin(code.replace("end", "}"));
}

mixin cToD!`
    int main() {
        log("Trying to avoid the visual clutter aused by closing curly braces") ;
        string myStr = "Now, code looks more elegant" ;
        log(myStr) ;
        wait ;
        return 0;
    end
`;

But I would strongly recommend against it.
November 03
On 11/03/2019 08:55 AM, Vinod K Chandran wrote:
> Hi all,
> I can do this in C++.
> #include <iostream>
> using namespace std ;
>
> #define end };
> #define log(x)  cout << x << endl
> #define wait std::cin.get()

There is nothing that stops one from using the C++ preprocessor on any text file. For example, you can do the following wherever GCC exists. If there are the following lines in a D file:

#define XYZ 42

auto a = XYZ;

Then you can pass it through the preprocessor like this:

  cpp foo.d

In fact, that's one of the tricks dpp uses to make C++ headers usable in D code:

  https://github.com/atilaneves/dpp

As you can see above, compile-time constants are defined with 'enum' in D:

enum XYZ = 42;

auto a = XYZ;

Beware though: Do not do that with arrays though, as every usage of an 'enum' array causes dynamic memory allocation at run time.

enum myConstants = [ 1, 2 ];

bool foo(int i) {
  import std.algorithm : canFind;
  return myConstants.canFind(i);    // <-- DON'T DO THIS
}

In addition to the enum version of an array (which you may need to use e.g. with 'static foreach') , also use a run-time initialized array:

// Use this e.g. for 'static foreach'
enum myConstants_enum = [ 1, 2 ];

// Use this for run-time code
immutable int[] myConstants;
shared static this() {
  // This is the initialization of the immutable array:
  myConstants = myConstants_enum;
}

bool foo(int i) {
  import std.algorithm : canFind;
  return myConstants.canFind(i);    // <-- DO THIS
}

Even though I've known about this gotcha, this wisdom comes from profiling my program by compiling with dmd's '-profile=gc' option. It was pretty obvious in the generated 'profilegc.log' file that I was causing such unnecessary memory allocations.

Ali

2 days ago
On Monday, 4 November 2019 at 00:20:37 UTC, Ali Çehreli wrote:
> On 11/03/2019 08:55 AM, Vinod K Chandran wrote:
> > [...]
>
> There is nothing that stops one from using the C++ preprocessor on any text file. For example, you can do the following wherever GCC exists. If there are the following lines in a D file:
>
> [...]

Sorry for the delayed reply. Thanks a lot for the hints.