Discussion:
this is almost a workaround for the lack of named parameters
(too old to reply)
J
2013-03-21 18:35:23 UTC
Permalink
#!/usr/bin/rdmd
void main(string[] arg) {

// Observation: I'd like to say:
/*
auto r = myfunc.call("named") with { z= 2; x = -123; y = 200; }
*/

// and have it turned into this:
with(myfunc) { x = -123; y = 200; z = -20; }
auto r = myfunc.call("named");

// Q: is there some way to achieve this? Maybe a variation on
with?

// Is there a macro facility lurking someplace? Or is there
another way to do this?
// Thanks!
// - J
}

import std.stdio;

struct myfunc_
{
// named keyword or named parameters
// --the call arguments and their defaults
int x=0;
int y=0;
int z=0;

string call(string non_keyword_arg)
{
writefln("%s: X %s, Y %s, Z %s", non_keyword_arg, x, y, z );
return "yo";
}
}
myfunc_ myfunc;
J
2013-03-21 18:39:36 UTC
Permalink
// CORRECTION:
// and have it turned into this:
with(myfunc) { z =2; x = -123; y = 200; }
auto r = myfunc.call("named");
J
2013-03-21 19:42:07 UTC
Permalink
/* Similarly but different (here I am instantiating a new
struct
before the call, rather than re-using a global single
struct each time),
it would be lovely and elegant to say:
*/

void main(string[] arg) {

/* Elegant:

auto r = myfunc() with { z= 2; x = -123; y = 200; }

*/

// and have it lowered to:
myfunc tmp;
with(tmp) { z= 2; x = -123; y = 200; }
auto r = tmp();

}

import std.stdio;

struct myfunc
{
// named keyword or named parameters
// --the call arguments and their defaults
int x=0;
int y=0;
int z=0;

// opCall is sweet... improves upon previous example

string opCall(string required_positional_arg = "default pos
arg value") {
writefln("%s: X %s, Y %s, Z %s", required_positional_arg,
x, y, z );
return "yo";
}

}
J
2013-03-22 09:18:31 UTC
Permalink
The bigger point here is more profound: it is trivial to
implement named parameters using structs + trivial lowerings, and
this is no way conflicts with function overloading.

D deserves to have named parameters to functions -- it makes for
much more legible code, and obviates the need for slow builder
patterns. Readable and speedable. It's win-win.
J
2013-03-22 10:17:01 UTC
Permalink
With credit for inspiration to David Medlock in this post--
http://forum.dlang.org/thread/d9lnrr$26q3$1 at digitaldaemon.com ...

// Tongue firmly in cheek, I'd like to introduce
// the NAPAPISS principle: (with apologies to SFINAE and RAII)

// NAPAPISS = NAmed Parameters Are simply Passed in a Struct,
Silly.

// Yes, indeed, maybe this is what happens after drinking too
much of
// the fine wine products from the Napa valley... you start having
// wild flights of fancy of how D might surprisingly soon have
// named parameters....


import std.stdio;
import std.c.stdlib;

void main(string[] arg) {

// this works today: but with the drawback that the
// named params must be known at compile time...

// Here is a named param call,
// as compact as I could get it (see struct below for actual
definition).

auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls
opCall
writeln("a=", a); // prints "a=yo", as returned from opCall



// And here's the runtime version, unfortunately you have to
// pre-declare g because otherwise it won't survive the
scope, and
// the return value from myfunc.opCall would become
inaccessible.
string g;
with(myfunc!()(0)) {
x=rand() % 40;
y=x/2;
z=y/2;
g = call(); // as a side effect, prints 'X 7, Y 3, Z 1'
}
writeln("g=", g); // prints "g=yo", as returned from opCall


/*
// The bright future: this demonstrates that
// it would be fairly trivial to make some kind of annotation
// like @kwarg or whaterver, to indicate that a function
// was using this calling convention:
@kwarg string f(int a, string b) { body; }

// so that @kwarg function definitions are lowered to:
struct f_kw {
int a;
string b;
string f() { body; }
}

// and calls to @kwarg functions are transformed
// from this:
auto r = f(a=5, b="good");

// into this:
f_kw tmp34;
tmp34.a = 5;
tmp34.b = "good";
auto r = tmp34.f();

// the benefit: named parameters can be used in a natural way,
// and they need be known only at runtime.
*/
}

// how the 'works today' above examples were implemented:
struct myfunc(string init_string="")
{
// named keyword or named parameters
// --the call arguments and their defaults
int x=0;
int y=0;
int z=0;

this(int) {}
string opCall() {
mixin(init_string ~ ";");
writefln("X %s, Y %s, Z %s", x, y, z );
return "yo";
}
alias opCall call;
}
Post by J
The bigger point here is more profound: it is trivial to
implement named parameters using structs + trivial lowerings,
and this is no way conflicts with function overloading.
D deserves to have named parameters to functions -- it makes
for much more legible code, and obviates the need for slow
builder patterns. Readable and speedable. It's win-win.
Jacob Carlborg
2013-03-22 11:58:54 UTC
Permalink
Post by J
With credit for inspiration to David Medlock in this post--
http://forum.dlang.org/thread/d9lnrr$26q3$1 at digitaldaemon.com ...
// Tongue firmly in cheek, I'd like to introduce
// the NAPAPISS principle: (with apologies to SFINAE and RAII)
// NAPAPISS = NAmed Parameters Are simply Passed in a Struct, Silly.
// Yes, indeed, maybe this is what happens after drinking too much of
// the fine wine products from the Napa valley... you start having
// wild flights of fancy of how D might surprisingly soon have
// named parameters....
import std.stdio;
import std.c.stdlib;
void main(string[] arg) {
// this works today: but with the drawback that the
// named params must be known at compile time...
// Here is a named param call,
// as compact as I could get it (see struct below for actual
definition).
auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls opCall
writeln("a=", a); // prints "a=yo", as returned from opCall
// And here's the runtime version, unfortunately you have to
// pre-declare g because otherwise it won't survive the scope, and
// the return value from myfunc.opCall would become inaccessible.
string g;
with(myfunc!()(0)) {
x=rand() % 40;
y=x/2;
z=y/2;
g = call(); // as a side effect, prints 'X 7, Y 3, Z 1'
}
writeln("g=", g); // prints "g=yo", as returned from opCall
/*
// The bright future: this demonstrates that
// it would be fairly trivial to make some kind of annotation
@kwarg string f(int a, string b) { body; }
struct f_kw {
int a;
string b;
string f() { body; }
}
auto r = f(a=5, b="good");
f_kw tmp34;
tmp34.a = 5;
tmp34.b = "good";
auto r = tmp34.f();
// the benefit: named parameters can be used in a natural way,
// and they need be known only at runtime.
*/
}
struct myfunc(string init_string="")
{
// named keyword or named parameters
// --the call arguments and their defaults
int x=0;
int y=0;
int z=0;
this(int) {}
string opCall() {
mixin(init_string ~ ";");
writefln("X %s, Y %s, Z %s", x, y, z );
return "yo";
}
alias opCall call;
}
Here's my proposal for anonymous structs that can be used as name
parameters:

http://forum.dlang.org/thread/kfbnuc$1cro$1 at digitalmars.com?page=1
--
/Jacob Carlborg
foobar
2013-03-22 20:04:12 UTC
Permalink
Post by J
With credit for inspiration to David Medlock in this post--
http://forum.dlang.org/thread/d9lnrr$26q3$1 at digitaldaemon.com ...
// Tongue firmly in cheek, I'd like to introduce
// the NAPAPISS principle: (with apologies to SFINAE and RAII)
// NAPAPISS = NAmed Parameters Are simply Passed in a Struct,
Silly.
// Yes, indeed, maybe this is what happens after drinking too
much of
// the fine wine products from the Napa valley... you start
having
// wild flights of fancy of how D might surprisingly soon have
// named parameters....
import std.stdio;
import std.c.stdlib;
void main(string[] arg) {
// this works today: but with the drawback that the
// named params must be known at compile time...
// Here is a named param call,
// as compact as I could get it (see struct below for
actual definition).
auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls
opCall
writeln("a=", a); // prints "a=yo", as returned from opCall
// And here's the runtime version, unfortunately you have to
// pre-declare g because otherwise it won't survive the
scope, and
// the return value from myfunc.opCall would become
inaccessible.
string g;
with(myfunc!()(0)) {
x=rand() % 40;
y=x/2;
z=y/2;
g = call(); // as a side effect, prints 'X 7, Y 3, Z
1'
}
writeln("g=", g); // prints "g=yo", as returned from opCall
/*
// The bright future: this demonstrates that
// it would be fairly trivial to make some kind of
annotation
@kwarg string f(int a, string b) { body; }
struct f_kw {
int a;
string b;
string f() { body; }
}
auto r = f(a=5, b="good");
f_kw tmp34;
tmp34.a = 5;
tmp34.b = "good";
auto r = tmp34.f();
// the benefit: named parameters can be used in a natural
way,
// and they need be known only at runtime.
*/
}
struct myfunc(string init_string="")
{
// named keyword or named parameters
// --the call arguments and their defaults
int x=0;
int y=0;
int z=0;
this(int) {}
string opCall() {
mixin(init_string ~ ";");
writefln("X %s, Y %s, Z %s", x, y, z );
return "yo";
}
alias opCall call;
}
Post by J
The bigger point here is more profound: it is trivial to
implement named parameters using structs + trivial lowerings,
and this is no way conflicts with function overloading.
D deserves to have named parameters to functions -- it makes
for much more legible code, and obviates the need for slow
builder patterns. Readable and speedable. It's win-win.
WTF? What do kwargs have to do with programming? Sounds more like
a half-Klingon & half-Ferengi species to me.
John Colvin
2013-03-22 21:10:25 UTC
Permalink
Post by foobar
Post by J
With credit for inspiration to David Medlock in this post--
http://forum.dlang.org/thread/d9lnrr$26q3$1 at digitaldaemon.com ...
// Tongue firmly in cheek, I'd like to introduce
// the NAPAPISS principle: (with apologies to SFINAE and RAII)
// NAPAPISS = NAmed Parameters Are simply Passed in a Struct,
Silly.
// Yes, indeed, maybe this is what happens after drinking too
much of
// the fine wine products from the Napa valley... you start
having
// wild flights of fancy of how D might surprisingly soon have
// named parameters....
import std.stdio;
import std.c.stdlib;
void main(string[] arg) {
// this works today: but with the drawback that the
// named params must be known at compile time...
// Here is a named param call,
// as compact as I could get it (see struct below for
actual definition).
auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls
opCall
writeln("a=", a); // prints "a=yo", as returned from opCall
// And here's the runtime version, unfortunately you have to
// pre-declare g because otherwise it won't survive the
scope, and
// the return value from myfunc.opCall would become
inaccessible.
string g;
with(myfunc!()(0)) {
x=rand() % 40;
y=x/2;
z=y/2;
g = call(); // as a side effect, prints 'X 7, Y 3, Z
1'
}
writeln("g=", g); // prints "g=yo", as returned from opCall
/*
// The bright future: this demonstrates that
// it would be fairly trivial to make some kind of
annotation
@kwarg string f(int a, string b) { body; }
struct f_kw {
int a;
string b;
string f() { body; }
}
auto r = f(a=5, b="good");
f_kw tmp34;
tmp34.a = 5;
tmp34.b = "good";
auto r = tmp34.f();
// the benefit: named parameters can be used in a natural
way,
// and they need be known only at runtime.
*/
}
struct myfunc(string init_string="")
{
// named keyword or named parameters
// --the call arguments and their defaults
int x=0;
int y=0;
int z=0;
this(int) {}
string opCall() {
mixin(init_string ~ ";");
writefln("X %s, Y %s, Z %s", x, y, z );
return "yo";
}
alias opCall call;
}
Post by J
The bigger point here is more profound: it is trivial to
implement named parameters using structs + trivial lowerings,
and this is no way conflicts with function overloading.
D deserves to have named parameters to functions -- it makes
for much more legible code, and obviates the need for slow
builder patterns. Readable and speedable. It's win-win.
WTF? What do kwargs have to do with programming? Sounds more
like a half-Klingon & half-Ferengi species to me.
kwargs = keyword arguments

It's a common naming convention in python, as exemplified in
matplotlib.
foobar
2013-03-22 21:29:45 UTC
Permalink
Post by John Colvin
Post by foobar
WTF? What do kwargs have to do with programming? Sounds more
like a half-Klingon & half-Ferengi species to me.
kwargs = keyword arguments
It's a common naming convention in python, as exemplified in
matplotlib.
That was meant more as a rhetorical question rather than a real
one.
Yes, I guessed the meaning by the surrounding context but
nevertheless it was a major WAT while skimming the post. Also,
Who the fuck cares whats common in Python? I was reading and
replying on the *D* NG, was I not?
John Colvin
2013-03-22 21:41:45 UTC
Permalink
Post by foobar
Post by John Colvin
Post by foobar
WTF? What do kwargs have to do with programming? Sounds more
like a half-Klingon & half-Ferengi species to me.
kwargs = keyword arguments
It's a common naming convention in python, as exemplified in
matplotlib.
That was meant more as a rhetorical question rather than a real
one.
Yes, I guessed the meaning by the surrounding context but
nevertheless it was a major WAT while skimming the post. Also,
Who the fuck cares whats common in Python? I was reading and
replying on the *D* NG, was I not?
Kwarg seems a reasonable name, consistent with a pre-existing
convention. Please suggest a better alternative if you have one.
I must admit I'm bemused by your level of aggression over what
appears to be a trivial matter.
foobar
2013-03-23 09:51:38 UTC
Permalink
Post by John Colvin
Post by foobar
Post by John Colvin
Post by foobar
WTF? What do kwargs have to do with programming? Sounds more
like a half-Klingon & half-Ferengi species to me.
kwargs = keyword arguments
It's a common naming convention in python, as exemplified in
matplotlib.
That was meant more as a rhetorical question rather than a
real one.
Yes, I guessed the meaning by the surrounding context but
nevertheless it was a major WAT while skimming the post. Also,
Who the fuck cares whats common in Python? I was reading and
replying on the *D* NG, was I not?
Kwarg seems a reasonable name, consistent with a pre-existing
convention. Please suggest a better alternative if you have
one. I must admit I'm bemused by your level of aggression over
what appears to be a trivial matter.
Your read it wrong. Not aggression but rather annoyment.
Also, code readability is NOT a trivial matter and people who
think that it is should have their keyboard chopped off.

IMHO, I think the entire feature is a code smell and glad D does
not support it. Code that needs named parameters to be more
readable is poorly designed code in the first place.
bearophile
2013-03-23 15:00:12 UTC
Permalink
Code that needs named parameters to be more readable is poorly
designed code in the first place.
Have you used a language where the usage of named arguments is
idiomatic, like Python, Scala or Ada? They are sometimes useful
even for well designed code, like functions with two arguments.

Bye,
bearophile
John Colvin
2013-03-23 15:55:35 UTC
Permalink
Post by bearophile
Code that needs named parameters to be more readable is poorly
designed code in the first place.
Have you used a language where the usage of named arguments is
idiomatic, like Python, Scala or Ada? They are sometimes useful
even for well designed code, like functions with two arguments.
Bye,
bearophile
A simple example is matplotlib.pyplot.plot

There are so many possible flags and parameters that can be
passed in order to get the exact behaviour you want, but commonly
you'll only want a few set for each call. You don't want to have
to set all the other preceding parameters, you just want to go
e.g. plot(data, linewidth=5)
Jacob Carlborg
2013-03-23 15:59:12 UTC
Permalink
Post by John Colvin
A simple example is matplotlib.pyplot.plot
There are so many possible flags and parameters that can be passed in
order to get the exact behaviour you want, but commonly you'll only want
a few set for each call. You don't want to have to set all the other
preceding parameters, you just want to go e.g. plot(data, linewidth=5)
I've heard it was a big boost for C# when it got support for default
arguments and named parameters. It made it a lot easier to integrate
with COM.
--
/Jacob Carlborg
foobar
2013-03-25 12:39:39 UTC
Permalink
Post by Jacob Carlborg
Post by John Colvin
A simple example is matplotlib.pyplot.plot
There are so many possible flags and parameters that can be
passed in
order to get the exact behaviour you want, but commonly you'll only want
a few set for each call. You don't want to have to set all the other
preceding parameters, you just want to go e.g. plot(data,
linewidth=5)
I've heard it was a big boost for C# when it got support for
default arguments and named parameters. It made it a lot easier
to integrate with COM.
AFAIK, this is only relevant or useful for COM (i.e. to support
legacy, not really OO code) and is not supported (compile error?)
for regular C# code as it is *not idiomatic C#* style (and is not
OO).
deadalnix
2013-03-23 19:56:14 UTC
Permalink
Post by John Colvin
Post by bearophile
Code that needs named parameters to be more readable is
poorly designed code in the first place.
Have you used a language where the usage of named arguments is
idiomatic, like Python, Scala or Ada? They are sometimes
useful even for well designed code, like functions with two
arguments.
Bye,
bearophile
A simple example is matplotlib.pyplot.plot
There are so many possible flags and parameters that can be
passed in order to get the exact behaviour you want, but
commonly you'll only want a few set for each call. You don't
want to have to set all the other preceding parameters, you
just want to go e.g. plot(data, linewidth=5)
Can't the monadic style thing do the trick ?

Named!plot.linewidth(5).call(data);

This is doable with actual D using compile time reflection.
J
2013-03-24 00:27:30 UTC
Permalink
Post by deadalnix
Post by John Colvin
Post by bearophile
Code that needs named parameters to be more readable is
poorly designed code in the first place.
Have you used a language where the usage of named arguments
is idiomatic, like Python, Scala or Ada? They are sometimes
useful even for well designed code, like functions with two
arguments.
Bye,
bearophile
A simple example is matplotlib.pyplot.plot
There are so many possible flags and parameters that can be
passed in order to get the exact behaviour you want, but
commonly you'll only want a few set for each call. You don't
want to have to set all the other preceding parameters, you
just want to go e.g. plot(data, linewidth=5)
Can't the monadic style thing do the trick ?
Named!plot.linewidth(5).call(data);
This is doable with actual D using compile time reflection.
Good point, and I'm sure we all develop our personal sense of
'code smell' based on our own past experience. I find adding lots
of enums to be like doing RAII in C++: I find it a pain to have
to pollute namespaces with extra enums (classes), just to get
readability/safety.

To me, the builder/monadic style is clunky and harder to read. I
find

plot(data, linewidth = 5)

to be clean, clear, and more concise.
timotheecour
2013-03-24 02:05:54 UTC
Permalink
I updated
https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d
to incorporate Jacob Carlborg's idea (thanks for the
working+clean code! let me know if attribution is ok)

auto a=named!fun.z(3).x(4).call();
and then simplified it a bit to:

auto a=named!fun.z(3).x(4)();

It's now looking pretty close to the ideal D syntax:
auto a=fun(z:3,x:4);

Notes:
auto a=fun(z=3,x=4);
doesn't seem like a good syntax compared to 'z:3,x:4', because
z=3 could be ambiguous with an expression assigning 3 to z when z
is in scope.
I find it a pain to have to pollute namespaces with extra enums
(classes), just to get readability/safety.
plot(data, linewidth = 5)
to be clean, clear, and more concise.
I agree.

In fact, I think we should push that named syntax
'named!fun.z(3).x(4)();' in std.functional once finalized, and
start using it in phobos ASAP, it makes things more self
documenting.

If 'fun(z:3,x:4)' syntax later comes to D, it'd be trivial to
write a tool that automatically changes the named!fun syntax in
people's / phobos' source code to use the new cleaner syntax.

main benefit IMO: prevent boilerplate code like this:

struct Options{int x; int y=1; int z=2;}
auto fun(Options options);

Options options;
options.x=4;
options.z=3;
auto a=fun(options);
(or similar with param expansion: auto
a=fun(options.x,options.y,options.z))


thanks for your comments!
Philippe Sigaud
2013-03-24 08:13:57 UTC
Permalink
Post by timotheecour
auto a=fun(z:3,x:4);
The last time I tried this (maybe 2 years ago, so before
std.traits.ParameterNameTuple?), I used associative arrays:

alias nfoo = named!foo; // nfoo is now a function admitting AA as arguments

auto result = nfoo(["z":"Title"], ["x":1, "y":100]);


Also, I see that at one time, you used a full string syntax:

auto result = nfoo(q{z = "Title", x = 1, y = 100}); // nfoo will parse
the input string

I rather like this one. Why did you ditch it?
Jacob Carlborg
2013-03-24 10:14:43 UTC
Permalink
Post by timotheecour
I updated
https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d
to incorporate Jacob Carlborg's idea (thanks for the working+clean code!
let me know if attribution is ok)
Absolutely.
Post by timotheecour
If 'fun(z:3,x:4)' syntax later comes to D, it'd be trivial to write a
tool that automatically changes the named!fun syntax in people's /
phobos' source code to use the new cleaner syntax.
struct Options{int x; int y=1; int z=2;}
auto fun(Options options);
Options options;
options.x=4;
options.z=3;
auto a=fun(options);
(or similar with param expansion: auto
a=fun(options.x,options.y,options.z))
What would be nice is to be able to do like this:

struct Options{int x; int y=1; int z=2;}
auto fun(Options options);

fun(y: 2, z: 45, x: 4);

Then add opDispatch to Options to soak up any varialble not found in
Options:

struct Options
{
int x;
int y = 1;
int z = 2;

private Variant[string] values;

void opDispatch (string name, T) (T value)
{
values[name] = Variant(value);
}
)

fun(y: 2, foo: "asd", bar: 4.0, z: 45, x: 4);

x, y, z are mapped to the variables in Options. foo and bar are handled
by opDispatch.

See my proposal for anonymous structs:

http://forum.dlang.org/thread/kfbnuc$1cro$1 at digitalmars.com
--
/Jacob Carlborg
Jacob Carlborg
2013-03-24 10:15:34 UTC
Permalink
Post by Philippe Sigaud
auto result = nfoo(q{z = "Title", x = 1, y = 100}); // nfoo will parse
the input string
I rather like this one. Why did you ditch it?
That would requires compile time values, i.e. no variables.
--
/Jacob Carlborg
Philippe Sigaud
2013-03-24 17:26:28 UTC
Permalink
Post by Jacob Carlborg
Post by Philippe Sigaud
auto result = nfoo(q{z = "Title", x = 1, y = 100}); // nfoo will parse
the input string
I rather like this one. Why did you ditch it?
That would requires compile time values, i.e. no variables.
You're right.
Jacob Carlborg
2013-03-24 19:35:50 UTC
Permalink
Post by timotheecour
I updated
https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d
to incorporate Jacob Carlborg's idea (thanks for the working+clean code!
let me know if attribution is ok)
BTW, why was the constructor added to Proxy and the "dummy" argument?
--
/Jacob Carlborg
timotheecour
2013-03-24 19:59:19 UTC
Permalink
Post by Jacob Carlborg
BTW, why was the constructor added to Proxy and the "dummy"
argument?
because I wanted to simplify syntax from 'auto
ret2=named!fun.z(3).x(4).call();' to 'auto
ret2=named!fun.z(3).x(4)();'
In doing that, I was having CT errors without it due to ambiguity
between default unnamed constructor and opCall, so I added
constructor.
Then inside the named() function i needed to return a proxy
object.
Alternatives were:
return Proxy!(func, null)(); //wrong: would call opCall
return Proxy!(func, null).init; //not sure if it would incur
overhead
return Proxy!(func, null)(0); //introduces dummy arg, which
should be
optimized away.

If you can find a better way (that doesn't incur runtime
overhead),
please do a pull request!
Also, I'm wondering about:
* how to put the unittest helper function "fun" inside main
unittest block
* whether the named!fun.z(3).x(4)(); call has any overhead over
calling fun(4,2,3) directly.
* how to support templated functions (here fun is not templated)
* whether we should support this syntax:
auto ret=named!fun.z(3)(4); //this would mean
named!fun.z(3).x(4)();
ie all non-optional arguments go in the opCall(..) arguments, all
optional arguments are called by name. So that would force API to
freeze names only for optional arguments, not non-optional ones,
cf in
python:
fun(4,z:3)


Finally, how do I reply from my email client ? Right I'm using
http://forum.dlang.org/ otherwise the message isn't delivered on
the forum... Thanks!
Jacob Carlborg
2013-03-24 20:36:14 UTC
Permalink
Post by timotheecour
Post by Jacob Carlborg
BTW, why was the constructor added to Proxy and the "dummy" argument?
because I wanted to simplify syntax from 'auto
ret2=named!fun.z(3).x(4).call();' to 'auto
ret2=named!fun.z(3).x(4)();'
In doing that, I was having CT errors without it due to ambiguity
between default unnamed constructor and opCall, so I added
constructor.
Then inside the named() function i needed to return a proxy object.
return Proxy!(func, null)(); //wrong: would call opCall
return Proxy!(func, null).init; //not sure if it would incur overhead
return Proxy!(func, null)(0); //introduces dummy arg, which should be
optimized away.
Aha, ok I see.
Post by timotheecour
Finally, how do I reply from my email client ? Right I'm using
http://forum.dlang.org/ otherwise the message isn't delivered on the
forum... Thanks!
I'm using Thunderbird and just using "Reply to the message".
--
/Jacob Carlborg
a a
2013-03-24 22:53:47 UTC
Permalink
Post by Jacob Carlborg
I'm using Thunderbird and just using "Reply to the message".
using gmail but doesn't work... (testing again via this message...) pls
ignore if this succeeds!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20130324/8c394eb0/attachment.html>
Jacob Carlborg
2013-03-25 09:01:01 UTC
Permalink
Post by a a
using gmail but doesn't work... (testing again via this message...) pls
ignore if this succeeds!
I got this.
--
/Jacob Carlborg
foobar
2013-03-25 12:36:01 UTC
Permalink
Post by bearophile
Code that needs named parameters to be more readable is poorly
designed code in the first place.
Have you used a language where the usage of named arguments is
idiomatic, like Python, Scala or Ada? They are sometimes useful
even for well designed code, like functions with two arguments.
Bye,
bearophile
"idiomatic" is a relative term, tightly coupled to a specific
language. Idiomatic D code for example is very different from
idiomatic Haskell code.
Idiomatic Python style in D would be very unidiomatic D code and
vise versa. Each language has its own conventions, styles, set of
distinct features, etc, etc and trying to use "language A" style
while coding in "language B" is like trying to fit a square peg
in a round hole.
For instance, I would NOT use smalltalk naming conventions while
writing say Java code. Both have very good and very consistent
styles that are tightly coupled with their respective syntaxes
and are very unsuitable to use in the other language.

In short, if you want to discuss python features, style or
specific math plotting libraries, please post to the python
mailing list, not D's NG.
bearophile
2013-03-25 13:02:47 UTC
Permalink
Post by foobar
"idiomatic" is a relative term, tightly coupled to a specific
language. Idiomatic D code for example is very different from
idiomatic Haskell code.
Idiomatic Python style in D would be very unidiomatic D code
and vise versa. Each language has its own conventions, styles,
set of distinct features, etc, etc and trying to use "language
A" style while coding in "language B" is like trying to fit a
square peg in a round hole.
For instance, I would NOT use smalltalk naming conventions
while writing say Java code. Both have very good and very
consistent styles that are tightly coupled with their
respective syntaxes and are very unsuitable to use in the other
language.
In short, if you want to discuss python features, style or
specific math plotting libraries, please post to the python
mailing list, not D's NG.
Imperative/OOP languages are not totally different from each
other, both Python and D derive strongly from C that comes
partially from Algol, and D copies several things from Python
(string functions, part of the module system, part of the range
design comes from itertools, and so on). So comparing languages
and their features is very useful.

If you have not used named arguments in languages that
idiomatically use them, then it's not easy for you to see how and
why they are sometimes useful and good.

In Python function arguments don't have a type, so named
arguments are more useful than in D. But from my experience in
Python, I believe D could enjoy named arguments.

Bye,
bearophile
foobar
2013-03-25 13:28:15 UTC
Permalink
Post by bearophile
Post by foobar
"idiomatic" is a relative term, tightly coupled to a specific
language. Idiomatic D code for example is very different from
idiomatic Haskell code.
Idiomatic Python style in D would be very unidiomatic D code
and vise versa. Each language has its own conventions, styles,
set of distinct features, etc, etc and trying to use "language
A" style while coding in "language B" is like trying to fit a
square peg in a round hole.
For instance, I would NOT use smalltalk naming conventions
while writing say Java code. Both have very good and very
consistent styles that are tightly coupled with their
respective syntaxes and are very unsuitable to use in the
other language.
In short, if you want to discuss python features, style or
specific math plotting libraries, please post to the python
mailing list, not D's NG.
Imperative/OOP languages are not totally different from each
other, both Python and D derive strongly from C that comes
partially from Algol, and D copies several things from Python
(string functions, part of the module system, part of the range
design comes from itertools, and so on). So comparing languages
and their features is very useful.
If you have not used named arguments in languages that
idiomatically use them, then it's not easy for you to see how
and why they are sometimes useful and good.
In Python function arguments don't have a type, so named
arguments are more useful than in D. But from my experience in
Python, I believe D could enjoy named arguments.
Bye,
bearophile
C is a HORRIBLE language regarding naming conventions and is a
*very poor choice* to learn from in this regard. Python sets very
high expectations regarding "beautiful code" and IMHO fails
miserably (more so because of the starting higher expectations).
I admit to being spoiled by actually beautifully designed
languages that are far superior in that respect. I suggest to
learn Smalltalk for a language that emphasizes code readability
decades before Python became cool.
I find Ruby which is based on Smalltalk's semantics and spirit to
be more elegant and less pretentious compared to Python.
deadalnix
2013-03-22 15:40:04 UTC
Permalink
Post by J
The bigger point here is more profound: it is trivial to
implement named parameters using structs + trivial lowerings,
and this is no way conflicts with function overloading.
D deserves to have named parameters to functions -- it makes
for much more legible code, and obviates the need for slow
builder patterns. Readable and speedable. It's win-win.
Question for specialists of the topic : are parameter name
available using compile time reflection ?

Because if they are, the problem boils down to perfect forwarding
issue. And it seems solvable :

NamedCall!(
function,
"foo", fooVal,
"bar", barVal); // Booya !
Dicebot
2013-03-22 15:50:37 UTC
Permalink
http://dlang.org/phobos/std_traits.html#.ParameterIdentifierTuple
deadalnix
2013-03-22 16:56:58 UTC
Permalink
Post by Dicebot
http://dlang.org/phobos/std_traits.html#.ParameterIdentifierTuple
Seems to me like a solved problem.
timotheecour
2013-03-22 18:48:55 UTC
Permalink
so i hacked up a working solution yesterday.
advantages over
https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135:
no need to no arguments at CT (just names); allows optional and
non optional ones; allows return value; also, mambo depends on
tango and is hard to revive.

More later.


see:
https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d

nothing to install, just call:
rdmd --main -unittest dtools/util/functional.d


auto s=callNamed!(fun,`x,y`)(10,20);
given a function:
auto fun(int x,int y=2,double z=z_val, string z2="asdf");

Compile time errors will occur on duplicate param names, or ones
that don't exist, or ones that are not optional and not provided
(eg x, above)

Feel free to contribute / comment
deadalnix
2013-03-22 19:03:39 UTC
Permalink
Post by timotheecour
so i hacked up a working solution yesterday.
advantages over
no need to no arguments at CT (just names); allows optional and
non optional ones; allows return value; also, mambo depends on
tango and is hard to revive.
More later.
https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d
rdmd --main -unittest dtools/util/functional.d
auto s=callNamed!(fun,`x,y`)(10,20);
auto fun(int x,int y=2,double z=z_val, string z2="asdf");
Compile time errors will occur on duplicate param names, or
ones that don't exist, or ones that are not optional and not
provided (eg x, above)
Feel free to contribute / comment
Don't have time to look at the code now, but it seems awesome !
Great leverage of language capabilities. Slightly different from
my proposal, but I'm really not sure which interface fit best.
I'm starting to think this should be :

callNamed!(fun,`x`, `y`)(10,20);

But I'm not sure of all the pro and cons.
Dmitry Olshansky
2013-03-22 20:02:00 UTC
Permalink
Post by timotheecour
so i hacked up a working solution yesterday.
advantages over
no need to no arguments at CT (just names); allows optional and non
optional ones; allows return value; also, mambo depends on tango and
is hard to revive.
More later.
https://github.com/timotheecour/dtools/blob/master/dtools/util/functional.d
rdmd --main -unittest dtools/util/functional.d
auto s=callNamed!(fun,`x,y`)(10,20);
auto fun(int x,int y=2,double z=z_val, string z2="asdf");
Compile time errors will occur on duplicate param names, or ones that
don't exist, or ones that are not optional and not provided (eg x, above)
Feel free to contribute / comment
Don't have time to look at the code now, but it seems awesome ! Great
leverage of language capabilities. Slightly different from my proposal,
but I'm really not sure which interface fit best. I'm starting to think
callNamed!(fun,`x`, `y`)(10,20);
Can opDispatch & chaining be leveraged to get the effect of:
named!(fun).x(10).y(20).call();

Or maybe even simpler?
But I'm not sure of all the pro and cons.
--
Dmitry Olshansky
Jacob Carlborg
2013-03-23 15:43:46 UTC
Permalink
Post by Dmitry Olshansky
named!(fun).x(10).y(20).call();
Here you go:

http://pastebin.com/ALaXLgt3

Use that together with "callNamed" from timotheecour.
--
/Jacob Carlborg
J
2013-03-23 05:43:21 UTC
Permalink
Post by timotheecour
auto s=callNamed!(fun,`x,y`)(10,20);
Thanks, but this is a non-solution.

The name must be next to the value ( x=10, y=20), so they it will
scale from 2 to 7 to 17 arguments and maintain readability.
J
2013-03-23 08:20:17 UTC
Permalink
Post by J
Post by timotheecour
auto s=callNamed!(fun,`x,y`)(10,20);
Thanks, but this is a non-solution.
The name must be next to the value ( x=10, y=20), so they it
will scale from 2 to 7 to 17 arguments and maintain readability.
For a use case, compare this call

reflectAndTranslate(2, 4, 5, 6, 1, 2, false, true, 15, false,
true, false);


Quick, without looking at the docs, what does the false after 15
do?

It's very hard to tell. Compare that to:


reflectAndTranslate(x=2, y=4, z=5, offset=6, alpha=1, beta=2,
invert=false, twist=true, colorBrush=15, stideReduce=false,
bindMatrix=true, slow=false);


It's self documenting.
deadalnix
2013-03-23 14:49:13 UTC
Permalink
Post by J
Post by J
Post by timotheecour
auto s=callNamed!(fun,`x,y`)(10,20);
Thanks, but this is a non-solution.
The name must be next to the value ( x=10, y=20), so they it
will scale from 2 to 7 to 17 arguments and maintain
readability.
For a use case, compare this call
reflectAndTranslate(2, 4, 5, 6, 1, 2, false, true, 15, false,
true, false);
Quick, without looking at the docs, what does the false after
15 do?
reflectAndTranslate(x=2, y=4, z=5, offset=6, alpha=1, beta=2,
invert=false, twist=true, colorBrush=15, stideReduce=false,
bindMatrix=true, slow=false);
It's self documenting.
I'd argue that with or without named parameter, that code is ugly
as hell.

First, boolean can be replaced by enums for great benefice.
Secondly, the usage of struct would also improve things quite a
lot (x, y, z) is a point or a vector or something.

At the end, it is about giving semantic to your code.

BTW, monadic style named parameters have been proposed earlier,
and I have to say this is really nice.
Jacob Carlborg
2013-03-21 19:59:01 UTC
Permalink
On 2013-03-21 19:35, J wrote:

Here's another workaround:
https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135
--
/Jacob Carlborg
bearophile
2013-03-21 20:33:25 UTC
Permalink
Post by Jacob Carlborg
https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135
Maybe such two links should go in one page of the D wiki about
lack of named parameters workarounds.

Eventually D should introduce a syntax for named arguments at the
call point plus a syntax to deprecate argument names. It's not
the most important thing that D currently lacks, but it's an
improvement.

Bye,
bearophile
Jacob Carlborg
2013-03-21 20:57:35 UTC
Permalink
Maybe such two links should go in one page of the D wiki about lack of
named parameters workarounds.
Eventually D should introduce a syntax for named arguments at the call
point plus a syntax to deprecate argument names. It's not the most
important thing that D currently lacks, but it's an improvement.
What do you think about my suggestion for anonymous structs as named
parameters?

http://forum.dlang.org/thread/kfbnuc$1cro$1 at digitalmars.com?page=1
--
/Jacob Carlborg
bearophile
2013-03-21 21:18:06 UTC
Permalink
Post by Jacob Carlborg
What do you think about my suggestion for anonymous structs as
named parameters?
You show code like:

void foo ({ int x, int y } point)
{
}

foo({ y: 5, x: 3 });


D already has two kinds of tuples so I don't want a "third kind"
of tuple. What I want is D to manage better the Phobos Tuple we
already have, adding an unpacking syntax
(http://forum.dlang.org/thread/gridjorxqlpoytuxwpsg at forum.dlang.org
). (This is not supposed to solve the named arguments problem).

Bye,
bearophile
Jacob Carlborg
2013-03-22 07:28:04 UTC
Permalink
Post by bearophile
void foo ({ int x, int y } point)
{
}
foo({ y: 5, x: 3 });
D already has two kinds of tuples so I don't want a "third kind" of
tuple. What I want is D to manage better the Phobos Tuple we already
have, adding an unpacking syntax
(http://forum.dlang.org/thread/gridjorxqlpoytuxwpsg at forum.dlang.org ).
(This is not supposed to solve the named arguments problem).
This is not a tuple, it's an anonymous struct.
--
/Jacob Carlborg
J
2013-03-21 20:42:32 UTC
Permalink
Post by Jacob Carlborg
https://github.com/jacob-carlborg/mambo/blob/master/mambo/util/Reflection.d#L135
Intriguing, Jacob! I could learn alot about reflection by
studying your code.

How is it installed? I installing by downloading that single
file, and with a quick hack to the Reflection.d top three lines
(commenting out the module and imports at the top), I tried
calling it with this, no luck:

#!/usr/bin/rdmd

import Reflection; // with module and imports commented out...
import std.stdio;

string my(int a, int b) {
writeln(a/b);
return "howdy";
}

void main(string[] arg) {

auto s = callWithNamedArguments(my, `a=3, b=4`);
}

// yields:

$ ./ref.d
./ref.d(13): Error: function ref.my (int a, int b) is not
callable using argument types ()
./ref.d(13): Error: expected 2 function arguments, not 0
Jacob Carlborg
2013-03-21 20:58:19 UTC
Permalink
Intriguing, Jacob! I could learn alot about reflection by studying your
code.
How is it installed? I installing by downloading that single file, and
with a quick hack to the Reflection.d top three lines (commenting out
#!/usr/bin/rdmd
import Reflection; // with module and imports commented out...
import std.stdio;
string my(int a, int b) {
writeln(a/b);
return "howdy";
}
void main(string[] arg) {
auto s = callWithNamedArguments(my, `a=3, b=4`);
}
$ ./ref.d
./ref.d(13): Error: function ref.my (int a, int b) is not callable using
argument types ()
./ref.d(13): Error: expected 2 function arguments, not 0
It's been quite a while since I tested that code. I'll see what I can do.
--
/Jacob Carlborg
Jacob Carlborg
2013-03-25 16:03:37 UTC
Permalink
On 2013-03-21 19:35, J wrote:

[snip]

I just noticed that Michel Fortin has implemented basic support for
named parameters. I've updated his code to the latest DMD and pushed it
to my fork:

https://github.com/jacob-carlborg/dmd/commit/e363a093040c4b14e7e814027c3e199676c82820

From the commit message:

Add basic support for named parameters.

This will only allow to add the name of the parameter
when calling a function. It doesn't not support passing
the arguments out of order.

All credit goes to Michel Fortin.
--
/Jacob Carlborg
J
2013-03-25 18:11:52 UTC
Permalink
Post by Jacob Carlborg
[snip]
I just noticed that Michel Fortin has implemented basic support
for named parameters. I've updated his code to the latest DMD
https://github.com/jacob-carlborg/dmd/commit/e363a093040c4b14e7e814027c3e199676c82820
Add basic support for named parameters.
This will only allow to add the name of the parameter
when calling a function. It doesn't not support passing
the arguments out of order.
All credit goes to Michel Fortin.
+1000

Excellent!
J
2013-03-26 08:16:40 UTC
Permalink
Post by J
Post by Jacob Carlborg
[snip]
I just noticed that Michel Fortin has implemented basic
support for named parameters. I've updated his code to the
https://github.com/jacob-carlborg/dmd/commit/e363a093040c4b14e7e814027c3e199676c82820
Add basic support for named parameters.
This will only allow to add the name of the parameter
when calling a function. It doesn't not support passing
the arguments out of order.
All credit goes to Michel Fortin.
+1000
Excellent!
Wow. This is really nice! I added a method to Michel's nice
work. You can get it in this branch.

https://github.com/glycerine/dmd/tree/namedarg

All the dmd test suite then passes.

You can now do this:

void test (double y, double z, int a, int b, int c, string d) { }

void main ()
{
test(y: 33.3,
z: 44.4,
a: 9999,
b: 8888,
7777, // truly optional
d:"Yehaw");
}


I also tested the passing of named parameters through variadic
templates, and there is a little work needed to make them 'named
argument' aware. I added a failing test for that, if anyone wants
to tackle it. It is dmd/test/compilable/namedarg_vararg.d in the
branch above.

$ cat namedarg_vararg.d
cat namedarg_vararg.d
import core.vararg;
import std.stdio;

void test(A...)(A a)
{
foreach(t; a)
writeln(t);
}

void main ()
{
test(x:33.3,
z: 44.4,
a: 9999,
b: 8888,
7777,
d:"Yehaw");
}

$ dmd namedarg_vararg.d
namedarg_vararg.d(12): Error: template
namedarg_vararg.test(A...)(A a) cannot deduce template function
from argument types
!()(x:double,z:double,a:int,b:int,int,d:string)
$

* * *

Wierd and cool: Since the current version requires the exact same
positions as names, it is almost like you get extra refined type
safety for free. Say I have a function that takes two strings.
The compiler can now help me if I mistakenly switch the two...

Example:

void find(string needle, string haystack) { }
void main ()
{
find(haystack: "abcdefg",
needle: "def");
}

dmd can now helpfully point out:

namedarg_haystack.d(6): Error: function namedarg_haystack.find
(string needle, string haystack) is not callable using argument
types (haystack:string,needle:string)

Nice. This has a different feel to it than where the compiler
just 'makes it right' for you, but I still really like it. Super
readable.
renoX
2013-03-26 09:31:51 UTC
Permalink
On Monday, 25 March 2013 at 16:03:38 UTC, Jacob Carlborg wrote:
[cut]
Post by Jacob Carlborg
Add basic support for named parameters.
This will only allow to add the name of the parameter
when calling a function. It doesn't not support passing
the arguments out of order.
All credit goes to Michel Fortin.
Interesting, the "doesn't not support passing the arguments out
of order." can be seen either as a (temporary or not)
implementation limitation OR as a feature.

The things to check is how this feature would work with optional
parameters..

renoX
Jacob Carlborg
2013-03-26 12:14:07 UTC
Permalink
Interesting, the "doesn't not support passing the arguments out of
order." can be seen either as a (temporary or not) implementation
limitation OR as a feature.
I would guess it was easier. At least the change is very small. Smaller
that I would have imagined.
The things to check is how this feature would work with optional
parameters..
Good point.
--
/Jacob Carlborg
J
2013-03-26 22:26:03 UTC
Permalink
Post by Jacob Carlborg
Post by renoX
Interesting, the "doesn't not support passing the arguments
out of
order." can be seen either as a (temporary or not)
implementation
limitation OR as a feature.
I would guess it was easier. At least the change is very small.
Smaller that I would have imagined.
Post by renoX
The things to check is how this feature would work with
optional
parameters..
Good point.
Tested this. Seems to work fine with optional parameters.

import std.stdio;
void test (int a, int b = 24, int c = 12, int d = 6, int e = 3)
{
writeln(a);
writeln(b);
writeln(c);
writeln(d);
writeln(e);
}

void main ()
{
test(a: 1,
2,
c: 9999);

}

// output:

$ ./namedarg_defaults
1
2
9999
6
3
Timothee Cour
2013-03-27 03:29:15 UTC
Permalink
Interesting, the "doesn't not support passing the arguments out of order." can be seen either as a (temporary or not) implementation >>limitation OR as a feature.
Named parameters are only interesting if we can skip some optional parameters.
This allows the python-like syntax of specifying only a subset of
parameters; otherwise this isn't very interesting. This is used
heavily in python and makes code
* self-documenting
* avoids DRY (don't specify unused params)
* avoids boilerplate of introducing auxiliary option structs and fields to it

Here are just 3 examples that hopefully will convince some that named
params are useful and not ugly.

----
//inspired from python's matplotlib; many more options configurable,
which are set to reasonable defaults
plot(x=1,y=2,color='red',width=3);

//here's another one (cf inspired by scons / waf build tools in python)
compile(input=["foo.cpp"] , run=true, debug=true, ldflags="-lcurl",
output_dir="build");

//other example: setting optional params in a classifier
trainSVM(input=X, labels=Y, C=1000, crossValidate=true, loss=squareHingeLoss)
----

Additionally, we should be able to provide arguments out of order and
check at compile time that there are no duplicates and no unexistant
fields. The code i posted with support for
named!plot.x(2).color("red").width(3)
did that, and that wasn't hard. So hopefully it won't be easy to
support as well skipping, reordering and CT checking with @Michel
Fortin's shiny syntax.

Here are some design decisions to make: given a function void fun(int
a,int b=1, int c=2);

* whether to support mixing named and non-named arguments in 1 call
(python does)
fun(0,b=1)

* whether to allow both calling conventions:
fun(0,1)
fun(0,b=1)

* whether to allow both calling conventions:
fun(0,1)
fun(0,b=1)

* whether to tag functions callable by named params via attribute
(check is done at CT): that'll indicate clearly we want to freeze
names in the API
@named void fun(int a,int b=1, int c=2);

* alternatively to above, whether to use ':' instead of '=' in
function declaration
void fun(int a,int b:1, int c:2); //now it's only callable by name

* whether to support skipping and reordering optional args ; I argued
we need to for this to be useful enough

Timothee Cour
deadalnix
2013-03-27 03:34:14 UTC
Permalink
Post by Timothee Cour
Named parameters are only interesting if we can skip some
optional parameters.
This allows the python-like syntax of specifying only a subset
of
parameters; otherwise this isn't very interesting. This is used
heavily in python and makes code
* self-documenting
* avoids DRY (don't specify unused params)
* avoids boilerplate of introducing auxiliary option structs
and fields to it
Here are just 3 examples that hopefully will convince some that
named
params are useful and not ugly.
----
//inspired from python's matplotlib; many more options
configurable,
which are set to reasonable defaults
plot(x=1,y=2,color='red',width=3);
//here's another one (cf inspired by scons / waf build tools in
python)
compile(input=["foo.cpp"] , run=true, debug=true,
ldflags="-lcurl",
output_dir="build");
//other example: setting optional params in a classifier
trainSVM(input=X, labels=Y, C=1000, crossValidate=true,
loss=squareHingeLoss)
----
How is that any better than the monadic solution proposed in the
thread and that dn't require any language addition ?
J
2013-03-27 06:45:57 UTC
Permalink
Post by Timothee Cour
Post by renoX
Interesting, the "doesn't not support passing the arguments
out of order." can be seen either as a (temporary or not)
implementation >>limitation OR as a feature.
Named parameters are only interesting if we can skip some
optional parameters.
I'd say named parameters are *more* interesting with skipping and
re-ordering, but still incredibly valuable even without. Let us
get them in people's hands first (and start the addiction process
going...bwahahaha!)

Let people experience first hand how awesome they are in a quick,
doable form.

(Feel free to contribute code that implements those skipping and
re-ordering features...)


Status update: I fixed the only known bug, and added a feature.

a. Named parameters now flow into variadic template arguments
without a hitch.

In other words, this compiles:

void test(A...)(A a) {}
void main ()
{
test(b: 33.3
c: 44.4);
}


b. There is an name-matching escape mechanism now. It uses
_underscores. If your function looks like:

void f(int a, int _b) {}

then you can call it like this:

f(a:1, anyLabelYouWant: 3);

(Actually this was necessitated by how dmd treats variadic actual
arguments; it calls them _param_0, _param_1, ..., internally. I'm
still going to call this escape-mechanism a feature, though.)


Here's the latest (see the named_parameters branch specifically)

https://github.com/glycerine/dmd/tree/named_parameters

This passes all tests.

Try it out. Try and break it.

J
2013-03-26 20:28:36 UTC
Permalink
Post by renoX
The things to check is how this feature would work with
optional parameters..
Another thing to check is whether there is enough information in
the object files to link across separately compiled objects.

Correct me if I'm wrong, but I don't think object files include
the names of struct fields, nor the names of argument parameters.

You might have to do what objective-C does, which is merge the
parameter names into the name of the function.
J
2013-03-26 21:46:51 UTC
Permalink
Post by J
Post by renoX
The things to check is how this feature would work with
optional parameters..
Another thing to check is whether there is enough information
in the object files to link across separately compiled objects.
Correct me if I'm wrong, but I don't think object files include
the names of struct fields, nor the names of argument
parameters.
You might have to do what objective-C does, which is merge the
parameter names into the name of the function.
Or maybe there are no link time issues. If named parameters are
only ever supplying additional type-check-time information, then
there would be zero impact at link time. Correct?
Continue reading on narkive:
Loading...