Re: tuples from text file

2017-12-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/19/17 7:47 PM, codephantom wrote:

so I have a text file containing 3 lines(e.g):

5, "hello", 4.3
"hello", 4.3
"hello", "world", 1, 2, 3, 5.5

Now I want to create tuples from each line.

However, (using line 1 as example), I get:

Tuple!string("5, \"hello\", 4.3")

but I really want:

Tuple!(int, string, double)(5, "hello", 4.3)

I know why - because a line is a string.

But anyone got an idea on how to extract the string into separate 
elements that can be correctly 'tuple'd" according to the type of each 
element?


Well, you need to know at compile time the types you are expecting. Then 
you just parse them out.


You can't decide tuples at runtime.

-Steve


Re: Tuples not working?

2015-01-09 Thread Ali Çehreli via Digitalmars-d-learn

On 01/09/2015 10:42 AM, Jonathan Marler wrote:

import std.stdio;
import std.typecons;
void main()
{
   alias TL = Tuple!(int, long, float);
   foreach (i, T; TL)
 writefln(TL[%d] = %s, i, typeid(T));
}

Why is this not working?

D:\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(419): Error: need
'this' for '_expand_field_0' of type 'int'
D:\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(419): Error: need
'this' for '_expand_field_1' of type 'long'
D:\dmd2\windows\bin\..\..\src\phobos\std\typecons.d(419): Error: need
'this' for '_expand_field_2' of type 'float'

Tried to compile using dmd 2.066 and dmd 2.067.  Code taken directly
from dlang website here (http://dlang.org/tuple.html). Thanks.


Broken documentation presumable because the feature changed later on. 
The code works if you we std.typetuple.TypeTuple:


import std.stdio;
import std.typetuple;

void main()
{
  alias TL = TypeTuple!(int, long, float);
  foreach (i, T; TL)
  writefln(TL[%d] = %s, i, typeid(T));
}

Ali



Re: Tuples printing

2014-07-05 Thread FrankLike via Digitalmars-d

[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
Good idea.
And shoud easy to be used by foreach.

Frank




Re: Tuples printing

2014-07-03 Thread H. S. Teoh via Digitalmars-d
On Thu, Jul 03, 2014 at 09:52:35AM +, bearophile via Digitalmars-d wrote:
[...]
 void main() {
 import std.stdio, std.typecons;
 
 alias RGB = Tuple!(ubyte,R, ubyte,G, ubyte,B);
 const arr = [RGB(1, 2, 3), RGB(4, 5, 6), RGB(7, 8, 9)];
 
 writeln(arr);
 }
 
 
 It prints:
 
 [const(Tuple!(ubyte, R, ubyte, G, ubyte, B))(1, 2, 3),
 const(Tuple!(ubyte, R, ubyte, G, ubyte, B))(4, 5, 6),
 const(Tuple!(ubyte, R, ubyte, G, ubyte, B))(7, 8, 9)]
 
 
 If your range of tuples grows larger, the printing becomes too much
 long and too much noisy. The signal gets almost lots.
 
 A simple solution is to print tuples inside ranges as just (field1,
 field2, ...), and keep the same printing style if you print a single
 tuple:
 
 writeln(RGB(1, 2, 3))
 writeln(arr);
 ==
 Tuple!(ubyte, R, ubyte, G, ubyte, B))(1, 2, 3)
 [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
[...]

I like this idea.

Looking at the code, it seems that Tuple.toString was specifically
written to output tuples in the current format, though admittedly it's
rather verbose. We *could* probably overload/rewrite it so that it
permits %(...%) format specifiers, upon which the user could specify a
different format, like the ones you suggested.

(This could constitute a legitimate (rather than toy) use case for
custom format specifiers, that I've written about. :-P)


T

-- 
MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs


Re: Tuples and compile-time assigned properties

2013-09-19 Thread Joseph Rushton Wakeling

On 19/09/13 17:21, Dicebot wrote:

+1 Why do you need to use tuples and manually force them into struct behavior
instead of simply using structs?


I guess I was thinking it'd be more finnicky to do something like

   struct EdgeProperties { double weight; }

   struct VertexProperties { size_t colour; string name; }

   auto g = Graph!(EdgeProperties, VertexProperties);

... than to allow the user the flexibility of just knocking up a Tuple in the 
moment.  But now that I think about it, it's not actually more complicated really.


Re: Tuples and compile-time assigned properties

2013-09-19 Thread Dicebot
On Thursday, 19 September 2013 at 14:56:08 UTC, Artur Skawina 
wrote:
I'm not sure i understand your problem, but you could use 
structs. ie:


   struct VertexProperties {
  size_t color;
  string name;
   }

You can get the field names and types at CT and work with that.


+1 Why do you need to use tuples and manually force them into 
struct behavior instead of simply using structs?


Re: Tuples and compile-time assigned properties

2013-09-19 Thread Artur Skawina
On 09/19/13 16:40, Joseph Rushton Wakeling wrote:
 alias EdgeProperties = Tuple!(double, weight);
 
 alias VertexProperties = Tuple!(size_t, colour, string, name);
 
 So then, you'd be able to extract the list of variable names and types at 
 compile time and use them to create the underlying data structures required; 
 and similarly you'd be able to create a set of public interfaces that gives 
 you access to those members.
 
 With that in mind, there are a number of potential issues that arise:
 
(i) is there a compile-time constraint via which I can insist that every
member of the tuple must be named?
 
   (ii) is there an easy way to extract all the names of tuple members as an
array of strings?
 
 Can anyone advise?

I'm not sure i understand your problem, but you could use structs. ie:

   struct VertexProperties {
  size_t color;
  string name;
   }

You can get the field names and types at CT and work with that.


artur


Re: Tuples and compile-time assigned properties

2013-09-19 Thread Joseph Rushton Wakeling

On 19/09/13 16:55, Artur Skawina wrote:

I'm not sure i understand your problem, but you could use structs. ie:

struct VertexProperties {
   size_t color;
   string name;
}

You can get the field names and types at CT and work with that.


Yes, that's a good suggestion.  I guess I was thinking that it'd be easier to do 
something like


auto g = Graph!(Tuple!(double, weight), Tuple!(size_t, colour, string, 
name));


... than to force the user to define a struct up front and pass it as template 
parameter.


Re: Tuples and compile-time assigned properties

2013-09-19 Thread Artur Skawina
On 09/19/13 17:22, Joseph Rushton Wakeling wrote:
 On 19/09/13 16:55, Artur Skawina wrote:
 I'm not sure i understand your problem, but you could use structs. ie:

 struct VertexProperties {
size_t color;
string name;
 }

 You can get the field names and types at CT and work with that.
 
 Yes, that's a good suggestion.  I guess I was thinking that it'd be easier to 
 do something like
 
 auto g = Graph!(Tuple!(double, weight), Tuple!(size_t, colour, 
 string, name));
 
 ... than to force the user to define a struct up front and pass it as 
 template parameter.

Yeah, support for anonymous structs as template parms would be useful;

auto g = Graph!(struct { double weight; size_t color; string name });

But that's not currently possible.
 

You can do something like:

auto g = Graph!q{ double weight; size_t color; string name; };

then, inside the Graph template:

   // template Graph(string F, ...) {
  struct S { mixin (F); }
  // ...look at fields of 'S'...


(This will work if you only need builtin types and/or custom ones already
available in the Graph template)

artur


Re: Tuples

2013-05-27 Thread Diggory

On Monday, 27 May 2013 at 03:28:07 UTC, deadalnix wrote:

On Monday, 27 May 2013 at 02:31:50 UTC, Jonathan M Davis wrote:

On Monday, May 27, 2013 04:24:51 Diggory wrote:

It also shouldn't break any code since the only addition to
TypeTuple is a check to make sure that the undocumented 
behaviour

of using it with non-types is disallowed, and in the case that
this undocumented feature is used the code can simply switch 
to

StaticTuple and be done.


Well, changing TypeTuple to only accept types _will_ break 
code. It gets used
quite heavily with foreach to get a static foreach, and that 
can involve using
expressions instead of types. Anyone using TypeTuple heavily 
knows what it can
do and will probably have used it for expressions at some 
point. It wouldn't
surprise me in the least if it's already done in Phobos, and 
there's no way to

know how much it is or isn't done elsewhere.



Granted that nobody understand them, it is fair to say it 
should be changed.


In case people agree:
https://github.com/D-Programming-Language/phobos/pull/1309


Re: Tuples

2013-05-27 Thread deadalnix

On Monday, 27 May 2013 at 09:25:14 UTC, Diggory wrote:
Granted that nobody understand them, it is fair to say it 
should be changed.


In case people agree:
https://github.com/D-Programming-Language/phobos/pull/1309


I'm all for it. Thank you.


Re: Tuples

2013-05-26 Thread Diggory

On Sunday, 26 May 2013 at 15:48:00 UTC, Russel Winder wrote:
I wonder if people coming to D, looking for information about 
tuples,
will get confused by http://dlang.org/tuple.html which seems to 
tell

people they have to roll their own, and
http://dlang.org/phobos/std_typecons.html which tells people 
they have

been pre-rolled in the standard library?


I found this especially confusing because the built-in Tuple is 
defined differently.


The Tuple in that example is equivalent to the definition of 
TypeTuple, and yet TypeTuple is supposedly specific to types 
while that example (as so by implication TypeTuple) apparently 
works just as well with other contents.


On top of that Tuple is the one that only works with types - any 
string expressions are extracted and used as names... Surely a 
tuple which can only store types should be a TypeTyple and a 
tuple which can store anything should be a Tuple.




Re: Tuples

2013-05-26 Thread Jonathan M Davis
On Sunday, May 26, 2013 22:38:24 Diggory wrote:
 On Sunday, 26 May 2013 at 15:48:00 UTC, Russel Winder wrote:
  I wonder if people coming to D, looking for information about
  tuples,
  will get confused by http://dlang.org/tuple.html which seems to
  tell
  people they have to roll their own, and
  http://dlang.org/phobos/std_typecons.html which tells people
  they have
  been pre-rolled in the standard library?
 
 I found this especially confusing because the built-in Tuple is
 defined differently.
 
 The Tuple in that example is equivalent to the definition of
 TypeTuple, and yet TypeTuple is supposedly specific to types
 while that example (as so by implication TypeTuple) apparently
 works just as well with other contents.
 
 On top of that Tuple is the one that only works with types - any
 string expressions are extracted and used as names... Surely a
 tuple which can only store types should be a TypeTyple and a
 tuple which can store anything should be a Tuple.

I really wish that the term tuple didn't get used with the built-in tuples / 
TypeTuples. They _aren't_ tuples. They're similar, but they don't nest, and 
they cause a lot of confusion with std.typecons.Tuple. And they're only 
compile-time constructs to boot.

- Jonathan M Davis


Re: Tuples

2013-05-26 Thread Manu
I have certainly been confused by the term 'tuple' used in D countless
times.
It seems to exist in a variety of different contexts, and every time I
think I understood it, I realise I'm probably wrong some time later.
There seems to be poor/no documentation comparing/distinguishing various D
tuples, also, there seems to be no real explicit syntax, which makes it
hard to recognise.
I can kinda handle a Tuple template, and then there are these type tuples,
and then expression tuples? What is the relationship between these? Are
they compatible? How do I distinguish them?

Someone that understand what they're talking about should take some time to
write a comprehensive article on the matter :)
Some of the things I have read seem to presume that I already know what
it's talking about, and as a result, lead to dismissing or misunderstanding
the article.

I think the practical take-away from my experience is that it ends up as
one of those 'too hard' concepts, that I develop a tendency to actively
avoid dealing with because it's confused me a number of times.
I typically just start typing stuff and hope it works. And if it doesn't I
fiddle with it until it eventually does (or I give up), and I never
*really* understand why.
I'll bet I'm not the only one...


On 27 May 2013 10:25, Jonathan M Davis jmdavisp...@gmx.com wrote:

 On Sunday, May 26, 2013 22:38:24 Diggory wrote:
  On Sunday, 26 May 2013 at 15:48:00 UTC, Russel Winder wrote:
   I wonder if people coming to D, looking for information about
   tuples,
   will get confused by http://dlang.org/tuple.html which seems to
   tell
   people they have to roll their own, and
   http://dlang.org/phobos/std_typecons.html which tells people
   they have
   been pre-rolled in the standard library?
 
  I found this especially confusing because the built-in Tuple is
  defined differently.
 
  The Tuple in that example is equivalent to the definition of
  TypeTuple, and yet TypeTuple is supposedly specific to types
  while that example (as so by implication TypeTuple) apparently
  works just as well with other contents.
 
  On top of that Tuple is the one that only works with types - any
  string expressions are extracted and used as names... Surely a
  tuple which can only store types should be a TypeTyple and a
  tuple which can store anything should be a Tuple.

 I really wish that the term tuple didn't get used with the built-in tuples
 /
 TypeTuples. They _aren't_ tuples. They're similar, but they don't nest, and
 they cause a lot of confusion with std.typecons.Tuple. And they're only
 compile-time constructs to boot.

 - Jonathan M Davis



Re: Tuples

2013-05-26 Thread Jonathan M Davis
On Monday, May 27, 2013 11:21:08 Manu wrote:
 I have certainly been confused by the term 'tuple' used in D countless
 times.
 It seems to exist in a variety of different contexts, and every time I
 think I understood it, I realise I'm probably wrong some time later.
 There seems to be poor/no documentation comparing/distinguishing various D
 tuples, also, there seems to be no real explicit syntax, which makes it
 hard to recognise.
 I can kinda handle a Tuple template, and then there are these type tuples,
 and then expression tuples? What is the relationship between these? Are
 they compatible? How do I distinguish them?

You basically just have to worry about Tuple and TypeTuple. Tuple is of course 
very easy to understand. TypeTuple is then just an alias for the built-in 
tuples, which can hold basically anything. They're what template parameter 
lists, function parameter lists, template argument lists, and function 
argument lists are made of. And you can use them handily in other places (such 
as foreach) by using TypeTuple explicitly. I believe that an expression tuple 
is simply a TypeTuple which holds only expressions. In practice, I think that 
the differences are fairly simple, but they take quite a bit to wrap your head 
around - primarily due to the terminology used rather than the actual concept.

 Someone that understand what they're talking about should take some time to
 write a comprehensive article on the matter :)

I guess that I'll have to look at doing that after I finish the article that 
I'm writing on ranges (that I really need to finish...).

 Some of the things I have read seem to presume that I already know what
 it's talking about, and as a result, lead to dismissing or misunderstanding
 the article.

I generally know what's going on with D, but there were talks at dconf that 
taught be stuff about D that I'd either forgotten or never known (like some of 
what was going on with moves in Ali's talk). D is nowhere near as bad C++ with 
regards to how complicated it is, but it's still quite complicated.

 I think the practical take-away from my experience is that it ends up as
 one of those 'too hard' concepts, that I develop a tendency to actively
 avoid dealing with because it's confused me a number of times.
 I typically just start typing stuff and hope it works. And if it doesn't I
 fiddle with it until it eventually does (or I give up), and I never
 *really* understand why.
 I'll bet I'm not the only one...

It's well worth understanding TypeTuple well enough to use it with foreach, as 
it's a great way to generate unit tests, particularly when you're dealing with 
templated functions. Phobos does that quite a lot, particularly with strings. 
Take splitLines unit test for example

foreach (S; TypeTuple!(char[], wchar[], dchar[], string, wstring, 
dstring))
{
auto s = 
to!S(\rpeter\n\rpaul\r\njerry\u2028ice\u2029cream\n\nsunday\n);

auto lines = splitLines(s);
assert(lines.length == 9);
assert(lines[0] == );
assert(lines[1] == peter);
assert(lines[2] == );
assert(lines[3] == paul);
assert(lines[4] == jerry);
assert(lines[5] == ice);
assert(lines[6] == cream);
assert(lines[7] == );
assert(lines[8] == sunday);

lines = splitLines(s, KeepTerminator.yes);
assert(lines.length == 9);
assert(lines[0] == \r);
assert(lines[1] == peter\n);
assert(lines[2] == \r);
assert(lines[3] == paul\r\n);
assert(lines[4] == jerry\u2028);
assert(lines[5] == ice\u2029);
assert(lines[6] == cream\n);
assert(lines[7] == \n);
assert(lines[8] == sunday\n);

s.popBack(); // Lop-off trailing \n
lines = splitLines(s);
assert(lines.length == 9);
assert(lines[8] == sunday);

lines = splitLines(s, KeepTerminator.yes);
assert(lines.length == 9);
assert(lines[8] == sunday);
}

You get to unit test with 6 different types while only writing the code once. 
That can be _extremely_ useful.

- Jonathan M Davis


Re: Tuples

2013-05-26 Thread Diggory

On Monday, 27 May 2013 at 01:36:58 UTC, Jonathan M Davis wrote:

On Monday, May 27, 2013 11:21:08 Manu wrote:
I have certainly been confused by the term 'tuple' used in D 
countless

times.
It seems to exist in a variety of different contexts, and 
every time I
think I understood it, I realise I'm probably wrong some time 
later.
There seems to be poor/no documentation 
comparing/distinguishing various D
tuples, also, there seems to be no real explicit syntax, which 
makes it

hard to recognise.
I can kinda handle a Tuple template, and then there are these 
type tuples,
and then expression tuples? What is the relationship between 
these? Are

they compatible? How do I distinguish them?


You basically just have to worry about Tuple and TypeTuple. 
Tuple is of course
very easy to understand. TypeTuple is then just an alias for 
the built-in
tuples, which can hold basically anything. They're what 
template parameter
lists, function parameter lists, template argument lists, and 
function
argument lists are made of. And you can use them handily in 
other places (such
as foreach) by using TypeTuple explicitly. I believe that an 
expression tuple
is simply a TypeTuple which holds only expressions. In 
practice, I think that
the differences are fairly simple, but they take quite a bit to 
wrap your head
around - primarily due to the terminology used rather than the 
actual concept.


Someone that understand what they're talking about should take 
some time to

write a comprehensive article on the matter :)


I guess that I'll have to look at doing that after I finish the 
article that

I'm writing on ranges (that I really need to finish...).

Some of the things I have read seem to presume that I already 
know what
it's talking about, and as a result, lead to dismissing or 
misunderstanding

the article.


I generally know what's going on with D, but there were talks 
at dconf that
taught be stuff about D that I'd either forgotten or never 
known (like some of
what was going on with moves in Ali's talk). D is nowhere near 
as bad C++ with
regards to how complicated it is, but it's still quite 
complicated.


I think the practical take-away from my experience is that it 
ends up as
one of those 'too hard' concepts, that I develop a tendency to 
actively

avoid dealing with because it's confused me a number of times.
I typically just start typing stuff and hope it works. And if 
it doesn't I
fiddle with it until it eventually does (or I give up), and I 
never

*really* understand why.
I'll bet I'm not the only one...


It's well worth understanding TypeTuple well enough to use it 
with foreach, as
it's a great way to generate unit tests, particularly when 
you're dealing with
templated functions. Phobos does that quite a lot, particularly 
with strings.

Take splitLines unit test for example

foreach (S; TypeTuple!(char[], wchar[], dchar[], string, 
wstring,

dstring))
{
auto s =
to!S(\rpeter\n\rpaul\r\njerry\u2028ice\u2029cream\n\nsunday\n);

auto lines = splitLines(s);
assert(lines.length == 9);
assert(lines[0] == );
assert(lines[1] == peter);
assert(lines[2] == );
assert(lines[3] == paul);
assert(lines[4] == jerry);
assert(lines[5] == ice);
assert(lines[6] == cream);
assert(lines[7] == );
assert(lines[8] == sunday);

lines = splitLines(s, KeepTerminator.yes);
assert(lines.length == 9);
assert(lines[0] == \r);
assert(lines[1] == peter\n);
assert(lines[2] == \r);
assert(lines[3] == paul\r\n);
assert(lines[4] == jerry\u2028);
assert(lines[5] == ice\u2029);
assert(lines[6] == cream\n);
assert(lines[7] == \n);
assert(lines[8] == sunday\n);

s.popBack(); // Lop-off trailing \n
lines = splitLines(s);
assert(lines.length == 9);
assert(lines[8] == sunday);

lines = splitLines(s, KeepTerminator.yes);
assert(lines.length == 9);
assert(lines[8] == sunday);
}

You get to unit test with 6 different types while only writing 
the code once.

That can be _extremely_ useful.

- Jonathan M Davis


IMO we should have the following:

Tuple - Current Tuple implementation, equivalent to C++ tuple 
with the extra naming feature. Can be instantiated and passed 
around.


StaticTuple - Current TypeTuple implementation, equivalent to 
type of ... parameter in template arguments. Should not be 
instantiable.


TypeTuple - A StaticTyple where all parts have been statically 
checked to be types. It should be easy to instantiate an actual 
Tuple using a TypeTuple. Note that the template system allows 
them to be the same type, ie. a StaticTuple!(int, float) == 
TypeTuple!(int, float) while a TypeTuple!(Hello) will fail to 
compile.


ExpressionTuple - A StaticTuple where all parts have been 
statically checked to be expressions.


It would be much easier to understand and it fills a big gap in 

Re: Tuples

2013-05-26 Thread Jonathan M Davis
On Monday, May 27, 2013 04:24:51 Diggory wrote:
 It also shouldn't break any code since the only addition to
 TypeTuple is a check to make sure that the undocumented behaviour
 of using it with non-types is disallowed, and in the case that
 this undocumented feature is used the code can simply switch to
 StaticTuple and be done.

Well, changing TypeTuple to only accept types _will_ break code. It gets used 
quite heavily with foreach to get a static foreach, and that can involve using 
expressions instead of types. Anyone using TypeTuple heavily knows what it can 
do and will probably have used it for expressions at some point. It wouldn't 
surprise me in the least if it's already done in Phobos, and there's no way to 
know how much it is or isn't done elsewhere.

Because you're generally in control of the TypeTuples that you're using (you 
aren't usually getting the from APIs and the like), I really don' think that 
the fact that it can hold both types and expressions is a big deal. I expect 
that it pretty much never causes problems in actual code. It just makes it so 
that the name sucks. I don't think that we'd gain much (if anything) by 
separating out TypeTuple into three different types. Renaming it would be nice, 
but given the current push to stop making breaking changes like that, I would 
expect that at best, we'd get an alias with a better name.

- Jonathan M Davis


Re: Tuples

2013-05-26 Thread Diggory

On Monday, 27 May 2013 at 02:31:50 UTC, Jonathan M Davis wrote:

On Monday, May 27, 2013 04:24:51 Diggory wrote:

It also shouldn't break any code since the only addition to
TypeTuple is a check to make sure that the undocumented 
behaviour

of using it with non-types is disallowed, and in the case that
this undocumented feature is used the code can simply switch to
StaticTuple and be done.


Well, changing TypeTuple to only accept types _will_ break 
code. It gets used
quite heavily with foreach to get a static foreach, and that 
can involve using
expressions instead of types. Anyone using TypeTuple heavily 
knows what it can
do and will probably have used it for expressions at some 
point. It wouldn't
surprise me in the least if it's already done in Phobos, and 
there's no way to

know how much it is or isn't done elsewhere.

Because you're generally in control of the TypeTuples that 
you're using (you
aren't usually getting the from APIs and the like), I really 
don' think that
the fact that it can hold both types and expressions is a big 
deal. I expect
that it pretty much never causes problems in actual code. It 
just makes it so
that the name sucks. I don't think that we'd gain much (if 
anything) by
separating out TypeTuple into three different types. Renaming 
it would be nice,
but given the current push to stop making breaking changes like 
that, I would

expect that at best, we'd get an alias with a better name.

- Jonathan M Davis


Hmm, given that the fix can be entirely automated incredibly 
simply with find and replace it doesn't seem that bad, especially 
as the broken behaviour is undocumented. Given that the 
documentation specifically disambiguates between TypeTuples and 
ExpressionTuples I think at least emitting a warning when 
non-types are used to a TypeTuple is reasonable.


Re: Tuples

2013-05-26 Thread deadalnix

On Monday, 27 May 2013 at 02:31:50 UTC, Jonathan M Davis wrote:

On Monday, May 27, 2013 04:24:51 Diggory wrote:

It also shouldn't break any code since the only addition to
TypeTuple is a check to make sure that the undocumented 
behaviour

of using it with non-types is disallowed, and in the case that
this undocumented feature is used the code can simply switch to
StaticTuple and be done.


Well, changing TypeTuple to only accept types _will_ break 
code. It gets used
quite heavily with foreach to get a static foreach, and that 
can involve using
expressions instead of types. Anyone using TypeTuple heavily 
knows what it can
do and will probably have used it for expressions at some 
point. It wouldn't
surprise me in the least if it's already done in Phobos, and 
there's no way to

know how much it is or isn't done elsewhere.



Granted that nobody understand them, it is fair to say it should 
be changed.


Re: Tuples and variable-length template parameter lists

2012-11-06 Thread Joseph Rushton Wakeling

On 11/05/2012 06:14 PM, Simen Kjaeraas wrote:

std.typecons.Tuple does a bit of magic behind the scenes. This includes
ridding itself of non-type parameters.

Simply put, you can imagine inserting the type tuple directly into the
function definition:

 void add(ID id, size_t arg0, real arg1, value arg2);

as you probably notice, the last argument looks weird.

Now, Phobos does not currently have a staticFilter template, nor does it
have an isType template, so here are implementations of those:

add would then have this signature:

 void add(ID id, staticFilter!(isType, Properties));


Oh, very cool!  Thanks ever so much for that.  Incidentally, and I don't 
understand why, using isTypeTuple also seems to work ...


Is there a case for some patches adding those features to Phobos?



Re: Tuples and variable-length template parameter lists

2012-11-05 Thread Simen Kjaeraas

On 2012-11-05, 15:53, Joseph Rushton Wakeling wrote:


Hello all,

Suppose I want to define a tuple type which may have a variable length,  
e.g.:


template Tup(ID, Properties...)
{
static if(Properties.length == 0)
alias Tuple!(ID, id) Tup;
else
alias Tuple!(ID, id, Properties) Tup;
}

Now, it's trivial to include an arbitrary selection of named values in  
this, e.g.


auto t1 = Tup!(size_t, real, value)(3, 4.5);
writeln(t1);
writeln(t1.id,  , t1.value);

auto t2 = Tup!(size_t, real, value, bool, active)(3, 4.5, true);
writeln(t2);
writeln(t2.id,  , t2.value,  , t2.active);

However, suppose now I want to define a container struct which holds an  
array of

tuples of the specified type.  Here's what I came up with:

struct Container(ID, Properties...)
{
Tup!(ID, Properties)[] contents;

void add(ID i, Properties p)
{
static if(Properties.length == 0)
contents ~= Tup!(ID)(i);
else
contents ~= Tup!(ID, Properties)(i, p);
}
}

Now, if I make properties empty, this works just fine:

auto c1 = Container!(size_t)();
c1.add(3);
c1.add(7);
c1.add(2);
writeln(c1);
foreach(t, tup; c1.contents)
writeln([, t, ] , tup.id);
writeln();

... and likewise if I pass the container a list of value types without  
value names:


auto c2 = Container!(size_t, real, real)();
c2.add(5, 3.2, 5.6);
writeln(c2);
writeln();

... but if I try asking the container to store a tuple with _named_  
values, e.g.


auto c3 = Container!(size_t, real, value)();

then compilation fails with the following error message:


tupcontainer.d(7): Error: tuple Properties is used as a type
tupcontainer.d(12): Error: template
std.typecons.Tuple!(ulong,id,real,value).Tuple.__ctor does not match  
any

function template declaration
/usr/local/include/d2/std/typecons.d(406): Error: template
std.typecons.Tuple!(ulong,id,real,value).Tuple.__ctor cannot deduce  
template

function from argument types !()(ulong,_error_)
tupcontainer.d(51): Error: template instance
tupcontainer.Container!(ulong,real,value) error instantiating


I'm confused as to why the Container struct cannot take these template
parameters when the corresponding parameters work just fine for Tup.

Can anyone advise what the problem is and if it's possible to get the  
Container

working as envisioned?


std.typecons.Tuple does a bit of magic behind the scenes. This includes
ridding itself of non-type parameters.

Simply put, you can imagine inserting the type tuple directly into the
function definition:

void add(ID id, size_t arg0, real arg1, value arg2);

as you probably notice, the last argument looks weird.

Now, Phobos does not currently have a staticFilter template, nor does it
have an isType template, so here are implementations of those:


template staticFilter( alias pred, T... ) {
static if ( T.length == 0 ) {
alias TypeTuple!( ) staticFilter;
} else static if ( pred!( T[0] ) ) {
alias TypeTuple!( T[0], staticFilter!( pred, T[1..$] ) )  
staticFilter;

} else {
alias staticFilter!( pred, T[1..$] ) staticFilter;
}
}

unittest {
static struct S(T...){}

assert( is( S!(staticFilter!(isType, int, float)) == S!(int, float) )  
);
assert( is( S!(staticFilter!(isType, int, foo, float)) == S!(int,  
float) ) );

assert( is( S!(staticFilter!(isType, foo, bar)) == S!() ) );
}

template isType( T... ) if ( T.length == 1 ) {
enum isType = !is( typeof( T[0] ) );
}

unittest {
struct S {}
class C {}

assert( isType!int );
assert( isType!string );
assert( isType!S );
assert( isType!C );

assert( !isType!1 );
assert( !isType! );
assert( !isType!(S( )) );
}


add would then have this signature:

void add(ID id, staticFilter!(isType, Properties));

--
Simen


Re: Tuples citizenship

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 11:41:16 Dmitry Olshansky wrote:
 On 02.03.2012 6:06, bearophile wrote:
  Jonathan M Davis:
  Yes, but chaining functions is the issue. It doesn't work well with
  tuples
  unless the function you're passing the result to wants the tuple. If all
  it
  wants is one piece of the tuple, then that doesn't work well at all.
 
 just stick in .expand ?
 
 void f(int x, int y){ }
 
 void main()
 {
   Tuple!(int, int) a;
   f(a.expand);
 }

That's assuming that you're passing all of the pieces of the tuple to the 
function. Often, that's not the case at all. Take the findSplit trio, for 
instance. What are the odds that you're going to want to pass all of the 
elements in the tuples that any of the return to another function? About zero, 
I'd say. It's _much_ more likely that you're going to want to take the results 
and then pass _one_ of them to another function. So, as it stands, chaining 
with those functions just doesn't work unless you only care about one of the 
results in the tuple.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-02 Thread deadalnix

Le 02/03/2012 00:09, Jonathan M Davis a écrit :


When you're looking to mutate existing variables in the caller, using out
parameters results in cleaner code.


I'd argue that not mutating parameter result in cleaner code most of the 
time.



Tuples are inherently messier, because you
have to deal with multiple return values. They also often do poorly when you
need to use the functional programming, because often you want all of the
return values for later use but only want to pass _one_ of them to the
function that you're passing the result to.


The first time I encountered tuple was using Caml. This claim doesn't 
support my practical experience.


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis jmdavisp...@gmx.com wrote:

 That's assuming that you're passing all of the pieces of the tuple to the 
 function. Often, that's not the case at all. Take the findSplit trio, for 
 instance. What are the odds that you're going to want to pass all of the 
 elements in the tuples that any of the return to another function? About 
 zero, 
 I'd say. It's _much_ more likely that you're going to want to take the 
 results 
 and then pass _one_ of them to another function. So, as it stands, chaining 
 with those functions just doesn't work unless you only care about one of the 
 results in the tuple.
 
 - Jonathan M Davis

How does 'out' make chaining any easier? Suppose we have a `R3
findSplit2(R1, R2, out R4, out R5)`, how to chain if we want to pass the R4
to another function?

R5 ignored;
R4 theRange;
findSplit2(haystack, needle, theRange, ignored);
return doSomething(theRange);

vs

return doSomething(findSplit(haystack, needle)[1]);


Re: Tuples citizenship

2012-03-02 Thread deadalnix

Le 02/03/2012 03:06, bearophile a écrit :

Jonathan M Davis:


Yes, but chaining functions is the issue. It doesn't work well with tuples
unless the function you're passing the result to wants the tuple. If all it
wants is one piece of the tuple, then that doesn't work well at all. You're
forced to assign the tuple to something else and then call then function
rather than chain calls.


In the years I have used a mountain of tuples in Python, but I barely perceive 
that problem, so I think it's not so bad.



int exp;
auto result = frexp(value, exp);

vs

auto tup = frexp(value);
result = tup[0];
exp = tup[1];


I have assumed to use a sane tuple unpacking syntax. So the second part of your 
comparison is:

immutable (result, exp) = frexp(value);



You got it right. +1


Re: Tuples citizenship

2012-03-02 Thread deadalnix

Le 02/03/2012 02:10, Jonathan M Davis a écrit :

On Thursday, March 01, 2012 18:57:15 bearophile wrote:

Jonathan M Davis:

They also often do poorly when you
need to use the functional programming,


As you know functional languages use tuples all the time.


Yes, but chaining functions is the issue. It doesn't work well with tuples
unless the function you're passing the result to wants the tuple. If all it
wants is one piece of the tuple, then that doesn't work well at all. You're
forced to assign the tuple to something else and then call then function
rather than chain calls. That's one of the reasons that you constantly end up
using stuff like let expressions and pattern matching in functional languages.
You don't _want_ a tuple. Dealing with a tuple is annoying. It's just that
it's often the best tool that you have to pass disparate stuff around, so
that's what you use.


And if you're not looking to assign the parts of a tuple to
existing variables, then they're not quite as bad as when you are, since
you don't necessarily have to then assign the pieces to other variables.

There are parts of your post that I don't fully understand.


It is often really annoying to have to deal with tuple return values, because
you have to worry about unpacking the result. I don't want to use a tuple in
the caller. Tuples are generally for grouping unrelated data that you don't
necessarily want to keep togother (since if you did, you'd generally use a
struct). I want the result to actually be assigned to variables. That is
definitely cleaner with out than with tuples.

int exp;
auto result = frexp(value, exp);

vs

auto tup = frexp(value);
result = tup[0];
exp = tup[1];

Getting tuple return values is annoying. Yes, it can be useful, but most stuff
doesn't operate on tuples. It operates on the pieces of tuples. So, you have
to constantly break them up. So, using out results in much nicer code.

It always feels like I'm fighting the code when I have to deal with tuple
return values.

- Jonathan M Davis


Do you rally think that shorter is always better ? I don't think so. I 
think better is what the piece of code do pretty much what you expect it 
to do. And most of the time, I want to pass argument to a function not 
return value throw arguments. At the callee place, version look just 
like any other function call, but exp isn't a parameter, it is actually 
a returned value. You cannot know that reading the code, you need to 
know about frexp declaration - thus you scroll more source 
code/documentation or rely on your memory that will sometime fail. To 
emphasis that, just imagine the same scenario with a function that isn't 
from the standard lib.


This practice will confuse a newcomer that don't know the stdlib well, 
and, used in thrid party code, will confuse anyone expect the one that 
write that piece of code.


Re: Tuples citizenship

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 09:31:14 kennytm wrote:
 Jonathan M Davis jmdavisp...@gmx.com wrote:
  That's assuming that you're passing all of the pieces of the tuple to the
  function. Often, that's not the case at all. Take the findSplit trio, for
  instance. What are the odds that you're going to want to pass all of the
  elements in the tuples that any of the return to another function? About
  zero, I'd say. It's _much_ more likely that you're going to want to take
  the results and then pass _one_ of them to another function. So, as it
  stands, chaining with those functions just doesn't work unless you only
  care about one of the results in the tuple.
  
  - Jonathan M Davis
 
 How does 'out' make chaining any easier? Suppose we have a `R3
 findSplit2(R1, R2, out R4, out R5)`, how to chain if we want to pass the R4
 to another function?
 
 R5 ignored;
 R4 theRange;
 findSplit2(haystack, needle, theRange, ignored);
 return doSomething(theRange);
 
 vs
 
 return doSomething(findSplit(haystack, needle)[1]);

True, you can't chain using the out parameters, but you _can_ chain using the 
return value, whereas if you have a tuple, you can't chain _at all_ unless you 
actually need all of the returned values (either as a tuple or expanded) or if 
you only need _one_ of the returned values, in which case you can use the 
subscript operator. So, you can definitely chain better without a tuple than 
with.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 10:27:02 deadalnix wrote:
 Le 02/03/2012 00:09, Jonathan M Davis a écrit :
  When you're looking to mutate existing variables in the caller, using out
  parameters results in cleaner code.
 
 I'd argue that not mutating parameter result in cleaner code most of the
 time.
 
  Tuples are inherently messier, because you
  have to deal with multiple return values. They also often do poorly when
  you need to use the functional programming, because often you want all of
  the return values for later use but only want to pass _one_ of them to
  the function that you're passing the result to.
 
 The first time I encountered tuple was using Caml. This claim doesn't
 support my practical experience.

Yes. Functional languages use tuples. But I'm talking about chaining functions 
like you would in a functional language. But functional languages use pattern 
matching and other stuff to make it not as big a problem as it is in D, and 
often in functional languages, you _still_ have to do their equivalent of 
assigning the pieces of the tuple to variables. Tuples are a bane of function 
chaining.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis jmdavisp...@gmx.com wrote:
 On Friday, March 02, 2012 09:31:14 kennytm wrote:
 Jonathan M Davis jmdavisp...@gmx.com wrote:
 That's assuming that you're passing all of the pieces of the tuple to the
 function. Often, that's not the case at all. Take the findSplit trio, for
 instance. What are the odds that you're going to want to pass all of the
 elements in the tuples that any of the return to another function? About
 zero, I'd say. It's _much_ more likely that you're going to want to take
 the results and then pass _one_ of them to another function. So, as it
 stands, chaining with those functions just doesn't work unless you only
 care about one of the results in the tuple.
 
 - Jonathan M Davis
 
 How does 'out' make chaining any easier? Suppose we have a `R3
 findSplit2(R1, R2, out R4, out R5)`, how to chain if we want to pass the R4
 to another function?
 
 R5 ignored;
 R4 theRange;
 findSplit2(haystack, needle, theRange, ignored);
 return doSomething(theRange);
 
 vs
 
 return doSomething(findSplit(haystack, needle)[1]);
 
 True, you can't chain using the out parameters, but you _can_ chain using the 
 return value, whereas if you have a tuple, you can't chain _at all_ unless 
 you 
 actually need all of the returned values (either as a tuple or expanded) or 
 if 
 you only need _one_ of the returned values, in which case you can use the 
 subscript operator. So, you can definitely chain better without a tuple than 
 with.
 
 - Jonathan M Davis

You can just chain with

return doSomething(findSplit(haystack, needle)[0]);

if you just need the return value. Compare with 'out':

R4 ignored;
R5 ignored2;
return doSomething(findSplit(haystack, needle, ignored, ignored2));

How do you chain with _partial_ amount of return values with 'out'?


Re: Tuples citizenship

2012-03-02 Thread Don

On 01.03.2012 23:08, bearophile wrote:

I think std.typecons.Tuples merit to be a little more citizens in D and Phobos.
I think reducing the usage of out argument, and replacing them with a tuple 
result, will avoid mistakes and make the code look better. In std.math there are 
functions that maybe are better to use std.typecons.Tuple:

pure nothrow @trusted real frexp(real value, out int exp);
==
pure nothrow @trusted Tuple!(real, int) frexp(real value);


nothrow @trusted real remquo(real x, real y, out int n);
==
nothrow @trusted Tuple!(real, int) remquo(real x, real y);


They're defined that way because they come from C, and they're in IEEE754.


Re: Tuples citizenship

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 09:53:19 kennytm wrote:
 You can just chain with
 
 return doSomething(findSplit(haystack, needle)[0]);
 
 if you just need the return value. Compare with 'out':
 
 R4 ignored;
 R5 ignored2;
 return doSomething(findSplit(haystack, needle, ignored, ignored2));
 
 How do you chain with _partial_ amount of return values with 'out'?

If the function uses out, then you can chain the return value without losing 
the values which were assigned to the out arguments, but if you have a tuple, 
and you select one of the elements in the tuple to chain, you lose the others. 
The only way to get _all_ of the values in the tuple is to assign the tuple to 
a variable, in which case, you can't chain at all.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-02 Thread deadalnix

Le 02/03/2012 11:10, Jonathan M Davis a écrit :

On Friday, March 02, 2012 09:53:19 kennytm wrote:

You can just chain with

 return doSomething(findSplit(haystack, needle)[0]);

if you just need the return value. Compare with 'out':

 R4 ignored;
 R5 ignored2;
 return doSomething(findSplit(haystack, needle, ignored, ignored2));

How do you chain with _partial_ amount of return values with 'out'?


If the function uses out, then you can chain the return value without losing
the values which were assigned to the out arguments, but if you have a tuple,
and you select one of the elements in the tuple to chain, you lose the others.
The only way to get _all_ of the values in the tuple is to assign the tuple to
a variable, in which case, you can't chain at all.

- Jonathan M Davis


But you are assigning to a variable, you just declare it before. 
Additionally, you loose all possibility to use auto.


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis jmdavisp...@gmx.com wrote:
 On Friday, March 02, 2012 09:53:19 kennytm wrote:
 You can just chain with
 
 return doSomething(findSplit(haystack, needle)[0]);
 
 if you just need the return value. Compare with 'out':
 
 R4 ignored;
 R5 ignored2;
 return doSomething(findSplit(haystack, needle, ignored, ignored2));
 
 How do you chain with _partial_ amount of return values with 'out'?
 
 If the function uses out, then you can chain the return value without losing 
 the values which were assigned to the out arguments, but if you have a tuple, 
 and you select one of the elements in the tuple to chain, you lose the 
 others. 
 The only way to get _all_ of the values in the tuple is to assign the tuple 
 to 
 a variable, in which case, you can't chain at all.
 
 - Jonathan M Davis

I see what you mean. However, this is useful only when you know one of the
return value is special, and make the rest 'out' parameters, e.g.

File openFile(string fn, string mode, out ErrorCode errCode);

because the API designer know people seldom focus on the 'errCode'. But if
not all return values are considered unimportant (such as findSplit and
remquo), randomly making some of them as the 'out' parameter just make the
normal use cases more messy.

Besides, you can't use type inference with 'out' parameters. You don't
actually know the types R4 and R5 in my findSplit2 example.


Re: Tuples citizenship

2012-03-02 Thread renoX

On Friday, 2 March 2012 at 10:13:17 UTC, Jonathan M Davis wrote:
If the function uses out, then you can chain the return value 
without losing
the values which were assigned to the out arguments, but if you 
have a tuple,
and you select one of the elements in the tuple to chain, you 
lose the others.
The only way to get _all_ of the values in the tuple is to 
assign the tuple to

a variable, in which case, you can't chain at all.

- Jonathan M Davis


Sure, but due to D's syntax which doesn't distinguish in/out/ref 
params in a function call, this is quite confusing to read: when 
you read f(x,y) which is in, which is out? If D's syntax was 
f(x,@y) (@ to distinguish out or ref parameter), this would be 
easy to read, but this isn't the case.


At least with tuples you don't have this issue.

Not that I consider tuples always the good answer: for the common 
use case where you want to return an error code and a result, the 
Maybe monad is better..


BR,
renoX







Re: Tuples citizenship

2012-03-02 Thread Jonathan M Davis
On Friday, March 02, 2012 12:59:43 kennytm wrote:
 Jonathan M Davis jmdavisp...@gmx.com wrote:
  On Friday, March 02, 2012 09:53:19 kennytm wrote:
  You can just chain with
  
  return doSomething(findSplit(haystack, needle)[0]);
  
  if you just need the return value. Compare with 'out':
  R4 ignored;
  R5 ignored2;
  return doSomething(findSplit(haystack, needle, ignored, ignored2));
  
  How do you chain with _partial_ amount of return values with 'out'?
  
  If the function uses out, then you can chain the return value without
  losing the values which were assigned to the out arguments, but if you
  have a tuple, and you select one of the elements in the tuple to chain,
  you lose the others. The only way to get _all_ of the values in the tuple
  is to assign the tuple to a variable, in which case, you can't chain at
  all.
  
  - Jonathan M Davis
 
 I see what you mean. However, this is useful only when you know one of the
 return value is special, and make the rest 'out' parameters, e.g.
 
 File openFile(string fn, string mode, out ErrorCode errCode);
 
 because the API designer know people seldom focus on the 'errCode'. But if
 not all return values are considered unimportant (such as findSplit and
 remquo), randomly making some of them as the 'out' parameter just make the
 normal use cases more messy.
 
 Besides, you can't use type inference with 'out' parameters. You don't
 actually know the types R4 and R5 in my findSplit2 example.

It's not like using out is fantastic and tuple sucks. They both have pros and 
cons. My point is that it's not the case that always returning tuples is 
better, which seems to be the point that Bearophile is trying to push. There 
_are_ downsides to returning tuples. Whether a tuple or an out parameter is 
better depends on the function and the context in which it is used.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis jmdavisp...@gmx.com wrote:

 It's not like using out is fantastic and tuple sucks. They both have pros and 
 cons. My point is that it's not the case that always returning tuples is 
 better, which seems to be the point that Bearophile is trying to push. There 
 _are_ downsides to returning tuples. Whether a tuple or an out parameter is 
 better depends on the function and the context in which it is used.
 
 - Jonathan M Davis

bearophile's example (frexp, remquo) are good examples where tuple return
is better than 'out' parameters though. Another Phobos function, I think,
which should use 'out' instead of Tuples is:

-  std.file.getTimes (have the two 'out' parameters, and the function
itself returns 'void'!)

While some functions should remain using 'out':

- std.stream.InputStream.read (due to overloading)

And of course the extern(C) functions need to use 'out' instead of Tuple
return :)


Re: Tuples citizenship

2012-03-02 Thread Andrej Mitrovic
Has anyone seen my recent thread about using the if+auto feature and
opCast(bool)? It's not related to tuples but I thought it was a cool D
feature. I admit I named the thread a pretty stupid name, but it was 6
AM when I posted it :)
(http://forum.dlang.org/thread/mailman.195.1330399006.24984.digitalmar...@puremagic.com)


Re: Tuples citizenship

2012-03-01 Thread Jonathan M Davis
On Thursday, March 01, 2012 17:08:44 bearophile wrote:
 I think std.typecons.Tuples merit to be a little more citizens in D and
 Phobos. I think reducing the usage of out argument, and replacing them
 with a tuple result, will avoid mistakes and make the code look better. In
 std.math there are functions that maybe are better to use
 std.typecons.Tuple:
 
 pure nothrow @trusted real frexp(real value, out int exp);
 ==
 pure nothrow @trusted Tuple!(real, int) frexp(real value);
[snip]

Having good tuple support is great, but out parameters are great too. I'm sure 
that there are plenty of cases where using out parameters is actually far 
cleaner than using tuples, since you don't have multiple return values to deal 
with. So, better enabling tuples is great, but I don't think that we're 
necessarily moving in a good direction if we're trying to eliminate out 
parameters in favor of tuples.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-01 Thread kennytm
bearophile bearophileh...@lycos.com wrote:
(snip) 
 It's good for tuples to become more common in D code. Some time ago I
 have asked the built-in associative arrays to grow a method to iterate on
 key-value pairs, named byPair:
 http://d.puremagic.com/issues/show_bug.cgi?id=5466
 
(snip)
 Bye,
 bearophile

Associative arrays (should) have UFCS, so one could just define

@property auto byPair(AA)(AA aa) {
return zip(aa.byKey, aa.byValue);
}

in std.array. Or object.di could just define a Pair!(K,V) structure which a
Tuple!(K,V) has an opAssign defined for it.


Re: Tuples citizenship

2012-03-01 Thread deadalnix

Le 01/03/2012 23:33, Jonathan M Davis a écrit :

On Thursday, March 01, 2012 17:08:44 bearophile wrote:

I think std.typecons.Tuples merit to be a little more citizens in D and
Phobos. I think reducing the usage of out argument, and replacing them
with a tuple result, will avoid mistakes and make the code look better. In
std.math there are functions that maybe are better to use
std.typecons.Tuple:

pure nothrow @trusted real frexp(real value, out int exp);
==
pure nothrow @trusted Tuple!(real, int) frexp(real value);

[snip]

Having good tuple support is great, but out parameters are great too. I'm sure
that there are plenty of cases where using out parameters is actually far
cleaner than using tuples, since you don't have multiple return values to deal
with. So, better enabling tuples is great, but I don't think that we're
necessarily moving in a good direction if we're trying to eliminate out
parameters in favor of tuples.

- Jonathan M Davis


I don't think out parameter is a great idea. This is rather confusing.

I tend to think as function's parameter as input of the function and 
return value as an output. Books usualy agree, so I guess it is a valid 
point.


OOP give us another parameter to play with : this. It act as a state 
that can be modified. UFCS is nice to extends that outside OOP. This is 
a way better alternative than out parameter.


Tuples are nice too. Since we have auto, this isn't a big deal.

Both should be preferred to out parameters IMO, because the later cannot 
be differentiated at the calling point and force the programer to refers 
to the function declaration all the time or use its - limited and 
sometime inaccurate - memory. This is something we want to avoid.


Re: Tuples citizenship

2012-03-01 Thread Jonathan M Davis
On Friday, March 02, 2012 00:05:22 deadalnix wrote:
 Le 01/03/2012 23:33, Jonathan M Davis a écrit :
  On Thursday, March 01, 2012 17:08:44 bearophile wrote:
  I think std.typecons.Tuples merit to be a little more citizens in D and
  Phobos. I think reducing the usage of out argument, and replacing them
  with a tuple result, will avoid mistakes and make the code look better.
  In
  std.math there are functions that maybe are better to use
  std.typecons.Tuple:
  
  pure nothrow @trusted real frexp(real value, out int exp);
  ==
  pure nothrow @trusted Tuple!(real, int) frexp(real value);
  
  [snip]
  
  Having good tuple support is great, but out parameters are great too. I'm
  sure that there are plenty of cases where using out parameters is
  actually far cleaner than using tuples, since you don't have multiple
  return values to deal with. So, better enabling tuples is great, but I
  don't think that we're necessarily moving in a good direction if we're
  trying to eliminate out parameters in favor of tuples.
  
  - Jonathan M Davis
 
 I don't think out parameter is a great idea. This is rather confusing.
 
 I tend to think as function's parameter as input of the function and
 return value as an output. Books usualy agree, so I guess it is a valid
 point.
 
 OOP give us another parameter to play with : this. It act as a state
 that can be modified. UFCS is nice to extends that outside OOP. This is
 a way better alternative than out parameter.
 
 Tuples are nice too. Since we have auto, this isn't a big deal.
 
 Both should be preferred to out parameters IMO, because the later cannot
 be differentiated at the calling point and force the programer to refers
 to the function declaration all the time or use its - limited and
 sometime inaccurate - memory. This is something we want to avoid.

When you're looking to mutate existing variables in the caller, using out 
parameters results in cleaner code. Tuples are inherently messier, because you 
have to deal with multiple return values. They also often do poorly when you 
need to use the functional programming, because often you want all of the 
return values for later use but only want to pass _one_ of them to the 
function that you're passing the result to.

At other times, tuples are nicer - like when you actually _want_ the return 
value packed together (though often, if that's what you really want, a struct 
might be better). And if you're not looking to assign the parts of a tuple to 
existing variables, then they're not quite as bad as when you are, since you 
don't necessarily have to then assign the pieces to other variables.

Both have value, though if you need a lot of either, you should probably 
consider whether a struct or class would suit what you're doing better.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-01 Thread bearophile
Jonathan M Davis:

 I'm sure 
 that there are plenty of cases where using out parameters is actually far 
 cleaner than using tuples, since you don't have multiple return values to 
 deal 
 with.

Are you able to show me one or more examples where using one or more out 
arguments is in your opinion more clear (and safer!) than using a tuple with 
the proposed unpacking syntax?

With a tuple you have to deal with multiple return values, but the semantics is 
cleaner (function = resulting tuple). The number of variables doesn't change, 
because with out you need to define them any way, before the call.

If you think with tuples you lose the names of the out arguments there is a way 
to avoid this problem (but I don't know if in some situations out arguments are 
more efficient than tuples):

pure nothrow @trusted real frexp(real value, out int exp);
==
pure nothrow @trusted Tuple!(real, int,exp) frexp(real value);


Also, with a tuple result there is no risk of confusion if an argument is out 
(do you remember the discussion where people have asked a ref/out annotation at 
the calling point too, as in C#? With tuples this problem doesn't exists).

Thank you for your answer,
bye,
bearophile


Re: Tuples citizenship

2012-03-01 Thread kennytm
Jonathan M Davis jmdavisp...@gmx.com wrote:

 When you're looking to mutate existing variables in the caller, using out 
 parameters results in cleaner code. Tuples are inherently messier, because 
 you 
 have to deal with multiple return values. They also often do poorly when you 
 need to use the functional programming, because often you want all of the 
 return values for later use but only want to pass _one_ of them to the 
 function that you're passing the result to.
 

You use 'ref' to mutate existing variable, not 'out'. Multiple return value
doesn't replace the use case of ref. 

Not sure how messy it is to extract one value out of the tuple. It is much
more messier to ignore an 'out' parameter than a field in a tuple in the
call site. 

 At other times, tuples are nicer - like when you actually _want_ the return 
 value packed together (though often, if that's what you really want, a struct 
 might be better). And if you're not looking to assign the parts of a tuple to 
 existing variables, then they're not quite as bad as when you are, since you 
 don't necessarily have to then assign the pieces to other variables.
 
 Both have value, though if you need a lot of either, you should probably 
 consider whether a struct or class would suit what you're doing better.
 
 - Jonathan M Davis


Re: Tuples citizenship

2012-03-01 Thread bearophile
Jonathan M Davis:

 When you're looking to mutate existing variables in the caller, using out 
 parameters results in cleaner code. Tuples are inherently messier, because 
 you 
 have to deal with multiple return values.

out arguments have two risks:
- If you assign a value to a variable and then use it to call a function, the 
precedent value is ignored and overwritten.
- If in a function you forget to assign an out argument, the D compiler 
produces no errors.
Both source of bugs are not present with tuples.


 They also often do poorly when you 
 need to use the functional programming,

As you know functional languages use tuples all the time.


 At other times, tuples are nicer - like when you actually _want_ the return 
 value packed together (though often, if that's what you really want, a struct 
 might be better).

Defining a struct makes your code messier. D tuples support named fields too, 
so the advantage of using a struct is limited.


 And if you're not looking to assign the parts of a tuple to 
 existing variables, then they're not quite as bad as when you are, since you 
 don't necessarily have to then assign the pieces to other variables.

There are parts of your post that I don't fully understand.


 Both have value, though if you need a lot of either, you should probably 
 consider whether a struct or class would suit what you're doing better.

For most usages of a tuple a class instance means useless heap activity and 
more work for the GC.
Using a struct to return the results of a function is sometimes acceptable, but 
most times I don't use tuples for that purpose. Consider this code in my 
original post, defining two static structs doesn't do much good to such kind of 
code:

Tuple!(char,int)[] pairs2 = frequences.pairs;
schwartzSort!(c_f = tuple(-c_f[1], c_f[0]))(pairs2);
foreach (c_f; pairs2)
writeln(c_f[1],  , c_f[0]);


Tuples are often defined and used on the fly, in-place.

Bye,
bearophile


Re: Tuples citizenship

2012-03-01 Thread Jonathan M Davis
On Thursday, March 01, 2012 18:57:15 bearophile wrote:
 Jonathan M Davis:
  They also often do poorly when you
  need to use the functional programming,
 
 As you know functional languages use tuples all the time.

Yes, but chaining functions is the issue. It doesn't work well with tuples 
unless the function you're passing the result to wants the tuple. If all it 
wants is one piece of the tuple, then that doesn't work well at all. You're 
forced to assign the tuple to something else and then call then function 
rather than chain calls. That's one of the reasons that you constantly end up 
using stuff like let expressions and pattern matching in functional languages. 
You don't _want_ a tuple. Dealing with a tuple is annoying. It's just that 
it's often the best tool that you have to pass disparate stuff around, so 
that's what you use.

  And if you're not looking to assign the parts of a tuple to
  existing variables, then they're not quite as bad as when you are, since
  you don't necessarily have to then assign the pieces to other variables.
 There are parts of your post that I don't fully understand.

It is often really annoying to have to deal with tuple return values, because 
you have to worry about unpacking the result. I don't want to use a tuple in 
the caller. Tuples are generally for grouping unrelated data that you don't 
necessarily want to keep togother (since if you did, you'd generally use a 
struct). I want the result to actually be assigned to variables. That is 
definitely cleaner with out than with tuples.

int exp;
auto result = frexp(value, exp);

vs

auto tup = frexp(value);
result = tup[0];
exp = tup[1];

Getting tuple return values is annoying. Yes, it can be useful, but most stuff 
doesn't operate on tuples. It operates on the pieces of tuples. So, you have 
to constantly break them up. So, using out results in much nicer code.

It always feels like I'm fighting the code when I have to deal with tuple 
return values.

- Jonathan M Davis


Re: Tuples citizenship

2012-03-01 Thread bearophile
Jonathan M Davis:

 Yes, but chaining functions is the issue. It doesn't work well with tuples 
 unless the function you're passing the result to wants the tuple. If all it 
 wants is one piece of the tuple, then that doesn't work well at all. You're 
 forced to assign the tuple to something else and then call then function 
 rather than chain calls.

In the years I have used a mountain of tuples in Python, but I barely perceive 
that problem, so I think it's not so bad.


 int exp;
 auto result = frexp(value, exp);
 
 vs
 
 auto tup = frexp(value);
 result = tup[0];
 exp = tup[1];

I have assumed to use a sane tuple unpacking syntax. So the second part of your 
comparison is:

immutable (result, exp) = frexp(value);

That is better than your version with the out argument, safer, looks better, 
and you are even able to make both results constant.


 Getting tuple return values is annoying. Yes, it can be useful, but most 
 stuff 
 doesn't operate on tuples. It operates on the pieces of tuples. So, you have 
 to constantly break them up. So, using out results in much nicer code.

I think that the tuple unpacking syntax is able to avoid part of your problems. 
The point of my original post, that maybe was lost in the bulk of the text, was 
that an unpacking syntax sugar is very useful if you want to use tuples for 
real in D.

Bye and thank you,
bearophile


Re: Tuples citizenship

2012-03-01 Thread Dmitry Olshansky

On 02.03.2012 6:06, bearophile wrote:

Jonathan M Davis:


Yes, but chaining functions is the issue. It doesn't work well with tuples
unless the function you're passing the result to wants the tuple. If all it
wants is one piece of the tuple, then that doesn't work well at all.


just stick in .expand ?

void f(int x, int y){ }

void main()
{
Tuple!(int, int) a;
f(a.expand);
}


BTW it's nowhere to be found here
http://dlang.org/phobos/std_typecons.html


You're

forced to assign the tuple to something else and then call then function
rather than chain calls.


In the years I have used a mountain of tuples in Python, but I barely perceive 
that problem, so I think it's not so bad.



int exp;
auto result = frexp(value, exp);

vs

auto tup = frexp(value);
result = tup[0];
exp = tup[1];


I have assumed to use a sane tuple unpacking syntax. So the second part of your 
comparison is:

immutable (result, exp) = frexp(value);

That is better than your version with the out argument, safer, looks better, 
and you are even able to make both results constant.



+1




Getting tuple return values is annoying. Yes, it can be useful, but most stuff
doesn't operate on tuples. It operates on the pieces of tuples. So, you have
to constantly break them up. So, using out results in much nicer code.


I think that the tuple unpacking syntax is able to avoid part of your problems.


s/part/most
I'd say that results clearly belond to the left side of x = fun(...) 
expression, and tuples + unpack syntax are the way to make it consistent.
With all sugar going on around Tuples, e.g. .tupleof, unpacking, I can't 
help but wonder why are they not built-ins. At least they should go to 
object.d/druntime like AA do.


--
Dmitry Olshansky


Re: Tuples, C#, Java, language design

2009-12-30 Thread justme
bearophile Wrote:

 C# will probably not follow the route of stagnation of Java for some more 
 time, thanks to Mono too. I don't like that string interpolation syntax 
 because it looks unsafe, and that design of tuples can be improved, but they 
 are listening to programmes (even if they risk creating a mudball language):
 http://www.infoq.com/news/2009/12/Mono-CSharp-Ex
 
 More on those tuples:
 http://tirania.org/blog/archive/2009/Dec-23.html
 
 Eventually it will be quite useful to have some very well designed 
 multi-return support in D (like those tuples, but better).

Doesn't D2 already have tuples in Phobos. D has the comma operator which C# 
doesn't so such syntax is not possible in D, me thinks.


Re: Tuples, C#, Java, language design

2009-12-30 Thread grauzone

justme wrote:

bearophile Wrote:


C# will probably not follow the route of stagnation of Java for some more time, 
thanks to Mono too. I don't like that string interpolation syntax because it 
looks unsafe, and that design of tuples can be improved, but they are listening 
to programmes (even if they risk creating a mudball language):
http://www.infoq.com/news/2009/12/Mono-CSharp-Ex

More on those tuples:
http://tirania.org/blog/archive/2009/Dec-23.html

Eventually it will be quite useful to have some very well designed multi-return 
support in D (like those tuples, but better).


Doesn't D2 already have tuples in Phobos. D has the comma operator which C# 
doesn't so such syntax is not possible in D, me thinks.


But tuples in D really suck. Compared to other languages, D tuples feel 
inflexible, stiff, and complicated.


Re: Tuples, C#, Java, language design

2009-12-30 Thread justme
grauzone Wrote:

 justme wrote:
  bearophile Wrote:
  
  C# will probably not follow the route of stagnation of Java for some more 
  time, thanks to Mono too. I don't like that string interpolation syntax 
  because it looks unsafe, and that design of tuples can be improved, but 
  they are listening to programmes (even if they risk creating a mudball 
  language):
  http://www.infoq.com/news/2009/12/Mono-CSharp-Ex
 
  More on those tuples:
  http://tirania.org/blog/archive/2009/Dec-23.html
 
  Eventually it will be quite useful to have some very well designed 
  multi-return support in D (like those tuples, but better).
  
  Doesn't D2 already have tuples in Phobos. D has the comma operator which C# 
  doesn't so such syntax is not possible in D, me thinks.
 
 But tuples in D really suck. Compared to other languages, D tuples feel 
 inflexible, stiff, and complicated.

The burden of proving your claims is still there. Isn't D meritocracy - nobody 
listens your opinions unless you post compiler / stdlib patches. I believe the 
Phobos tuple classes are sufficient until a better system arrives in D3 or D4. 
D2 book is almost finished so you need to write your patches against D3 now.


Re: Tuples, C#, Java, language design

2009-12-30 Thread grauzone

justme wrote:

grauzone Wrote:


justme wrote:

bearophile Wrote:


C# will probably not follow the route of stagnation of Java for some more time, 
thanks to Mono too. I don't like that string interpolation syntax because it 
looks unsafe, and that design of tuples can be improved, but they are listening 
to programmes (even if they risk creating a mudball language):
http://www.infoq.com/news/2009/12/Mono-CSharp-Ex

More on those tuples:
http://tirania.org/blog/archive/2009/Dec-23.html

Eventually it will be quite useful to have some very well designed multi-return 
support in D (like those tuples, but better).

Doesn't D2 already have tuples in Phobos. D has the comma operator which C# 
doesn't so such syntax is not possible in D, me thinks.
But tuples in D really suck. Compared to other languages, D tuples feel 
inflexible, stiff, and complicated.


The burden of proving your claims is still there. Isn't D meritocracy - nobody 
listens your opinions unless you post compiler / stdlib patches. I believe the 
Phobos tuple classes are sufficient until a better system arrives in D3 or D4. 
D2 book is almost finished so you need to write your patches against D3 now.


My experience with patches is, that they're mostly either ignored or 
rejected. I guess the chance of an unrequested patch changing a core 
language feature in crucial ways is 200%. Walter doesn't listen to 
anyone anyway *g*.


The downsides of D tuples has been often mentioned, e.g. here: 
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=98953
(Sorry, I'm not as eloquent as language_fan to write it up myself, plus 
nobody would read it.)


Re: tuples

2009-11-02 Thread zkp0s
Ellery Newcomer Wrote:

 Is there currently any way to get something like
 
 Tuple!(int,i) t = tuple(5);
 
 to work?

Tuples are compile-time constructions. They are immutable.
And btw the types do not coincide 


Re: tuples

2009-11-02 Thread Ellery Newcomer
Ellery Newcomer wrote:
 Is there currently any way to get something like
 
 Tuple!(int,i) t = tuple(5);
 
 to work?

Doh. It looks like

Tuple!(int,i) t = tuple!(int,i)(5);

should work, but I'm getting the following error

/home/ellery/download/dmd2035/dmd2/linux/bin/../../src/phobos/std/typecons.d(514):
Error: template std.typecons.tuple(T...) declaration T is already defined

any ideas?


Re: tuples

2009-11-02 Thread zkp0s
Ellery Newcomer Wrote:

 Ellery Newcomer wrote:
  Is there currently any way to get something like
  
  Tuple!(int,i) t = tuple(5);
  
  to work?
 
 Doh. It looks like
 
 Tuple!(int,i) t = tuple!(int,i)(5);
 
 should work, but I'm getting the following error
 
 /home/ellery/download/dmd2035/dmd2/linux/bin/../../src/phobos/std/typecons.d(514):
 Error: template std.typecons.tuple(T...) declaration T is already defined
 
 any ideas?

Ah that std.typecons tuple, not the variadic template tuple;
I assume you are trying to initialize the tuple like
 Tuple!(int,i) t = tuple!(5);
if it is not, what are you trying to do?


Re: tuples

2009-06-12 Thread Jarrett Billingsley
On Fri, Jun 12, 2009 at 12:10 AM, Ellery
Newcomerellery-newco...@utulsa.edu wrote:
 what is up with this code?

 auto t = tuple(1,'a',3.333,false);
 pragma(msg,typeof(t.tupleof[2 .. $]).stringof);

 spits out

 (double, bool, int, char, double, bool)


It has to do with the way Tuple is implemented in std.typecons:

union
{
Types field;
mixin(tupleFields!(0, T));
}

field is of type (double, bool, int, char), and the mixin defines
something like struct { double _0; bool _1; int _2; char _3; }.
Since it's a union, the field member overlaps with the anonymous
struct, just giving you two different ways of accessing the same
member: t.field[0] or t._0.

When DMD does the tupleof, it puts all the union members in the tuple,
giving you what looks like a duplicated type list.

You can instead use:

pragma(msg,typeof(t.field[$ - 2 .. $]).stringof);


Re: tuples

2009-06-12 Thread Jarrett Billingsley
On Fri, Jun 12, 2009 at 11:00 AM, Jarrett
Billingsleyjarrett.billings...@gmail.com wrote:
 On Fri, Jun 12, 2009 at 12:10 AM, Ellery
 Newcomerellery-newco...@utulsa.edu wrote:
 what is up with this code?

 auto t = tuple(1,'a',3.333,false);
 pragma(msg,typeof(t.tupleof[2 .. $]).stringof);

 spits out

 (double, bool, int, char, double, bool)


 It has to do with the way Tuple is implemented in std.typecons:

    union
    {
        Types field;
        mixin(tupleFields!(0, T));
    }

 field is of type (double, bool, int, char), and the mixin defines
 something like struct { double _0; bool _1; int _2; char _3; }.
 Since it's a union, the field member overlaps with the anonymous
 struct, just giving you two different ways of accessing the same
 member: t.field[0] or t._0.

 When DMD does the tupleof, it puts all the union members in the tuple,
 giving you what looks like a duplicated type list.

 You can instead use:

        pragma(msg,typeof(t.field[$ - 2 .. $]).stringof);

Er,

pragma(msg,typeof(t.field[2 .. $]).stringof);


Re: tuples

2009-06-11 Thread Saaa

 what is up with this code?

 auto t = tuple(1,'a',3.333,false);
 pragma(msg,typeof(t.tupleof[2 .. $]).stringof);

 spits out

 (double, bool, int, char, double, bool)


template Tuple(E...)
{
alias E Tuple;
}
alias Tuple!(1,'a',3.333,false) t;
pragma(msg,typeof(t.tupleof[2 .. $]).stringof);
//Error

pragma(msg,typeof(t[2..$].stringof);
//writes (double, bool)




Re: Tuples

2009-02-06 Thread BCS

Reply to dsimcha,


I've been thinking a little about the idea of returning tuples from
functions, w.r.t. Bugzilla 2628
(http://d.puremagic.com/issues/show_bug.cgi?id=2628).   Would it be
feasible to solve this by making struct[index] for any struct w/o an
opIndex overload equivalent to struct.tupleof[index]?  This would be
trivial syntactic sugar, but would allow user-defined tuples in Phobos
to look like a builtin tuple, be returned from functions, etc., while
changing very little under the hood.   Furthermore, for functions that
take a tuple, we could allow structs to be implicitly cast to tuples,
e.g.:

struct Foo {
uint u;
float f;
}
void doStuff(uint myInt, float myFloat) {}

Foo foo;
doStuff(foo);  // Implicitly casts to foo.tupleof, works.


I like the first part some (but not without reservations). As for the second 
bit... I don't like it. It would make overload resolution to tricky, if not 
at the compiler level than at the eyeball level.





Re: Tuples

2009-02-06 Thread dsimcha
== Quote from BCS (a...@pathlink.com)'s article
 Reply to dsimcha,
  I've been thinking a little about the idea of returning tuples from
  functions, w.r.t. Bugzilla 2628
  (http://d.puremagic.com/issues/show_bug.cgi?id=2628).   Would it be
  feasible to solve this by making struct[index] for any struct w/o an
  opIndex overload equivalent to struct.tupleof[index]?  This would be
  trivial syntactic sugar, but would allow user-defined tuples in Phobos
  to look like a builtin tuple, be returned from functions, etc., while
  changing very little under the hood.   Furthermore, for functions that
  take a tuple, we could allow structs to be implicitly cast to tuples,
  e.g.:
 
  struct Foo {
  uint u;
  float f;
  }
  void doStuff(uint myInt, float myFloat) {}
 
  Foo foo;
  doStuff(foo);  // Implicitly casts to foo.tupleof, works.
 I like the first part some (but not without reservations). As for the second
 bit... I don't like it. It would make overload resolution to tricky, if not
 at the compiler level than at the eyeball level.

Yeah, scratch the second part.  In addition, I thought of this problem after I 
posted:

struct Foo {
uint u;
float f;
}

void doStuff(T...)(T args) {}
Foo foo;
doStuff(foo);  // Ambiguous.  Does the struct get passed, or is it //unpacked 
to a
tuple?


Re: Tuples

2009-02-06 Thread Daniel Keep


BCS wrote:
 Reply to dsimcha,
 
 I've been thinking a little about the idea of returning tuples from
 functions, w.r.t. Bugzilla 2628
 (http://d.puremagic.com/issues/show_bug.cgi?id=2628).   Would it be
 feasible to solve this by making struct[index] for any struct w/o an
 opIndex overload equivalent to struct.tupleof[index]?  This would be
 trivial syntactic sugar, but would allow user-defined tuples in Phobos
 to look like a builtin tuple, be returned from functions, etc., while
 changing very little under the hood.   Furthermore, for functions that
 take a tuple, we could allow structs to be implicitly cast to tuples,
 e.g.:

 struct Foo {
 uint u;
 float f;
 }
 void doStuff(uint myInt, float myFloat) {}

 Foo foo;
 doStuff(foo);  // Implicitly casts to foo.tupleof, works.
 
 I like the first part some (but not without reservations). As for the
 second bit... I don't like it. It would make overload resolution to
 tricky, if not at the compiler level than at the eyeball level.

I personally believe this is all getting a bit too silly; it's all this
work to get around that you can't return tuples from a function.  I
think it'd be a better idea to just make it so we can return value
tuples from functions, period.

Of course, I also want automatic unpacking and to re-purpose that silly
comma operator, but that can wait.  :)

As for the second, I just use this:

Foo foo;
doStuff(foo.tupleof);

Note: it's been a while, and I might have used a special .tuple member;
can't remember.

  -- Daniel