Re: Extend the call site default argument expansion mechanism?

2018-05-16 Thread Nick Treleaven via Digitalmars-d

On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:

auto opDispatch(string s)()
if (s == "bar")


In case anyone isn't aware, this is better written:

auto opDispatch(string s : "bar")()


Re: Extend the call site default argument expansion mechanism?

2018-05-16 Thread Simen Kjærås via Digitalmars-d

On Wednesday, 16 May 2018 at 10:51:51 UTC, jmh530 wrote:

On Wednesday, 16 May 2018 at 09:01:29 UTC, Simen Kjærås wrote:

snip]

struct Foo(int x)
{
int n = x;
auto opDispatch(string s)()
if (s == "bar")
{
n++;
return n;
}
}


unittest
{
int y = 0;
with(Foo!1())
{
y = bar; // Works!
}
assert(y == 2);
}

--
  Simen


Thanks for catching that. Any idea why the original was having 
problems?


Seems to me there's an issue with overload priority - we expect 
opDispatch to count before globals, but it doesn't. Filed an 
issue: https://issues.dlang.org/show_bug.cgi?id=18866


--
  Simen


Re: Extend the call site default argument expansion mechanism?

2018-05-16 Thread jmh530 via Digitalmars-d

On Wednesday, 16 May 2018 at 09:01:29 UTC, Simen Kjærås wrote:

snip]

struct Foo(int x)
{
int n = x;
auto opDispatch(string s)()
if (s == "bar")
{
n++;
return n;
}
}


unittest
{
int y = 0;
with(Foo!1())
{
y = bar; // Works!
}
assert(y == 2);
}

--
  Simen


Thanks for catching that. Any idea why the original was having 
problems?


Re: Extend the call site default argument expansion mechanism?

2018-05-16 Thread Simen Kjærås via Digitalmars-d

On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:
On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer 
wrote:

[snip]

It seems opDispatch isn't being used in the with statement. 
That seems like a bug, or maybe a limitation. I'm not sure how 
"with" works, but I assumed it would try calling as a member, 
and then if it doesn't work, try the call normally. Probably 
it's checking to see if it has that member first.


Annoying...

-Steve


Looks like with statements ignore opDispatch.

struct Foo(int x)
{
auto opDispatch(string s)()
if (s == "bar")
{
return x++;
}
}


void main()
{
int y = 0;
with(Foo!1)
{
y = bar; //error: undefined identifier bar
}
assert(y == 2);
}


You've got bugs in your code: ++x has to fail for the template 
case, since you're trying to increment a compile-time value. This 
is what the call to bar is lowered to:


Foo!1.opDispatch!"bar"()

When you try and compile that, you get these error messages:

Error: cannot modify constant 1
Error: template instance `foo.Foo!1.Foo.opDispatch!"bar"` error 
instantiating


In addition, the with-statement in your code refers to the type 
Foo!1, not an instance of it. Fixed code:


struct Foo(int x)
{
int n = x;
auto opDispatch(string s)()
if (s == "bar")
{
n++;
return n;
}
}


unittest
{
int y = 0;
with(Foo!1())
{
y = bar; // Works!
}
assert(y == 2);
}

--
  Simen


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Computermatronic via Digitalmars-d

On Tuesday, 15 May 2018 at 20:31:14 UTC, jmh530 wrote:

On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:

[snip]



Note, it's not an issue if Foo were not a struct. This was 
fixed in Bug 6400 [1]l. The issue is with template instances. I 
have filed a new enhancement request [2]


[1] https://issues.dlang.org/show_bug.cgi?id=6400
[2] https://issues.dlang.org/show_bug.cgi?id=18863


Interestingly, you can get pretty close with a struct nested in a 
template function, however it seems that overload resolution does 
not check opDispatch if a public symbol of the same name exists.


this (https://run.dlang.io/is/ZzfWDs) dosen't work, but this 
(https://run.dlang.io/is/7zvfqc) does (notice SList & DList are 
not directly visible).


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread jmh530 via Digitalmars-d

On Tuesday, 15 May 2018 at 15:02:36 UTC, jmh530 wrote:

[snip]



Note, it's not an issue if Foo were not a struct. This was fixed 
in Bug 6400 [1]l. The issue is with template instances. I have 
filed a new enhancement request [2]


[1] https://issues.dlang.org/show_bug.cgi?id=6400
[2] https://issues.dlang.org/show_bug.cgi?id=18863


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread jmh530 via Digitalmars-d
On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer 
wrote:

[snip]

It seems opDispatch isn't being used in the with statement. 
That seems like a bug, or maybe a limitation. I'm not sure how 
"with" works, but I assumed it would try calling as a member, 
and then if it doesn't work, try the call normally. Probably 
it's checking to see if it has that member first.


Annoying...

-Steve


Looks like with statements ignore opDispatch.

struct Foo(int x)
{
auto opDispatch(string s)()
if (s == "bar")
{
return x++;
}
}


void main()
{
int y = 0;
with(Foo!1)
{
y = bar; //error: undefined identifier bar
}
assert(y == 2);
}


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Meta via Digitalmars-d
On Tuesday, 15 May 2018 at 14:52:46 UTC, Steven Schveighoffer 
wrote:
Sadly with(WithAlloc!alloc) doesn't work. (If you have to use 
withAlloc.func everywhere, it kind of destroy the point, 
doesn't it?)


It seems opDispatch isn't being used in the with statement. 
That seems like a bug, or maybe a limitation. I'm not sure how 
"with" works, but I assumed it would try calling as a member, 
and then if it doesn't work, try the call normally. Probably 
it's checking to see if it has that member first.


Annoying...

-Steve


Yeah I tried it with opDispatch but it didn't work. I vaguely 
remember some changes being made to how lookup is done in the 
past year or so... but I can't find the PR in question.


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Steven Schveighoffer via Digitalmars-d

On 5/15/18 10:26 AM, Yuxuan Shui wrote:

On Tuesday, 15 May 2018 at 13:59:37 UTC, jmh530 wrote:

On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer wrote:

[snip]

Hm... neat idea. Somehow, opDispatch can probably be used to make 
this work even more generically (untested):


struct WithAlloc(alias alloc)
{
   auto opDispatch(string s, Args...)(auto ref Args args) if 
(__traits(compiles, mixin(s ~ "(args, alloc)")))

   {
  mixin("return " ~ s ~ "(args, alloc);");
   }
}

-Steve


Example:
https://run.dlang.io/is/RV2xIH


Sadly with(WithAlloc!alloc) doesn't work. (If you have to use 
withAlloc.func everywhere, it kind of destroy the point, doesn't it?)


It seems opDispatch isn't being used in the with statement. That seems 
like a bug, or maybe a limitation. I'm not sure how "with" works, but I 
assumed it would try calling as a member, and then if it doesn't work, 
try the call normally. Probably it's checking to see if it has that 
member first.


Annoying...

-Steve


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread jmh530 via Digitalmars-d

On Tuesday, 15 May 2018 at 14:26:48 UTC, Yuxuan Shui wrote:

[snip]
Example:
https://run.dlang.io/is/RV2xIH


Sadly with(WithAlloc!alloc) doesn't work. (If you have to use 
withAlloc.func everywhere, it kind of destroy the point, 
doesn't it?)


Yeah I know, I tried it, but couldn't figure out how to do the 
with statement with it.


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 15 May 2018 at 13:59:37 UTC, jmh530 wrote:
On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer 
wrote:

[snip]

Hm... neat idea. Somehow, opDispatch can probably be used to 
make this work even more generically (untested):


struct WithAlloc(alias alloc)
{
   auto opDispatch(string s, Args...)(auto ref Args args) if 
(__traits(compiles, mixin(s ~ "(args, alloc)")))

   {
  mixin("return " ~ s ~ "(args, alloc);");
   }
}

-Steve


Example:
https://run.dlang.io/is/RV2xIH


Sadly with(WithAlloc!alloc) doesn't work. (If you have to use 
withAlloc.func everywhere, it kind of destroy the point, doesn't 
it?)


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread jmh530 via Digitalmars-d
On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer 
wrote:

[snip]

Hm... neat idea. Somehow, opDispatch can probably be used to 
make this work even more generically (untested):


struct WithAlloc(alias alloc)
{
   auto opDispatch(string s, Args...)(auto ref Args args) if 
(__traits(compiles, mixin(s ~ "(args, alloc)")))

   {
  mixin("return " ~ s ~ "(args, alloc);");
   }
}

-Steve


Example:
https://run.dlang.io/is/RV2xIH


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Steven Schveighoffer via Digitalmars-d

On 5/15/18 7:53 AM, Yuxuan Shui wrote:

On Friday, 11 May 2018 at 18:55:03 UTC, Meta wrote:

On Friday, 11 May 2018 at 15:03:41 UTC, Uknown wrote:

[...]


It's not as pretty, and I don't know if it works outside this toy 
example yet, but you can do:


import std.stdio;

struct Allocator
{
    auto call(alias F, Args...)(Args args)
    {
    return F(this, args);
    }

    void deallocateAll()
    {
    writeln("deallocateAll");
    }
}

void f1(Allocator a, int n) { writeln("f1"); }
void f2(Allocator, string s, double d) { writeln("f2"); }

void main()
{
    with (Allocator())
    {
    scope(exit) deallocateAll;
    call!f1(2);
    call!f2("asdf", 1.0);
    }
}


I found another alternative to this:

https://godbolt.org/g/3Etims


Hm... neat idea. Somehow, opDispatch can probably be used to make this 
work even more generically (untested):


struct WithAlloc(alias alloc)
{
   auto opDispatch(string s, Args...)(auto ref Args args) if 
(__traits(compiles, mixin(s ~ "(args, alloc)")))

   {
  mixin("return " ~ s ~ "(args, alloc);");
   }
}

-Steve


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Atila Neves via Digitalmars-d

On Friday, 11 May 2018 at 13:22:12 UTC, Meta wrote:

On Friday, 11 May 2018 at 11:42:07 UTC, Dukc wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

...
// constructor of DataStructure
this(Allocator alloc=__ALLOC__) {...}
...
auto alloc = new SomeAllocator();
define __ALLOC__ = alloc;
// And we don't need to pass alloc everytime
...

Is this a good idea?


Doesn't this basically mean including the implicits Martin 
Odersky talked about at Dconf in D?


Yes it does. I was thinking the exact same thing while watching 
his talk; implicits would be perfect for allocators.


D doesn't have Scala's implicits though. However, one can write 
up a reader monad in the D we have right now.


Atila


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Yuxuan Shui via Digitalmars-d

On Friday, 11 May 2018 at 18:55:03 UTC, Meta wrote:

On Friday, 11 May 2018 at 15:03:41 UTC, Uknown wrote:

[...]


It's not as pretty, and I don't know if it works outside this 
toy example yet, but you can do:


import std.stdio;

struct Allocator
{
auto call(alias F, Args...)(Args args)
{
return F(this, args);
}

void deallocateAll()
{
writeln("deallocateAll");
}
}

void f1(Allocator a, int n) { writeln("f1"); }
void f2(Allocator, string s, double d) { writeln("f2"); }

void main()
{
with (Allocator())
{
scope(exit) deallocateAll;
call!f1(2);
call!f2("asdf", 1.0);
}
}


I found another alternative to this:

https://godbolt.org/g/3Etims


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread jmh530 via Digitalmars-d

On Friday, 11 May 2018 at 11:42:07 UTC, Dukc wrote:

[snip]

Doesn't this basically mean including the implicits Martin 
Odersky talked about at Dconf in D?


I don't know whether it's a good idea all-in-all, but assuming 
the arguments can be used as compile-time I can already see a 
big use case: killing autodecoding without breaking code. 
Something like:


auto front(C, bool disableDecoding = __NODECODE__)(inout C[] 
string)

{   static if (disableDecoding) {...}
else {...}
}


I'm not sure this makes sense or not...but what about instead of 
implicits, you allow a template to have type erased parameters, 
basically to optionally mimic the behavior of Java's generics. 
That way the allocator could be included in the type and checked 
at compile-time, but it wouldn't be known at run-time (not sure 
that's a positive or not).


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 15:15:03 UTC, Paul Backus wrote:
On Thursday, 10 May 2018 at 14:37:00 UTC, rikki cattermole 
wrote:

On 11/05/2018 2:33 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

But doing it with default argument expansion saves you 1 
allocation, has 1 less type, while being just as readable. I 
think that's a win.


class -> struct, now it is back to 1 allocation.


Even easier:

alias createDataStructure = (...) => new DataStructure(..., 
alloc);


I think one problem with this and Factory, is that you have to 
create one alias/lambda/factory type for every type that takes an 
allocator.


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Meta via Digitalmars-d

On Friday, 11 May 2018 at 15:03:41 UTC, Uknown wrote:
I see what you're saying and I agree with you. I think a better 
way would be to try and extend the `with` syntax to work with 
arbitrary functions, rather than only objects. That would make 
it more useful. So something like:


---
void f1(allocator alloc, ...){}
void f2(allocator alloc, ...){}
...
void fn(allocator alloc, ...){}

void main()
{
with(MyAllocator) {
f1(...);
f2(...);
...
fn(...);
}
}
---


It's not as pretty, and I don't know if it works outside this toy 
example yet, but you can do:


import std.stdio;

struct Allocator
{
auto call(alias F, Args...)(Args args)
{
return F(this, args);
}

void deallocateAll()
{
writeln("deallocateAll");
}
}

void f1(Allocator a, int n) { writeln("f1"); }
void f2(Allocator, string s, double d) { writeln("f2"); }

void main()
{
with (Allocator())
{
scope(exit) deallocateAll;
call!f1(2);
call!f2("asdf", 1.0);
}
}


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Uknown via Digitalmars-d

On Friday, 11 May 2018 at 14:26:21 UTC, Jonathan M Davis wrote:
On Thursday, May 10, 2018 14:15:18 Yuxuan Shui via 
Digitalmars-d wrote:

So in D I can use default argument like this:
[...]
Is this a good idea?


It seems like really risky move, honestly, because it means 
that the function is then affected by what is and isn't 
declared within the scope where it's called. __FILE__ and 
__LINE__ are well-defined as to what they mean. No can declare 
them to mean something else. You don't have symbol resolution 
issues or naming conflicts. And they're solving a problem that 
can't actually be solved without compiler help. However, if you 
just want to change what arguments get passed to foo within 
your module, all you have to do is define another foo inside 
the module and have it forward to the original one with 
whatever arguments you want. What you're suggesting here seems 
to introduce name pollution issues without solving anything 
that can't easily be solved with the language as-is.


- Jonathan M Davis


I see what you're saying and I agree with you. I think a better 
way would be to try and extend the `with` syntax to work with 
arbitrary functions, rather than only objects. That would make it 
more useful. So something like:


---
void f1(allocator alloc, ...){}
void f2(allocator alloc, ...){}
...
void fn(allocator alloc, ...){}

void main()
{
with(MyAllocator) {
f1(...);
f2(...);
...
fn(...);
}
}
---


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Jonathan M Davis via Digitalmars-d
On Thursday, May 10, 2018 14:15:18 Yuxuan Shui via Digitalmars-d wrote:
> So in D I can use default argument like this:
>
> int f(int line=__LINE__) {}
>
> And because default argument is expanded at call site, f() will
> be called with the line number of the call site.
>
> This is a really clever feature, and I think a similar feature
> can be useful in other ways.
>
> Say I need to construct a bunch of data structure that takes an
> Allocator argument, I need to do this:
>
> ...
> auto alloc = new SomeAllocator();
> auto data1 = new DataStructure(..., alloc);
> auto data2 = new DataStructure(..., alloc);
> auto data3 = new DataStructure(..., alloc);
> ...
>
> This looks redundant. But if we have the ability to define more
> special keywords like __LINE__, we can do something like this:
>
> ...
> // constructor of DataStructure
> this(Allocator alloc=__ALLOC__) {...}
> ...
> auto alloc = new SomeAllocator();
> define __ALLOC__ = alloc;
> // And we don't need to pass alloc everytime
> ...
>
> Is this a good idea?

It seems like really risky move, honestly, because it means that the
function is then affected by what is and isn't declared within the scope
where it's called. __FILE__ and __LINE__ are well-defined as to what they
mean. No can declare them to mean something else. You don't have symbol
resolution issues or naming conflicts. And they're solving a problem that
can't actually be solved without compiler help. However, if you just want to
change what arguments get passed to foo within your module, all you have to
do is define another foo inside the module and have it forward to the
original one with whatever arguments you want. What you're suggesting here
seems to introduce name pollution issues without solving anything that can't
easily be solved with the language as-is.

- Jonathan M Davis



Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Timon Gehr via Digitalmars-d

On 10.05.2018 16:22, rikki cattermole wrote:

On 11/05/2018 2:20 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:17:50 UTC, rikki cattermole wrote:

On 11/05/2018 2:15 AM, Yuxuan Shui wrote:

[...]


Bad idea, too much magic.


This magic is already there in D. I just want to use it in a different 
way.


The magic is not already in there.

__LINE__ and __MODULE__ are special, they are constants recognized by 
the compiler and are immediately substituted if not specified.


Yes, that's essentially the definition of "magic".


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Meta via Digitalmars-d

On Friday, 11 May 2018 at 11:42:07 UTC, Dukc wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

...
// constructor of DataStructure
this(Allocator alloc=__ALLOC__) {...}
...
auto alloc = new SomeAllocator();
define __ALLOC__ = alloc;
// And we don't need to pass alloc everytime
...

Is this a good idea?


Doesn't this basically mean including the implicits Martin 
Odersky talked about at Dconf in D?


Yes it does. I was thinking the exact same thing while watching 
his talk; implicits would be perfect for allocators.


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Dukc via Digitalmars-d

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

...
// constructor of DataStructure
this(Allocator alloc=__ALLOC__) {...}
...
auto alloc = new SomeAllocator();
define __ALLOC__ = alloc;
// And we don't need to pass alloc everytime
...

Is this a good idea?


Doesn't this basically mean including the implicits Martin 
Odersky talked about at Dconf in D?


I don't know whether it's a good idea all-in-all, but assuming 
the arguments can be used as compile-time I can already see a big 
use case: killing autodecoding without breaking code. Something 
like:


auto front(C, bool disableDecoding = __NODECODE__)(inout C[] 
string)

{   static if (disableDecoding) {...}
else {...}
}


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Paul Backus via Digitalmars-d

On Thursday, 10 May 2018 at 14:37:00 UTC, rikki cattermole wrote:

On 11/05/2018 2:33 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

But doing it with default argument expansion saves you 1 
allocation, has 1 less type, while being just as readable. I 
think that's a win.


class -> struct, now it is back to 1 allocation.


Even easier:

alias createDataStructure = (...) => new DataStructure(..., 
alloc);


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Uknown via Digitalmars-d

On Thursday, 10 May 2018 at 14:37:00 UTC, rikki cattermole wrote:

On 11/05/2018 2:33 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

[...]


But doing it with default argument expansion saves you 1 
allocation, has 1 less type, while being just as readable. I 
think that's a win.


class -> struct, now it is back to 1 allocation.


Alternatively `scope`d classes would also work with dip1000


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread rikki cattermole via Digitalmars-d

On 11/05/2018 2:33 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

[...]


For things like this you can use the OOP Factory pattern, pseudocode:

class DataStructureFactory
{
  this(Allocator alloc)
  {
    this.alloc = alloc;
  }

  Allocator alloc;

  DataStructure createDataStructure(...)
  {
    return new DataStructure(..., alloc)
  }
}

DataStructureFactory factory = new DataStructureFactory(new 
SomeAllocator())

auto data1 = factory.createDataStructure(...)
auto data2 = factory.createDataStructure(...)
auto data3 = factory.createDataStructure(...)


But doing it with default argument expansion saves you 1 allocation, has 
1 less type, while being just as readable. I think that's a win.


class -> struct, now it is back to 1 allocation.


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 14:30:49 UTC, Seb wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

So in D I can use default argument like this:

int f(int line=__LINE__) {}

[...]


Why not define a TLS or global variable like theAllocator?
Or if you know it at compile-time as an alias?


Because my proposal is better encapsulated. Definitions of 
expanded default arguments are scoped, so in the given example, 
you can have different __ALLOC__ in different scope, where 
different allocators might be needed.


My proposal is basically an alias, but an alias which is 
recognized by compiler as subtitution keywords for default 
arguments (like __LINE__, __FILE__).


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

[...]


For things like this you can use the OOP Factory pattern, 
pseudocode:


class DataStructureFactory
{
  this(Allocator alloc)
  {
this.alloc = alloc;
  }

  Allocator alloc;

  DataStructure createDataStructure(...)
  {
return new DataStructure(..., alloc)
  }
}

DataStructureFactory factory = new DataStructureFactory(new 
SomeAllocator())

auto data1 = factory.createDataStructure(...)
auto data2 = factory.createDataStructure(...)
auto data3 = factory.createDataStructure(...)


But doing it with default argument expansion saves you 1 
allocation, has 1 less type, while being just as readable. I 
think that's a win.


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Seb via Digitalmars-d

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

So in D I can use default argument like this:

int f(int line=__LINE__) {}

[...]


Why not define a TLS or global variable like theAllocator?
Or if you know it at compile-time as an alias?


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread JN via Digitalmars-d

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

So in D I can use default argument like this:

int f(int line=__LINE__) {}

And because default argument is expanded at call site, f() will 
be called with the line number of the call site.


This is a really clever feature, and I think a similar feature 
can be useful in other ways.


Say I need to construct a bunch of data structure that takes an 
Allocator argument, I need to do this:


...
auto alloc = new SomeAllocator();
auto data1 = new DataStructure(..., alloc);
auto data2 = new DataStructure(..., alloc);
auto data3 = new DataStructure(..., alloc);
...

This looks redundant. But if we have the ability to define more 
special keywords like __LINE__, we can do something like this:


...
// constructor of DataStructure
this(Allocator alloc=__ALLOC__) {...}
...
auto alloc = new SomeAllocator();
define __ALLOC__ = alloc;
// And we don't need to pass alloc everytime
...

Is this a good idea?


For things like this you can use the OOP Factory pattern, 
pseudocode:


class DataStructureFactory
{
  this(Allocator alloc)
  {
this.alloc = alloc;
  }

  Allocator alloc;

  DataStructure createDataStructure(...)
  {
return new DataStructure(..., alloc)
  }
}

DataStructureFactory factory = new DataStructureFactory(new 
SomeAllocator())

auto data1 = factory.createDataStructure(...)
auto data2 = factory.createDataStructure(...)
auto data3 = factory.createDataStructure(...)


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread rikki cattermole via Digitalmars-d

On 11/05/2018 2:20 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:17:50 UTC, rikki cattermole wrote:

On 11/05/2018 2:15 AM, Yuxuan Shui wrote:

[...]


Bad idea, too much magic.


This magic is already there in D. I just want to use it in a different way.


The magic is not already in there.

__LINE__ and __MODULE__ are special, they are constants recognized by 
the compiler and are immediately substituted if not specified.


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 14:17:50 UTC, rikki cattermole wrote:

On 11/05/2018 2:15 AM, Yuxuan Shui wrote:

[...]


Bad idea, too much magic.


This magic is already there in D. I just want to use it in a 
different way.


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread rikki cattermole via Digitalmars-d

On 11/05/2018 2:15 AM, Yuxuan Shui wrote:

So in D I can use default argument like this:

int f(int line=__LINE__) {}

And because default argument is expanded at call site, f() will be 
called with the line number of the call site.


This is a really clever feature, and I think a similar feature can be 
useful in other ways.


Say I need to construct a bunch of data structure that takes an 
Allocator argument, I need to do this:


...
auto alloc = new SomeAllocator();
auto data1 = new DataStructure(..., alloc);
auto data2 = new DataStructure(..., alloc);
auto data3 = new DataStructure(..., alloc);
...

This looks redundant. But if we have the ability to define more special 
keywords like __LINE__, we can do something like this:


...
// constructor of DataStructure
this(Allocator alloc=__ALLOC__) {...}
...
auto alloc = new SomeAllocator();
define __ALLOC__ = alloc;
// And we don't need to pass alloc everytime
...

Is this a good idea?


Bad idea, too much magic.