Jump to page: 1 2 3
Thread overview
named arguments (C++) - Something D could learn from
Dec 14, 2018
bauss
Dec 14, 2018
JN
Dec 14, 2018
Dukc
Dec 14, 2018
rikki cattermole
Dec 14, 2018
John Chapman
Dec 14, 2018
Neia Neutuladh
Dec 15, 2018
NX
Dec 15, 2018
Neia Neutuladh
Dec 16, 2018
Jacob Carlborg
Dec 16, 2018
Matthew OConnor
Dec 17, 2018
Ethan
Dec 18, 2018
Atila Neves
Dec 17, 2018
JN
Dec 18, 2018
Atila Neves
Dec 18, 2018
JN
Dec 18, 2018
aliak
Dec 18, 2018
Simen Kjærås
Dec 18, 2018
aliak
Dec 19, 2018
Simen Kjærås
Dec 19, 2018
Kagamin
Dec 19, 2018
JN
Dec 19, 2018
Neia Neutuladh
December 14, 2018
In C++ you can achieve named arguments using templates and operator overload:

It's sad that D is still against having named arguments, but it's possible in something that D thrives to be better than.

https://www.fluentcpp.com/2018/12/14/named-arguments-cpp/

I assume this is not possible to port to D because D doesn't do operator overload in the same way C++ does, correct?

I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.
December 14, 2018
On Friday, 14 December 2018 at 20:13:42 UTC, bauss wrote:
> I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.

Even if a DIP would happen, people would just say it's unnecessary/bloat/can be done as a library function through some ugly mixin :/

December 14, 2018
On 12/14/18 3:13 PM, bauss wrote:
> In C++ you can achieve named arguments using templates and operator overload:
> 
> It's sad that D is still against having named arguments, but it's possible in something that D thrives to be better than.
> 
> https://www.fluentcpp.com/2018/12/14/named-arguments-cpp/
> 
> I assume this is not possible to port to D because D doesn't do operator overload in the same way C++ does, correct?

Bleh, C++ is so ugly. I can't see how D can't do better.

operator overloading works fine in D, just like it does in the given example.

What C++ allows is:

1. operator overloading of arbitrary operators. D has certain requirements for certain operators.
2. extracting the operator overloading to a module-level function. D requires operator overloading inside a type.

But neither of those problems are in play here. You could practically port the solution exactly to D.

HOWEVER, I don't think the mechanics make this solution worthwhile. Carrying around extra structs and wrapping things in this complicated way doesn't seem very attractive to me.

-Steve
December 14, 2018
On Friday, 14 December 2018 at 20:13:42 UTC, bauss wrote:
> I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.

Hope if far from lost here. There is not one, but two DIPs in draft stage to add named function parameters to D:

https://github.com/dlang/DIPs/pull/123
https://github.com/dlang/DIPs/pull/126
December 15, 2018
On 15/12/2018 10:22 AM, Dukc wrote:
> On Friday, 14 December 2018 at 20:13:42 UTC, bauss wrote:
>> I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.
> 
> Hope if far from lost here. There is not one, but two DIPs in draft stage to add named function parameters to D:
> 
> https://github.com/dlang/DIPs/pull/123
> https://github.com/dlang/DIPs/pull/126

Disclaimer the second DIP is mine.

The first is mostly concerned with syntax sugar.
The second is about modelling externally setting internal (but private) attributes that are visible publicly.

They both have their own pluses and minuses, but IMO the second is much harder to implement as a library. In fact we already do, see ElementType for input ranges. We can do better at modelling this.
December 14, 2018
On Friday, 14 December 2018 at 21:22:38 UTC, Dukc wrote:
> On Friday, 14 December 2018 at 20:13:42 UTC, bauss wrote:
>> I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.
>
> Hope if far from lost here. There is not one, but two DIPs in draft stage to add named function parameters to D:
>
> https://github.com/dlang/DIPs/pull/123
> https://github.com/dlang/DIPs/pull/126

If anyone wants to play with an implementation, I've updated Jacob Carlborg's old work here: https://github.com/jsatellite/dmd/tree/named-arguments

December 14, 2018
On Fri, 14 Dec 2018 20:13:42 +0000, bauss wrote:
> In C++ you can achieve named arguments using templates and operator overload:
> 
> It's sad that D is still against having named arguments, but it's possible in something that D thrives to be better than.
> 
> https://www.fluentcpp.com/2018/12/14/named-arguments-cpp/
> 
> I assume this is not possible to port to D because D doesn't do operator overload in the same way C++ does, correct?
> 
> I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.

The only vaguely interesting thing in that example is selecting an item based on its compile-time type, and that's easy.

In addition to what the FluentCpp post supports, we'd like to add default value handling, and we'd like to automatically generate the forwarding function.

I hacked this up:

https://git.ikeran.org/dhasenan/snippets/src/branch/master/namedargs/ forwarding.d

And you use it like:
---
writeln(dispatch!greet(Count(3), Name("Aerith")));
---

Issues:
* You have to write a bunch of extra structs. Namespace pollution ahoy.
Code that looks right but isn't because both module A and module B define a
`Name` parameter struct. You can probably reduce that a bit with
std.typecons.Typedef.
* This ignores superfluous arguments. That's left as an exercise to the
reader.
* Documentation. You can document the non-dispatch version of things and
suggest that users use the dispatch wrapper, or you can document an alias
around dispatch!fun and have no documentation for what parameters the
function has.
* Overloads. It is difficult to refer to a specific overload from a set,
and if you want to provide aliases for the dispatch function, it is
difficult to expose all of them. (On the other hand, with optional,
reorderable, named arguments, you can much more easily pack things into the
same function, assuming they're all supposed to do roughly the same thing,
which is good design.)
* Ref and out parameters. You can probably support them, but it would be
kind of hard.

Another strategy is to automatically generate a struct for each function, then use the struct initialization syntax to create the value and call a method on it to invoke the function. It would work like:

---
Invoker!greet f = {
  name: "Rydia",
  count: 1
};
writeln(f());
---

And that has its own issues: you have to declare a new variable each time, it's easy to call the function multiple times, and ref and out parameters are much more awkward. You can at least tell whether a parameter was provided or not using std.typecons.Nullable or the like.
December 15, 2018
On Friday, 14 December 2018 at 23:10:35 UTC, Neia Neutuladh wrote:
> I hacked this up:
>
> https://git.ikeran.org/dhasenan/snippets/src/branch/master/namedargs/forwarding.d

Check this out: https://github.com/CyberShadow/ae/blob/master/utils/meta/args.d
December 15, 2018
On Sat, 15 Dec 2018 15:59:48 +0000, NX wrote:
> On Friday, 14 December 2018 at 23:10:35 UTC, Neia Neutuladh wrote:
>> I hacked this up:
>>
>> https://git.ikeran.org/dhasenan/snippets/src/branch/master/namedargs/
forwarding.d
> 
> Check this out: https://github.com/CyberShadow/ae/blob/master/utils/meta/args.d

Nice! I think I saw this before and forgot about it.

I'll still probably never use it, but oh well.
December 16, 2018
On 2018-12-14 21:13, bauss wrote:
> In C++ you can achieve named arguments using templates and operator overload:
> 
> It's sad that D is still against having named arguments, but it's possible in something that D thrives to be better than.
> 
> https://www.fluentcpp.com/2018/12/14/named-arguments-cpp/
> 
> I assume this is not possible to port to D because D doesn't do operator overload in the same way C++ does, correct?
> 
> I still think named arguments should be something to consider implementing for D, but since everything requires a DIP and it's very hard to write a DIP that's proper for such a thing then I guess it'll just be a dream, forever.

Here's a simple version in D that doesn't require to declare a variable for each name, does not support reordering names:

void foo(int a)
{
    writeln(a);
}

void bar(NamedArgument!("b", int) b)
{
    writeln(b);
}

struct NamedArgument(string name, T)
{
    T value;
    alias value this;
}

struct NamedArgumentProxy
{
    auto opDispatch(string name, T)(T value) const
    {
        return NamedArgument!(name, T)(value);
    }
}

immutable NamedArgumentProxy na;

void main()
{
    foo(na.a = 3); // the name "a" here doesn't matter, it can be anything
    foo(na.b = 4); // this has to be "b", otherwise it won't compile
}

https://run.dlang.io/is/zgejqi

-- 
/Jacob Carlborg
« First   ‹ Prev
1 2 3