D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 9306 - __function alias
Summary: __function alias
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords: pull
Depends on:
Blocks:
 
Reported: 2013-01-12 13:46 UTC by bearophile_hugs
Modified: 2022-09-08 10:04 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2013-01-12 13:46:15 UTC
This is a spinoff of Issue 5140 , see there for more info and discussions.

Inside a function __function (or __func) is the alias to the function itself. It allows code like this, this recursive code will keep working even if "fact" gets renamed, it's more DRY (http://en.wikipedia.org/wiki/Don%27t_Repeat_Yourself ):


long fact(long n) {
    if (n <= 1)
        return 1;
    else
        return n * __function(n - 1);
}
void main() {
    assert(fact(20) == 2_432_902_008_176_640_000);
}



See a better explanations and some examples of __function:
http://rosettacode.org/wiki/Anonymous_recursion


It's like the difference between D OOP and Java, this is Java-like code:

class Foo {
    Foo(int x) {...}
    void bar(Foo f) {
        Foo g = new Foo(5);
        ...
    }
}


This is one possible equivalent D code, it contains the name Foo only once:

class Foo {
    this(int x) {...}
    void bar(typeof(this) f) {
        auto g = new typeof(this)(5);
        ...
    }
}


Another use case for __function:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=26404
Comment 1 basile-z 2017-02-26 03:19:28 UTC
It's easy to do at the library level:

auto recursion(string Fun = __FUNCTION__ , A...)(auto ref A a)
{
    import std.typecons: tuple;
    mixin("return " ~ Fun ~ "(" ~ a.stringof ~ "[0..$]);");
}

used like this:

long factorial(long a)
{
    if (a <= 1)
        return a;
    else
        return a * recursion (a-1);
}

void main()
{
    auto a = factorial(20);
}

So maybe this one could be closed as WONTFIX ?
Comment 2 Dlang Bot 2020-08-09 10:29:14 UTC
@NilsLankila updated dlang/dmd pull request #11538 "add `__traits(getCurrentFunction)`" fixing this issue:

- fix issue 8109, 9306, add `__traits(getCurrentFunction)`
  
  This new traits is a shortcut allowing to call the function we
  are in without using `mixin` and `__FUNCTION__` tricks.

https://github.com/dlang/dmd/pull/11538