I was just thinking about porting a javascript function to
D that takes an object of params:
function foo(args) { ... }
foo( { "closeButton" : false, "width" : 200 } );
In D, I figured I'd make args a struct:
struct FooArgs {
bool closeButton = true; // the default is for it to be there
int width = 600;
}
void foo(FooArgs args) { ... }
And, of course, this works, but it was leaving a declared
variable around and can be somewhat repetitive. But first
I tried making it look kinda like the JS:
FooArgs args = { closeButton: false };
foo(args);
But, that style struct initializer doesn't respect the default
values. Here, width == 0. No good.
So, then, well, that's OK, I'll just write it out:
FooArgs args;
args.closeButton = false;
foo(args);
There we go, not too bad at all. We can kill some repetition
of "args" with the with() {} statement. Great!
But, what if I have another call later? I don't want that args
sticking around.
FooArgs args;
// ...
foo(args);
BarArgs args; // error, args already declared
No prob, let's scope it! I tried:
with(FooArgs args) {
closeButton = false;
foo(args);
}
// can redeclare another args here if you want
But it didn't work. It is with(symbol) or with(expression)
in the spec.
Would it work to also allow with(decl)? It seems to me that
it should be ok... kinda similar to the currently allowed
if(auto a = foo()) { /* use a here */ }
So we're just extending that same idea out to the with statement
too.

But it didn't work. It is with(symbol) or with(expression)
in the spec.
Would it work to also allow with(decl)? It seems to me that
it should be ok... kinda similar to the currently allowed
if(auto a = foo()) { /* use a here */ }
So we're just extending that same idea out to the with statement
too.

The more general form would be to make variable declaration an expression. I'm
not sure if that causes any ambiguity, parsing-wise, but it allows other neat
things as well, like while(vardecl) and if (decl1 && condition).

The more general form would be to make variable declaration an
expression.

Right, and that would be pretty amazing, but it would probably
be too hard to do in D today...

The bizarre thing, however, is that the compiler uses it internally.
There's thing called a DeclarationExp. It's created all the time when
lowering occurs.
It"s only in the parser that declarations are not valid as expressions.

But it didn't work. It is with(symbol) or with(expression)
in the spec.
Would it work to also allow with(decl)? It seems to me that
it should be ok... kinda similar to the currently allowed
if(auto a = foo()) { /* use a here */ }
So we're just extending that same idea out to the with statement
too.

The more general form would be to make variable declaration an expression. I'm
not sure if that causes any ambiguity, parsing-wise, but it allows other neat
things as well, like while(vardecl) and if (decl1&& condition).

With the current grammar, it is difficult, because declarations are
statements.

I was just thinking about porting a javascript function to
D that takes an object of params:

Let's not add another special case for the declaration can be used here
instead of an expression. This is already the case in if and it will
proliferate.
The real need here is to allow variable declaration to be used as
expressions. And functions too as they are first class citizens now.
This reduces special cases instead of adding new one, and give a much
greater opportunity for expressiveness in the language.

I can't help thinking it sounds rather like a job for... named
parameters. Just imagine it:

Yeah, that could do it too, but named parameters have been
brought up a few times too and there's opposition to it.
I kinda prefer the struct to named params anyway because
you can store it for later too. But I could go either way.

I can't help thinking it sounds rather like a job for... named
parameters. Just imagine it:

Yeah, that could do it too, but named parameters have been
brought up a few times too and there's opposition to it.
I kinda prefer the struct to named params anyway because
you can store it for later too. But I could go either way.

Oh I know; which is why I wrote in a slightly snarky manner. I
still hold out hope. Your reuse argument for structs is, of
course, completely valid and compelling.
Another possibility, in cases like that presented in the original
post, is to write a single struct to be used with all the
relevant functions -- but then there's the problem of memory
abuse. In some cases it may be fine, but tossing around several
copies of a very large struct, and only using two or three of the
fields in a given case, is just unreasonable.
-- Chris NS