Thread overview
[Issue 17593] __POS__ magical constant like __FILE__ and friends
Jul 05, 2017
Vladimir Panteleev
Jul 05, 2017
Eyal
Jul 05, 2017
b2.temp@gmx.com
Jul 05, 2017
Vladimir Panteleev
Jul 05, 2017
b2.temp@gmx.com
Dec 17, 2022
Iain Buclaw
July 05, 2017
https://issues.dlang.org/show_bug.cgi?id=17593

Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dlang-bugzilla@thecybershad
                   |                            |ow.net

--- Comment #1 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
I think such an enhancement could use some more background.

When would you find it useful, and how are the existing tools insufficient to warrant a change in the language?

Right now, you can use:

- string mixins, i.e.:
    Pos pos = mixin(mixPos);
  where
    enum mixPos = q{ Pos(__FILE__, __MODULE__, __LINE__) };

- The property of __FILE__/__LINE__ etc. that as default arguments, they are
evaluated at the call site:
    Pos pos = getPos();
  where
    Pos getPos(string f=__FILE__, string m=__MODULE__, int l=__LINE__)
    { return Pos(f, m, l); }

- As above, but also for template arguments, not just runtime function
arguments:
    Pos pos = currentPos!();
  where
    enum Pos currentPos(string f=__FILE__, string m=__MODULE__, int l=__LINE__)
= Pos(f, m, l);

(I haven't tested the above, but I think they should work.)

--
July 05, 2017
https://issues.dlang.org/show_bug.cgi?id=17593

--- Comment #2 from Eyal <eyal@weka.io> ---
I tested the mixin approach before filing this. It doesn't work:

struct Pos { size_t line; }
void foo(size_t line=__LINE__, Pos pos=Pos(__LINE__))() { .. }

line is caller's line. pos.line is foo's decl line.

The reason I want this enhancement is that we have a logging framework that uses the line numbers in compile-time (to make fast logs that log very minimally at runtime).

I often want to create log-line wrappers for specific cases.

Currently I have to do this:

void myLogger(string fmt, string file=__FILE__, string mod=__MODULE__, size_t
line=__LINE__, Args...)(auto ref Args args) {
    log!("my extra stuff" ~ fmt, file, mod, line)(myExtraArgs, args);
}

And this has to be repeated, verbatim, for every log wrapper in existence.

It is quite a big discouragement against writing functions that work and pass on code positions.

Much nicer:

void myLogger(string fmt, Pos pos=__POS__) {
    log!("my extra stuff" ~ fmt, pos)(myExtraArgs, args);
}

Almost as nice:

void myLogger(string fmt, Pos pos=mixin(POS)) ...

So alternatively to adding __POS__, dmd could be fixed so that __LINE__ is based on its *lexical* position. i.e: same value for __LINE__ in a default CT param value and when it is given to Pos() inside a default CT param value.

--
July 05, 2017
https://issues.dlang.org/show_bug.cgi?id=17593

b2.temp@gmx.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |b2.temp@gmx.com

--- Comment #3 from b2.temp@gmx.com ---
I manage to make the feature working with a tuple after a quick hacking session, with this code that compiles and runs and then displays the expected result:

====
module runnable;

import std.stdio, std.typecons;

void foo(Tuple!(string, string, int) p = __POS__)
{
    writeln(p);
}

void main(string[] args)
{
    writeln(__POS__[0]);
    writeln(__POS__[1]);
    writeln(__POS__[2]);
    foo();
}
====

actually more can be added to the tuple. (here it's the equivalent of __FILE__, __MODULE__ then __LINE__) since __PRETTY_FUNCTION__ is also important for logging.


If DMD people agree on the principle of the feature I'm not against proposing a PR. Also with a small bounty as motivation if possible.

--
July 05, 2017
https://issues.dlang.org/show_bug.cgi?id=17593

--- Comment #4 from Vladimir Panteleev <dlang-bugzilla@thecybershadow.net> ---
(In reply to Eyal from comment #2)
> So alternatively to adding __POS__, dmd could be fixed so that __LINE__ is based on its *lexical* position. i.e: same value for __LINE__ in a default CT param value and when it is given to Pos() inside a default CT param value.

That seems like the way to go here IMO. As described, __POS__ seems a bit too specific to your logging framework, whereas the above should be a more universal improvement.

--
July 05, 2017
https://issues.dlang.org/show_bug.cgi?id=17593

b2.temp@gmx.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|b2.temp@gmx.com             |

--- Comment #5 from b2.temp@gmx.com ---
The tuple solution while working is not ideal, tuple type is not infered so it cannot be upgraded automatically if the internal DMD tuple member changes.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=17593

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P4

--