Thread overview | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 10, 2018 Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
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? |
May 11, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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.
|
May 10, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | 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.
|
May 11, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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.
|
May 10, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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(...) |
May 10, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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?
|
May 10, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to JN | 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.
|
May 10, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Seb | 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__).
|
May 11, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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.
|
May 10, 2018 Re: Extend the call site default argument expansion mechanism? | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | 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
|
Copyright © 1999-2021 by the D Language Foundation