March 02, 2011
On 3/2/11 8:45 AM, Jim wrote:
> In addition to that, named template arguments would allow you to
> create very customizable, yet lean types. It would be possible to
> parameterize all components. Basically, if you're not pleased with
> the default search algorithm or container type of a more complex
> object then you can specify your own.

Got to say, named template arguments would be pretty awesome for policy-based design. There are other ways to deal with that (just accept variadic arguments and detect policies by signatures) but that's less clear for the client and aggravates the library writer.

Andrei
March 02, 2011
On 03/02/2011 02:59 PM, Steven Schveighoffer wrote:
> On Wed, 02 Mar 2011 08:45:43 -0500, Jason E. Aten <j.e.aten@gmail.com> wrote:
>
>> I find this an interesting discussion. Coming from writing alot of code in
>> language that makes extensive and
>> highly effective use of named arguments (R), I can say that optional named
>> arguments
>> (as in Lisp, and descendants like Python and R) do have big software
>> engineering benefits,
>> but also come with a substantial costs in terms of complexity of the
>> function call sequence.
>>
>> That is, named arguments can be expensive in a typical interpreted
>> implementation
>> (probably one reason why R and Python are much slower to execute than the
>> other
>> interpreted languages), presumably because each function call has to
>> invoke hash
>> table lookups to determine the canonical formal position of each actual
>> argument, and deal with variadic
>> cases, to rearrange the order of the arguments to match expectations of the
>> callee.
>>
>> Someone familiar with lisp compilers could probably tell you if the heavy
>> speed tax is intrinsic
>> or just the price of interpretation.
>>
>> It would indeed be an interesting challenge to see if the compile-time
>> metaprogramming
>> features of D would allow one to include named arguments in an opt-in
>> fashion without speed reduction.
>
> Considering that calling a function with parameters by name directly translates
> at compile time to a function call by position, there should be zero speed
> impact. The interpretation of the parameter names, which is done at runtime for
> Python, would be done at compile time in D.
>
> -Steve

I had never thought at that, but I'm surprised: what prevents Python's "compiler" (say, a semantic phase after parsing) to check number and names of arguments. (Number seems not to be checked before runtime neither.)
All required information is in the AST. For named params, Python could translate to position params just like D. This would certainly remove a relevant amount of runtime "speed-down", I guess. (Only type-check of builtin func args must remain at runtime.)

Denis
-- 
_________________
vita es estrany
spir.wikidot.com

March 02, 2011
On 01/03/2011 11:59, spir wrote:
<snip>
> On the other hand, I would like it still be possible to write:
> void f (x=0, y=0) {...}
> ...
> f(y=1);
<snip>

It would.  And it would still set the variable y in the calling scope to 1, and then call f(1, 0).

Stewart.
March 02, 2011
On 3/2/11 8:45 AM, spir wrote:
> I had never thought at that, but I'm surprised: what prevents Python's
> "compiler" (say, a semantic phase after parsing) to check number and
> names of arguments. (Number seems not to be checked before runtime
> neither.)
> All required information is in the AST. For named params, Python could
> translate to position params just like D. This would certainly remove a
> relevant amount of runtime "speed-down", I guess. (Only type-check of
> builtin func args must remain at runtime.)
>
> Denis

What follows is speculation; I'm not a Python programmer, but I am loosely familiar with the language.  If I'm completely wrong, I'm sure someone will point it out:

A Python "compiler" certainly can (and probably does) check function arguments, but the runtime is still heavily involved in argument passing.  The complexity in Python is an artifact of how arguments are delivered at run-time: in a big (dynamically created, of course) dictionary.  Essentially, The interpreter matches argument positions with parameter names -- at run time -- and then supplies those name/argument pairs as entries in the dictionary.  (This is a logical view of the language, and may not precisely match implementations.  For instance, I'd expect that "compiled" .pyc files throw out positional information ahead of time.)  Looked at another way, *everything* is passed by name, not position; positional arguments are merely a shorthand notation.

This is vastly different from how named arguments would be handled in D.  D passes arguments by position -- end of story.  Named arguments provide an alternative method of specifying the position of a given argument, which is determined by the compiler long before the linker or the runtime get involved.
March 02, 2011
On Wed, 02 Mar 2011 13:38:05 -0500, Bekenn <leaveme@alone.com> wrote:

> On 3/2/11 8:45 AM, spir wrote:
>> I had never thought at that, but I'm surprised: what prevents Python's
>> "compiler" (say, a semantic phase after parsing) to check number and
>> names of arguments. (Number seems not to be checked before runtime
>> neither.)
>> All required information is in the AST. For named params, Python could
>> translate to position params just like D. This would certainly remove a
>> relevant amount of runtime "speed-down", I guess. (Only type-check of
>> builtin func args must remain at runtime.)
>>
>> Denis
>
> What follows is speculation; I'm not a Python programmer, but I am loosely familiar with the language.  If I'm completely wrong, I'm sure someone will point it out:
>
> A Python "compiler" certainly can (and probably does) check function arguments, but the runtime is still heavily involved in argument passing.  The complexity in Python is an artifact of how arguments are delivered at run-time: in a big (dynamically created, of course) dictionary.  Essentially, The interpreter matches argument positions with parameter names -- at run time -- and then supplies those name/argument pairs as entries in the dictionary.  (This is a logical view of the language, and may not precisely match implementations.  For instance, I'd expect that "compiled" .pyc files throw out positional information ahead of time.)  Looked at another way, *everything* is passed by name, not position; positional arguments are merely a shorthand notation.
>
> This is vastly different from how named arguments would be handled in D.   D passes arguments by position -- end of story.  Named arguments provide an alternative method of specifying the position of a given argument, which is determined by the compiler long before the linker or the runtime get involved.

Not a python expert either, but I think you are right.

Most dynamic languages are this way -- because you need that flexibility since a "compiled" script might not be recompiled after you change the API.

And also, many dynamic languages allow changing the API mid-program (not sure about python).  There would just be no way to determine this at compile time.

-Steve
March 07, 2011
(De-lurking; I've been interested in D for a while, but my programming is almost exclusively in C -- generally C99.)

Does D have the equivalent of C99's "designated initializers"?

Were I to attempt something like this in C, the code would go something like this:

    int foo(int height, int width);
    struct _foo_args {
        int height; int width;
    };
    #define foo(...) \
        foo((struct _foo_args){__VA_ARGS__}.height, \
            (struct _foo_args){__VA_ARGS__}.width)

at which point each of these calls:

    foo(a, b);
    foo(.height = a, .width = b);
    foo(.width = b, .height = a);

have the same effect.

I'll readily admit this is *not* pretty, and likely more effort than it's worth, but is will work.

Are D's compile-time operations not capable of something at *least* this powerful?

--Joel
March 07, 2011
On Sunday 06 March 2011 16:57:17 Joel C. Salomon wrote:
> (De-lurking; I've been interested in D for a while, but my programming is almost exclusively in C -- generally C99.)
> 
> Does D have the equivalent of C99's "designated initializers"?
> 
> Were I to attempt something like this in C, the code would go something like this:
> 
>     int foo(int height, int width);
>     struct _foo_args {
>         int height; int width;
>     };
>     #define foo(...) \
>         foo((struct _foo_args){__VA_ARGS__}.height, \
>             (struct _foo_args){__VA_ARGS__}.width)
> 
> at which point each of these calls:
> 
>     foo(a, b);
>     foo(.height = a, .width = b);
>     foo(.width = b, .height = a);
> 
> have the same effect.
> 
> I'll readily admit this is *not* pretty, and likely more effort than it's worth, but is will work.
> 
> Are D's compile-time operations not capable of something at *least* this powerful?

D doesn't have macros. It has incredibly powerful templates as well as string mixins, but no macros. So, what D has tends to be very powerful, but there are times when it's more verbose to use than a C macro might be, and there are some things that you can do with C macros that you can't readily do in D (though there are a lot of things that yo ucan do with D templates that you could never do with C macros or even C++ templates - or if you can, it's a _lot_ harder in C++). It's a lot safer and less error-prone that way though.

In this case, you could do something like this:

int width;
int height;

func(width = 2, height = 7);

That _is_ a bit wasteful though in that it's assigning to local variables which are likely never used after that. Regardless, I don't think that you can do something quite like what you're trying to do. If nothing else, I don't think that D has anything like C99's designated initializers. It has constructors.

- Jonathan M Davis
March 07, 2011
Joel C. Salomon:

> Does D have the equivalent of C99's "designated initializers"?

D2 currently allows code like this (but I don't know if this will be deprecated, for me sometimes is not easy to remember all things that will be deprecated):

struct Foo { int x, y, z; }
Foo f1 = { x:1, y:2 };
Foo f2 = { x:1, z:2 };
void main() {}

Bye,
bearophile
March 08, 2011
On 28/02/2011 21:38, Don wrote:
>
> But I still don't see the need for this feature. Aren't people using
> IDEs where the function signature (with parameter names) pops up when
> you're entering the function, and when you move the mouse over the
> function call?
> And if you really want to see them all the time, why not build that
> feature into the IDE?
> ("hit ctrl-f9 to show all parameter names, hit it again to hide them").

That's exactly the point I was going to make, as soon as I saw the question/challenge of "    HRESULT hr = m_Device.Present(null, null, null, null);

Quick: What behavior does that third argument specify?"

For such a fine grained and common situation, looking that API up anywhere outside the IDE (such as in a webpage, or in a file in a filesystem) in any serious development just seems to me very archaic. But hey, maybe I'm just spoiled by Java... :P

-- 
Bruno Medeiros - Software Engineer
March 08, 2011
On 28/02/2011 22:13, bearophile wrote:
>> But I still don't see the need for this feature. Aren't people using
>> >  IDEs where the function signature (with parameter names) pops up when
>> >  you're entering the function, and when you move the mouse over the
>> >  function call?
> If you print code on a book or you show code on the web, etc, you don't have an IDE to help you.
> D isn't designed to require an IDE. And C# devs have added named arguments even if most C# programmers use an IDE.
>
> Bye,
> bearophile

This doesn't make it *required* to have an IDE. It perhaps just makes it better.

The question that should be asked is if D should be optimized for IDE usage or not...

-- 
Bruno Medeiros - Software Engineer