www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [variadics] syntactical sugar

reply Manfred Nowak <svv1999 hotmail.com> writes:
The possibility to implement lists of equally typed formal parameters 
with variadics again raises the question of syntactical sugar to 
prevent ugliness.

For example a list of structs created on the fly currently would look 
at best like

1:  func( _( 1, "qwert"), _( 2, "asdf"), _( 3, "zxcv"));

If static initialization would be allowed:

2:  func( { 1, "qwert"}, { 2, "asdf"}, { 3, "zxcv"});

For me both possibilities look at bit uglier than:

3:  func( 1, "qwert")( 2, "asdf")( 3, "zxcv");

for which already was written, that it looks ugly enough to not use 
such notification. 

So I again come up with the suggestion of a semicolon to separate the 
individual actual parameter lists:

4:  func( 1, "qwert"; 2, "asdf"; 3, "zxcv");

What do you suggest?

-manfred
Aug 16 2005
next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
I'm confused. What is the signature of func? What use cases did you have in 
mind?

"Manfred Nowak" <svv1999 hotmail.com> wrote in message 
news:ddtpfs$17c2$1 digitaldaemon.com...
 The possibility to implement lists of equally typed formal parameters
 with variadics again raises the question of syntactical sugar to
 prevent ugliness.

 For example a list of structs created on the fly currently would look
 at best like

 1:  func( _( 1, "qwert"), _( 2, "asdf"), _( 3, "zxcv"));

 If static initialization would be allowed:

 2:  func( { 1, "qwert"}, { 2, "asdf"}, { 3, "zxcv"});

 For me both possibilities look at bit uglier than:

 3:  func( 1, "qwert")( 2, "asdf")( 3, "zxcv");

 for which already was written, that it looks ugly enough to not use
 such notification.

 So I again come up with the suggestion of a semicolon to separate the
 individual actual parameter lists:

 4:  func( 1, "qwert"; 2, "asdf"; 3, "zxcv");

 What do you suggest?

 -manfred 

Aug 16 2005
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
"Ben Hinkle" <ben.hinkle gmail.com> wrote:

 I'm confused. What is the signature of func? What use cases did
 you have in mind?

Ooops, already in that matter for some days I did not realizee, that there might be a difficulty to see what I mean from the specs, that allow lists of arguments of same type T to be declared like: Answering your first question: void func( T[] param ...){ }; If T is a primary type like `int' a call with literals would look like this: func( 1, 2, 3, 4); If you are to use different types in the list, there is currently no solution with variadics, except that there is some regularity in the list, so that you can join adjacent parameters into a struct. If T is a class or a struct S: struct S{ int i; char[] s; } a call with literals is not possible that easily. The known technic is to insert an opCall into struct S that initiliazes the struct S and returns it: S opCall( int ii, char[] si){ i= ii; s= si; return *this; } Thus one can code: void func( S[] param ...){ }; S _; func( _( 1, "qwert"), _( 2, "asdf")); Answering your second question: a) Why didn't you ask that Walter when he introduced this feature with version 0.126? b) I am interested in features like this since a long time: D/26867 c) I use this feature for initializations x.init( 1, 2, 3, 6); or when I have to check whether a particular instance is in a given fixed set of possibilities: firstIsIn( _( x, y), _( 1, 2), _( 3, 6) ); I would prefer to write: firstIsIn( x, y; 1, 2; 3, 6 ) -manfred
Aug 16 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Manfred Nowak" <svv1999 hotmail.com> wrote in message 
news:ddu0b8$1dbm$1 digitaldaemon.com...
 "Ben Hinkle" <ben.hinkle gmail.com> wrote:

 I'm confused. What is the signature of func? What use cases did
 you have in mind?

Ooops, already in that matter for some days I did not realizee, that there might be a difficulty to see what I mean from the specs, that allow lists of arguments of same type T to be declared like: Answering your first question: void func( T[] param ...){ }; If T is a primary type like `int' a call with literals would look like this: func( 1, 2, 3, 4); If you are to use different types in the list, there is currently no solution with variadics, except that there is some regularity in the list, so that you can join adjacent parameters into a struct. If T is a class or a struct S: struct S{ int i; char[] s; } a call with literals is not possible that easily. The known technic is to insert an opCall into struct S that initiliazes the struct S and returns it: S opCall( int ii, char[] si){ i= ii; s= si; return *this; } Thus one can code: void func( S[] param ...){ }; S _; func( _( 1, "qwert"), _( 2, "asdf"));

OK - I see what you mean. (ps - love the _ :-)
 Answering your second question:

 a) Why didn't you ask that Walter when he introduced this feature
 with version 0.126?

The typesafe vararg is fine with me. I was asking for use cases for the special struct sugar.
 b) I am interested in features like this since a long time:
 D/26867

Yeah I remember those. That was when vararg discussions were all the rage and how to do printf or C++ <<-style io etc etc. Fun stuff.
 c) I use this feature for initializations

   x.init( 1, 2, 3, 6);

You mean for some init(int[] param ...), I presume. In other words the init call above works today, correct?
 or when I have to check whether a particular instance is in a given
 fixed set of possibilities:

  firstIsIn( _( x, y),
             _( 1, 2), _( 3, 6)
           );

 I would prefer to write:

  firstIsIn( x, y;
             1, 2;  3, 6
           )

What does firstIsIn do? I'm not getting it. But this was exactly what I was looking for when I asked for use cases. By "use case" I mean a (preferrably common) coding pattern or construct that would be made much easier with this sugar. Stepping back I wonder if the oft-requested ability to create structs in expressions would be good enough. The firstIsIn(x,y;1,2;3,6) is definitely the most compact syntax we could use but why add a special case for the nearly equally simple firstIsIn(S{x,y},S{1,2},S{3,6}) or whatever the magic syntax will be for struct-expressions. The struct S already needs to be defined in order to write the declaration of firstIsIn (unless you also want to change the syntax for typesafe varargs).
 -manfred 

Aug 16 2005
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
"Ben Hinkle" <ben.hinkle gmail.com> wrote:

[...]
 You mean for some init(int[] param ...), I presume. In other
 words the init call above works today, correct?

Yes, that works.
 or when I have to check whether a particular instance is in a
 given fixed set of possibilities:


 What does firstIsIn do? I'm not getting it. But this was exactly
 what I was looking for when I asked for use cases. By "use case"
 I mean a (preferrably common) coding pattern or construct that
 would be made much easier with this sugar.

Because it is sugar only, there is no case where the "much" is justified. The coding pattern you ask for I already described above: "check whether a particular instance is in a given fixed set of possibilities". Therefore in the given example firstIsIn checks, whether the coordinate (x,y) is in the set of coordinates that follows. In the example a set consisting of the two coordinates {(1,2), (3,6)}. But the list might also be interpreted as a list of rectangles. Then firstIsIn checks whether ( x, y) is in the rectangle denoted by the coordinates ( (1,2) , ( 3,6)).
 Stepping back I wonder if the oft-requested ability to create
 structs in expressions would be good enough. The
 firstIsIn(x,y;1,2;3,6) is definitely the most compact syntax we
 could use but why add a special case for the nearly equally
 simple firstIsIn(S{x,y},S{1,2},S{3,6}) or whatever the magic 
 syntax will be for struct-expressions. The struct S already
 needs to be defined in order to write the declaration of
 firstIsIn (unless you also want to change the syntax for
 typesafe varargs). 

Right, the struct S and the opCalls of S has to be defined in order to use `firstIsIn' in this example. And yes, in this example the suggested syntax sugar saves only three characters per instantiation. But when I introduced the FSM on signatures, in my post mentioned above, there were replies that a surplus of only one character per instantiation renders my suggestion at that time as unusable: the one additional character in `)(' against `;'. But the mere syntax sugar, that my suggestion is in this case may turn out to be really usefull in other cases of variadics. In digitalmars.D.bugs/4713 I posted, that an ambiguity using variadics is currently not detected. But the ambiguity stems from the fact, that the start of the parameter list for the instantiation of the class currently can not be marked sufficiently enough. If a semicolon must be used to mark the start of the parameter list for the instantiation the call test( 1, 1) must belong to the overload void test( Foo f ...){} and the call test( 1; 1) must belong to the overload void test( int x, Foo f ...){} Because I have not thaught of this usage before, my suggestion may turn out, to be not only syntactical sugar. -manfred
Aug 16 2005
parent AJG <AJG_member pathlink.com> writes:
Hi,

But the ambiguity stems from the fact, that the start of the 
parameter list for the instantiation of the class currently can not 
be marked sufficiently enough. If a semicolon must be used to mark 
the start of the parameter list for the instantiation the call
  test( 1, 1) 
must belong to the overload
  void test( Foo f ...){}
and the call
  test( 1; 1) 
must belong to the overload
  void test( int x, Foo f ...){}

Hm... I think I agree with the syntax you propose. It makes sense to delineate clearly which subset(s) of the parameter list belongs to which of 1) object instantiation 2) struct creation. 3) regular parameter. Cheers, --AJG.
Aug 16 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 16 Aug 2005 22:31:24 +0000 (UTC), Manfred Nowak wrote:

 The possibility to implement lists of equally typed formal parameters 
 with variadics again raises the question of syntactical sugar to 
 prevent ugliness.

[snip]
 
 So I again come up with the suggestion of a semicolon to separate the 
 individual actual parameter lists:
 
 4:  func( 1, "qwert"; 2, "asdf"; 3, "zxcv");

Just to clarify, this is a proposal to enable us to code struct literals as function arguments, right? How often is that actually used by people? -- Derek (skype: derek.j.parnell) Melbourne, Australia 17/08/2005 9:12:31 AM
Aug 16 2005
parent Manfred Nowak <svv1999 hotmail.com> writes:
Derek Parnell <derek psych.ward> wrote:

[...]
 Just to clarify, this is a proposal to enable us to code struct
 literals as function arguments, right? How often is that
 actually used by people? 

Not only struct literals can be used, but also instantiating classes and calling further variadics According to your question: please look at my answer to Bens post and then: I do not know an answer to your question because currently nobody is forced to report his uses to me and I also believe that only very few users of D have already realized the benefits of programming with list-like structures. If your question is to be taken more abstract in the sense of how much will this feature be used in the future, I declare to be willing to give an answer after you have stated the same thing you ask me for all the features that are already in the language. My answer will follow the guidance you will give for justifying your estimations. -manfred
Aug 16 2005