Re: Is there a nice syntax to achieve optional named parameters?

2019-01-21 Thread John Burton via Digitalmars-d-learn

On Monday, 21 January 2019 at 07:57:58 UTC, Simen Kjærås wrote:

On Saturday, 19 January 2019 at 14:26:31 UTC, Zenw wrote:

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:

[...]


how about this

auto With(string code,T)(T value)
{
with(value)
{
mixin(code ~";");
}
return value;
}

auto window = Window().With!q{title = "My window",width = 
800,fullscreen = true};


The problem with using string mixins like that is when you want 
to use some local variable:


int width = getWidth();
auto window = Window().With!q{width = width};

This would work:

struct Window {
string title;
int width;
bool fullscreen;
}

auto With(T, Args...)(T ctx, Args args) {
static foreach (i; 0..Args.length) {
mixin("ctx."~Args[i].name~" = args[i].value;");
}
return ctx;
}

struct args {
static opDispatch(string _name, T)(T value) {
struct Result {
enum name = _name;
T value;
}
return Result(value);
}
}

unittest {
auto window = Window().With(args.title = "My window", 
args.width = 800, args.fullscreen = true);

assert(window.title == "My window");
assert(window.width == 800);
assert(window.fullscreen == true);
}

However, I don't see that there's all that much gain compared 
to just assigning the fields the normal way.


--
  Simen


Thanks everyone for your advice on this.
I'm decided to just use a parameter structure to pass in. Works 
well and everyone can understand it. The question was really just 
does D offer a nicer way and the answer appears to be "not 
really". But the original approach isn't bad anyway.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-21 Thread Simen Kjærås via Digitalmars-d-learn

On Saturday, 19 January 2019 at 14:26:31 UTC, Zenw wrote:

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
As an example let's say I have a type 'Window' that represents 
a win32 window. I'd like to be able to construct an instance 
of the type with some optional parameters that default to some 
reasonable settings and create the underlying win32 window.


[...]


how about this

auto With(string code,T)(T value)
{
with(value)
{
mixin(code ~";");
}
return value;
}

auto window = Window().With!q{title = "My window",width = 
800,fullscreen = true};


The problem with using string mixins like that is when you want 
to use some local variable:


int width = getWidth();
auto window = Window().With!q{width = width};

This would work:

struct Window {
string title;
int width;
bool fullscreen;
}

auto With(T, Args...)(T ctx, Args args) {
static foreach (i; 0..Args.length) {
mixin("ctx."~Args[i].name~" = args[i].value;");
}
return ctx;
}

struct args {
static opDispatch(string _name, T)(T value) {
struct Result {
enum name = _name;
T value;
}
return Result(value);
}
}

unittest {
auto window = Window().With(args.title = "My window", 
args.width = 800, args.fullscreen = true);

assert(window.title == "My window");
assert(window.width == 800);
assert(window.fullscreen == true);
}

However, I don't see that there's all that much gain compared to 
just assigning the fields the normal way.


--
  Simen


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-19 Thread Zenw via Digitalmars-d-learn

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
As an example let's say I have a type 'Window' that represents 
a win32 window. I'd like to be able to construct an instance of 
the type with some optional parameters that default to some 
reasonable settings and create the underlying win32 window.


[...]


how about this

auto With(string code,T)(T value)
{
with(value)
{
mixin(code ~";");
}
return value;
}

auto window = Window().With!q{title = "My window",width = 
800,fullscreen = true};




Re: Is there a nice syntax to achieve optional named parameters?

2019-01-18 Thread Neia Neutuladh via Digitalmars-d-learn
On Fri, 18 Jan 2019 09:39:31 +, John Burton wrote:
> On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote:
> 
>> struct Config {
>>  string title;
>>  int width;
>> }
>>
>> struct Window {
>>  this(Config config)
> 
> It likely is a bad idea for a small struct like this but if it was much
> bigger would it makes sense to write this as :-
> 
>   this(const ref Config config)
> 
> Which is what you might do in C++ or does D handle this differently?

Creating a window is the dominating cost here. If you're creating enough 
windows that copying them is a problem, you're doing something seriously 
weird and it might be more productive to step back and think about that 
than to switch to const ref.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-18 Thread Kagamin via Digitalmars-d-learn

On Friday, 18 January 2019 at 09:39:31 UTC, John Burton wrote:
It likely is a bad idea for a small struct like this but if it 
was much bigger would it makes sense to write this as :-


this(const ref Config config)

Which is what you might do in C++ or does D handle this 
differently?


For big Config struct it probably doesn't matter, but ref 
parameters don't accept rvalues.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-18 Thread evilrat via Digitalmars-d-learn

On Friday, 18 January 2019 at 09:39:31 UTC, John Burton wrote:

On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote:


struct Config
{
string title;
int width;
}

struct Window
{
this(Config config)


It likely is a bad idea for a small struct like this but if it 
was much bigger would it makes sense to write this as :-


this(const ref Config config)

Which is what you might do in C++ or does D handle this 
differently?


You'd better profile and only then act.
Seriously, whatever you know and familiar with in C++ might not 
work with D, you'll just end up with C++'ish code that just 
happens to be written in D.


D is not C++, and such premature optimizations might cause more 
harm if applied on occassion or out of habit.


IIRC D structs are all movable, so doing const refs here and 
there or using writing to ref parameter instead normal 
return(RVO) is likely bad for your code.


D has its own ABI, it's not even compatible with C++, so when you 
pass structs by value it may or may not produce similar asm as 
C++ compilers does.


When struct contains strings/arrays they are anyway managed by 
GC(unless you allocated it on your own), but this is something 
that more seasoned D users can explain in better details and 
cleaner explanation than me, if it means anything at all.


Even without all this, do you really want to mess up your 
codebase with implementation details about how it should do it, 
or write clean (self)documented code? Is it really going to be a 
bottleneck in your program? Passing one big struct at widget's 
creation on program startup and some rare events really going to 
kill performance?
Why not just write working code first and then identify 
bottlenecks and optimize when it absolutely ultimately necessary?
Btw I don't remember much ref parameters in phobos, just look at 
it... I found only 4 ref consts it in std.file, 3 in std.array, 
other modules more likely to have them in comparison operators(I 
have no idea why, to not introduce potential RVO case?) and in 
unit tests for testing correct behavior.


Again, D is not C++, what might work or even considered "good 
practice" there may or may not work here. So just profile it!




Re: Is there a nice syntax to achieve optional named parameters?

2019-01-18 Thread John Burton via Digitalmars-d-learn

On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote:


struct Config
{
string title;
int width;
}

struct Window
{
this(Config config)


It likely is a bad idea for a small struct like this but if it 
was much bigger would it makes sense to write this as :-


this(const ref Config config)

Which is what you might do in C++ or does D handle this 
differently?




Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread Matheus via Digitalmars-d-learn

On Thursday, 17 January 2019 at 16:55:33 UTC, SrMordred wrote:

Yes, but there is a mistake there:
alias is part of the template:

foo(alias x)(){} //note extra parens

than u call like an template:

foo!"a"; //equivalent = foo!("a")();
foo!1;


I see now and thanks.

Matheus.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread kdevel via Digitalmars-d-learn

On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote:

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:


[...]


auto window = Window();
window.title = "My Window";
window.width = 1000;
window.create();


[...]


Is there a better way that's not ugly?


[...]


//usage:
auto a = NewWindow!q{ title : "MainTitle" };
auto b = NewWindow!q{ title : "MainTitle", width : 800 };
auto c = NewWindow!q{ width : 1000 };
auto d = NewWindow!q{};


:)


Put a semicolon instead of the comma in the line "auto b ..." and 
compile.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread SrMordred via Digitalmars-d-learn

On Thursday, 17 January 2019 at 12:11:02 UTC, Matheus wrote:


foo(alias x){}

foo("a");
foo(1);

'x' will be string one time and integer another? Or there is 
something that I'm missing.


Matheus.


Yes, but there is a mistake there:
alias is part of the template:

foo(alias x)(){} //note extra parens

than u call like an template:

foo!"a"; //equivalent = foo!("a")();
foo!1;


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread Matheus via Digitalmars-d-learn

On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote:

Let me throw this idea here:
...


I usually do this too, I like to use struct and then in another 
language I use reflection do optimize binding.


Anyway I understood all your code, except for this "alias code"


auto NewWindow( alias code )()
{
mixin("Config config = {"~code~"};");
return Window(config);
}


Looking on specs: https://dlang.org/spec/declaration.html#alias

"AliasDeclarations create a symbol that is an alias for another 
type, and can be used anywhere that other type may appear."


So with your example imagine this:

foo(alias x){}

foo("a");
foo(1);

'x' will be string one time and integer another? Or there is 
something that I'm missing.


Matheus.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 17, 2019 at 10:29:13AM +, John Burton via Digitalmars-d-learn 
wrote:
[...]
> Well window was just an example really, my real use case is a similar
> object that needs a lot of configuration where mostly the default
> works but you might want to override, and the config is needed to
> create the object in the first place.
[...]

When I encounter similar situations in my code, my go-to solution is to
use a struct with default field values as a configuration object that
you pass to the ctor. You can either pass .init to the ctor to get
default behavior, or declare an instance of the struct and customize as
you see fit before handing it to the ctor.


--T


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread John Burton via Digitalmars-d-learn
On Wednesday, 16 January 2019 at 14:59:01 UTC, Kagamin wrote:> On 
Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
auto window = Window(title = "My Window", width = 1000, 
fullscreen = true);


In this particular case I would make the constructor take 3 
parameters - title, width and height. Full screen is a rare 
functionality and shouldn't clutter the constructor, can it be 
set after the window is created?


Well window was just an example really, my real use case is a 
similar
object that needs a lot of configuration where mostly the default 
works
but you might want to override, and the config is needed to 
create the

object in the first place.

For this example you are right though, and it may be that I'm 
overthinking

the whole thing.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-17 Thread John Burton via Digitalmars-d-learn

On Thursday, 17 January 2019 at 01:43:42 UTC, SrMordred wrote:

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:

[...]


Let me throw this idea here:


struct Config
{
string title;
int width;
}

struct Window
{
this(Config config)
{
//use static foreach magic to set everything :P
}
}

auto NewWindow( alias code )()
{
mixin("Config config = {"~code~"};");
return Window(config);
}

//usage:
auto a = NewWindow!q{ title : "MainTitle" };
auto b = NewWindow!q{ title : "MainTitle", width : 800 };
auto c = NewWindow!q{ width : 1000 };
auto d = NewWindow!q{};


:)


Oh that's interesting!


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-16 Thread SrMordred via Digitalmars-d-learn

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
As an example let's say I have a type 'Window' that represents 
a win32 window. I'd like to be able to construct an instance of 
the type with some optional parameters that default to some 
reasonable settings and create the underlying win32 window.


I'd ideally like some syntax like this :-

auto window = Window(title = "My Window", width = 1000, 
fullscreen = true);


Assume that title, width, fullscreen are optional and if not 
specified there are defaults to use. And that there are many 
other settings than just these 3 that I've chosen to just use 
the default here.


I know that I can't do it like this is D but what is the best 
way to achieve this kind of thing? I can add properties and 
then do a specific "create" function to create the underlying 
win32 window once I'm done but that seems ugly.


auto window = Window();
window.title = "My Window";
window.width = 1000;
window.create();

This is ok, but I'm not so keen on separating the creation and 
construction like this.

Is there a better way that's not ugly?


Let me throw this idea here:


struct Config
{
string title;
int width;
}

struct Window
{
this(Config config)
{
//use static foreach magic to set everything :P
}
}

auto NewWindow( alias code )()
{
mixin("Config config = {"~code~"};");
return Window(config);
}

//usage:
auto a = NewWindow!q{ title : "MainTitle" };
auto b = NewWindow!q{ title : "MainTitle", width : 800 };
auto c = NewWindow!q{ width : 1000 };
auto d = NewWindow!q{};


:)


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-16 Thread Kagamin via Digitalmars-d-learn

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
auto window = Window(title = "My Window", width = 1000, 
fullscreen = true);


In this particular case I would make the constructor take 3 
parameters - title, width and height. Full screen is a rare 
functionality and shouldn't clutter the constructor, can it be 
set after the window is created?


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-16 Thread John Burton via Digitalmars-d-learn

On Wednesday, 16 January 2019 at 11:21:53 UTC, Dukc wrote:

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
This is ok, but I'm not so keen on separating the creation and 
construction like this.

Is there a better way that's not ugly?


You can make the constructor a template that takes a single 
struct of arbitrary, and inspects (at compile time) if it has 
fields with certain names and types. Then, when constructing, 
you feed that constructor a std.typecons.Tuple with named 
fields. Or alternatively, use a separate builder type that 
makes a good struct to feed for the window constructor.


The disadvantage is that you cannot link the constructor 
template directly for external programs. But for that, you 
define some sort of wrapper function that always takes all the 
parameters and then calls the template.


Thanks, I tried out the tuple approach and it works very well.
Constructing a tuple at the point of call with named fields works 
well, but looks a bit "ugly" to me but I might use it.
I think on balance that creating a separate builder struct that I 
can set the fields in and pass to the "real" constructor might be 
the way to go though for me.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-16 Thread JN via Digitalmars-d-learn

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:


auto window = Window();
window.title = "My Window";
window.width = 1000;
window.create();



You can slightly modify it to the way APIs like DirectX or Vulkan 
do it.


auto windowinfo = WindowInfo();
windowinfo.title = "My Window";
windowinfo.width = 1000;

auto window = Window(windowinfo);


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-16 Thread Dukc via Digitalmars-d-learn

On Wednesday, 16 January 2019 at 11:21:53 UTC, Dukc wrote:

a template that takes a single struct of arbitrary,


meant "of arbitrary type"




Re: Is there a nice syntax to achieve optional named parameters?

2019-01-16 Thread Dukc via Digitalmars-d-learn

On Tuesday, 15 January 2019 at 11:14:54 UTC, John Burton wrote:
This is ok, but I'm not so keen on separating the creation and 
construction like this.

Is there a better way that's not ugly?


You can make the constructor a template that takes a single 
struct of arbitrary, and inspects (at compile time) if it has 
fields with certain names and types. Then, when constructing, you 
feed that constructor a std.typecons.Tuple with named fields. Or 
alternatively, use a separate builder type that makes a good 
struct to feed for the window constructor.


The disadvantage is that you cannot link the constructor template 
directly for external programs. But for that, you define some 
sort of wrapper function that always takes all the parameters and 
then calls the template.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-15 Thread John Burton via Digitalmars-d-learn
On Tuesday, 15 January 2019 at 12:15:41 UTC, rikki cattermole 
wrote:

On 16/01/2019 1:05 AM, John Burton wrote:
On Tuesday, 15 January 2019 at 11:26:50 UTC, rikki cattermole 
wrote:

Longer term, you're better off with the builder.

Thanks for your reply. But what is the builder?


https://en.wikipedia.org/wiki/Builder_pattern

One of the few OOP design patterns that I can agree with.


Ah right, that.
Thank you.
Hmm that would work.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-15 Thread rikki cattermole via Digitalmars-d-learn

On 16/01/2019 1:05 AM, John Burton wrote:

On Tuesday, 15 January 2019 at 11:26:50 UTC, rikki cattermole wrote:

Longer term, you're better off with the builder.

Thanks for your reply. But what is the builder?


https://en.wikipedia.org/wiki/Builder_pattern

One of the few OOP design patterns that I can agree with.


Re: Is there a nice syntax to achieve optional named parameters?

2019-01-15 Thread John Burton via Digitalmars-d-learn
On Tuesday, 15 January 2019 at 11:26:50 UTC, rikki cattermole 
wrote:

Longer term, you're better off with the builder.

Thanks for your reply. But what is the builder?


Creating windows is a very complex task that can balloon in 
scope.


Well that was mostly just an example that I thought people could 
relate to more than my obscure real case :) But the principle is 
the same so the answer is likely too




Re: Is there a nice syntax to achieve optional named parameters?

2019-01-15 Thread rikki cattermole via Digitalmars-d-learn
Longer term, you're better off with the builder. Even with named 
parameters (2 DIP's are in the queue for adding it).


Creating windows is a very complex task that can balloon in scope.
Being able to hide it away in a separate type can be quite desirable if 
you want your windowing library to be actually useful in not just one 
simple case.


Of course that doesn't mean you couldn't hide that its there ;)


Is there a nice syntax to achieve optional named parameters?

2019-01-15 Thread John Burton via Digitalmars-d-learn
As an example let's say I have a type 'Window' that represents a 
win32 window. I'd like to be able to construct an instance of the 
type with some optional parameters that default to some 
reasonable settings and create the underlying win32 window.


I'd ideally like some syntax like this :-

auto window = Window(title = "My Window", width = 1000, 
fullscreen = true);


Assume that title, width, fullscreen are optional and if not 
specified there are defaults to use. And that there are many 
other settings than just these 3 that I've chosen to just use the 
default here.


I know that I can't do it like this is D but what is the best way 
to achieve this kind of thing? I can add properties and then do a 
specific "create" function to create the underlying win32 window 
once I'm done but that seems ugly.


auto window = Window();
window.title = "My Window";
window.width = 1000;
window.create();

This is ok, but I'm not so keen on separating the creation and 
construction like this.

Is there a better way that's not ugly?