Re: alias c=mixin(expr); disallowed, why?

2013-06-23 Thread Jacob Carlborg

On 2013-06-22 23:47, Timon Gehr wrote:


No, it is arbitrary.


I think the spec says you can only mixin whole expression. But for some 
reason you can use a mixin in a __traits expression without having the 
whole expression in a mixin.


--
/Jacob Carlborg


Re: Can call static method with null reference

2013-06-23 Thread Jacob Carlborg

On 2013-06-22 23:51, Timon Gehr wrote:


If that is the only problem then the solution is to allow overloading on
static, which is easy to do.


You still need to call the static method on the class/struct if there's 
an ambiguity.


--
/Jacob Carlborg


Good Candy Doc Forks?

2013-06-23 Thread Michal Minich

Does anybody know some good looking or with good features?

btw, I'm wondering why is some basic version of Candy Doc bundled 
with DMD.


Thanks.


Re: Can call static method with null reference

2013-06-23 Thread Jonathan M Davis
On Sunday, June 23, 2013 11:30:11 Jacob Carlborg wrote:
> On 2013-06-22 23:51, Timon Gehr wrote:
> > If that is the only problem then the solution is to allow overloading on
> > static, which is easy to do.
> 
> You still need to call the static method on the class/struct if there's
> an ambiguity.

I would have thought that that was obvious, and I fail to see why that would 
be a problem. The only risk I see in allowing static and non-static functions 
to be overloaded, is that if you have static function being called with an 
instance, and you add a non-static overload, then the code would silently 
change to call the non-static function. But we have that exact same problem 
with UFCS and member functions as it is, and that wouldn't break any existing 
code (since you can't overload on static right now). It would just be a future 
risk of breaking code.

- Jonathan M Davis


Re: Can call static method with null reference

2013-06-23 Thread Namespace

I don't see what's so terrible about it


It's bug prone.

class Foo {
public:
static void test1() { }
void test2() { }
}

Foo f;
f.test1(); /// Oh nice, that works, f is not null.
f.test2(); /// WTF? f is null?

Also I don't know why I should call static methods from an 
instance. What's the purpose?


Re: Can call static method with null reference

2013-06-23 Thread Jonathan M Davis
On Sunday, June 23, 2013 12:02:42 Namespace wrote:
> > I don't see what's so terrible about it
> 
> It's bug prone.
> 
> class Foo {
> public:
>   static void test1() { }
>   void test2() { }
> }
> 
> Foo f;
> f.test1(); /// Oh nice, that works, f is not null.
> f.test2(); /// WTF? f is null?

I fail to see what's bug-prone about that. It's confusing, but it's not 
causing any bugs.

> Also I don't know why I should call static methods from an
> instance. What's the purpose?

It's stupid and pointless as far as I can tell, but I believe that C++, Java, 
C#, and D all do it, so as stupid as it is, it's a common stupidity. I 
certainly wish that we could change it, but I wouldn't expect Walter to agree 
to the change, since it would break at least some existing code, and I suspect 
that he doesn't consider the fact that you can call static functions on 
instances to be a problem. That's not the sort of thing that he generally 
seems to think is an issue. It's almost always stuff that causes actual bugs 
that he agrees to change and not things that are aesthetically displeasing or 
which could theoretically cause bugs.

- Jonathan M Davis


Re: alias c=mixin(expr); disallowed, why?

2013-06-23 Thread Artur Skawina
On 06/22/13 21:52, Timothee Cour wrote:
> Is there a reason the language spec disallows this?
> 
> 
> void main(){
> auto a=mixin("1");//OK
> alias b=a;//OK
> mixin("alias c=a;");//OK
> // alias c=mixin("a");//NG : Error: basic type expected, not mixin
> }

How would that be different from "auto c=mixin("a");"?

It's probably clear, but that error message is misleading, so i'll say
it anyway - the reason why your 'alias' line does not work is because
alias requires a symbol, but 'mixin()' is an expression.
Special-casing mixin-expressions (so that they propagate the symbol when
that is possible would be a bad idea); the other possibility is to allow
aliasing /expressions/. But that's a bad idea too, and would likely not
do what you expect it to do. A mixin-less version could be made to work,
but there are already other ways to get the same effect.
Hence the above question.

artur


Re: Can call static method with null reference

2013-06-23 Thread monarch_dodra

On Sunday, 23 June 2013 at 10:09:39 UTC, Jonathan M Davis wrote:

On Sunday, June 23, 2013 12:02:42 Namespace wrote:

> I don't see what's so terrible about it

It's bug prone.

class Foo {
public:
static void test1() { }
void test2() { }
}

Foo f;
f.test1(); /// Oh nice, that works, f is not null.
f.test2(); /// WTF? f is null?


I fail to see what's bug-prone about that. It's confusing, but 
it's not

causing any bugs.


Also I don't know why I should call static methods from an
instance. What's the purpose?


It's stupid and pointless as far as I can tell, but I believe 
that C++, Java,
C#, and D all do it, so as stupid as it is, it's a common 
stupidity. I
certainly wish that we could change it, but I wouldn't expect 
Walter to agree
to the change, since it would break at least some existing 
code, and I suspect
that he doesn't consider the fact that you can call static 
functions on
instances to be a problem. That's not the sort of thing that he 
generally
seems to think is an issue. It's almost always stuff that 
causes actual bugs
that he agrees to change and not things that are aesthetically 
displeasing or

which could theoretically cause bugs.

- Jonathan M Davis


C++ doesn't allow it. I don't know about the rest.

If anything, I find overloading static non static could make 
sense:


A.print(); //"I'm an A!"
a.print(); //"I'm an A called foo!"

With this in mind, it can mean that a struct can first define the 
static function, and in the future, add extra logic to handle 
information from a specific instance, yet without having to 
caller code.


Re: Can call static method with null reference

2013-06-23 Thread Jonathan M Davis
On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote:
> C++ doesn't allow it. I don't know about the rest.

Yes it does. I just tested it. This code compiles and runs just fine

#include 

using namespace std;

class C
{
public:
static void foo()
{
cout << "I'm static!" << endl;
}
};

int main()
{
C c;
c.foo();
return 0;
}

And just like D, C++ won't allow you to overload on static (also just tested), 
so D's behavior in this regard appears to be identical to C++.

- Jonathan M Davis


InstanceOf

2013-06-23 Thread Lemonfiend
I'm trying to create a fairly generic component system, where an 
object iterates over a bunch of other objects that all implement 
a certain interface.
And this all works fine, however, I would also like to be able to 
get objects of a specific type (a la instanceOf), and I can't 
figure out how to do it.


Could anyone help me out?

[code]
interface I
{
void update();
void write();
}

class A : I
{
int n;

void update()
{
n++;
}

void write()
{
writeln(n);
}
}

class B : I
{
int m;

void update()
{
m--;
}

void write()
{
writeln(m);
}
}

class C
{
I[] array;

void addElem(I elem)
{
array ~= elem;
}

void loop()
{
foreach(elem; array)
elem.update();
}

void writeAll()
{
foreach(elem; array)
elem.write();
}

void writeB()
{
// Only call .write on B's
// How do I get the B's from the array of I's?
}
}

void main()
{
C c = new C();

c.addElem(new A());
c.addElem(new B());

c.loop();

c.writeAll();

c.writeB(); // This is the problem
}
[/code]


Re: InstanceOf

2013-06-23 Thread Artur Skawina
On 06/23/13 13:04, Lemonfiend wrote:
> void writeAll()
> {
> foreach(elem; array)
> elem.write();
> }
> 
> void writeB()
> {
> // Only call .write on B's
> // How do I get the B's from the array of I's?
> }

void writeB()
{
foreach(elem; array)
   if (auto b = cast(B)elem)
   b.write();
}

artur


Re: InstanceOf

2013-06-23 Thread Chris Cain

On Sunday, 23 June 2013 at 11:04:59 UTC, Lemonfiend wrote:

...
void writeAll()
{
foreach(elem; array)
elem.write();
}

void writeB()
{
// Only call .write on B's
// How do I get the B's from the array of I's?
}


http://dlang.org/expression.html#CastExpression

So, this should do it:

void writeB()
{
foreach(elem; array)
if(cast(B) elem)
elem.write();
}

You can also do some things like this, if you want to use 
something specific to Bs:


if(auto b = cast(B) elem)
b.bSpecificMethod();


Re: InstanceOf

2013-06-23 Thread Namespace

On Sunday, 23 June 2013 at 11:04:59 UTC, Lemonfiend wrote:
I'm trying to create a fairly generic component system, where 
an object iterates over a bunch of other objects that all 
implement a certain interface.
And this all works fine, however, I would also like to be able 
to get objects of a specific type (a la instanceOf), and I 
can't figure out how to do it.


Could anyone help me out?

[code]
interface I
{
void update();
void write();
}

class A : I
{
int n;

void update()
{
n++;
}

void write()
{
writeln(n);
}
}

class B : I
{
int m;

void update()
{
m--;
}

void write()
{
writeln(m);
}
}

class C
{
I[] array;

void addElem(I elem)
{
array ~= elem;
}

void loop()
{
foreach(elem; array)
elem.update();
}

void writeAll()
{
foreach(elem; array)
elem.write();
}

void writeB()
{
// Only call .write on B's
// How do I get the B's from the array of I's?
}
}

void main()
{
C c = new C();

c.addElem(new A());
c.addElem(new B());

c.loop();

c.writeAll();

c.writeB(); // This is the problem
}
[/code]


foreach (I i; array) {
if (B b = cast(B) i) { ... }
}


Re: alias c=mixin(expr); disallowed, why?

2013-06-23 Thread Timon Gehr

On 06/23/2013 12:19 PM, Artur Skawina wrote:

On 06/22/13 21:52, Timothee Cour wrote:

Is there a reason the language spec disallows this?


void main(){
auto a=mixin("1");//OK
alias b=a;//OK
mixin("alias c=a;");//OK
// alias c=mixin("a");//NG : Error: basic type expected, not mixin
}


How would that be different from "auto c=mixin("a");"?

It's probably clear, but that error message is misleading, so i'll say
it anyway - the reason why your 'alias' line does not work is because
alias requires a symbol, but 'mixin()' is an expression.
Special-casing mixin-expressions (so that they propagate the symbol when
that is possible would be a bad idea); the other possibility is to allow
aliasing /expressions/. But that's a bad idea too, and would likely not
do what you expect it to do. A mixin-less version could be made to work,
but there are already other ways to get the same effect.
Hence the above question.

artur



mixin template T(alias x){ }

void foo(){ import std.stdio; writeln("foo"); }

void main(){
auto a=mixin("1");
mixin T!a; // ok
mixin T!(mixin("a")); // ok
mixin T!1; // ok (!)
mixin T!(mixin("foo")); // ok (no implicit call)
}



Re: alias c=mixin(expr); disallowed, why?

2013-06-23 Thread Timon Gehr

On 06/23/2013 11:32 AM, Jacob Carlborg wrote:

On 2013-06-22 23:47, Timon Gehr wrote:


No, it is arbitrary.


I think the spec says you can only mixin whole expression.


That only means you cannot do things like eg:

mixin("a*"); mixin("b");

but instead you need to do:

mixin("a*b");

such that the string content forms a valid expression according to the 
grammar.




But for some
reason you can use a mixin in a __traits expression without having the
whole expression in a mixin.



Example?


Re: InstanceOf

2013-06-23 Thread Lemonfiend

foreach (I i; array) {
if (B b = cast(B) i) { ... }
}


Thanks all 3 of you for the quick and identical answers. :)

It had not occurred to me to use a cast for this, but indeed the 
language ref says the same:
"In order to determine if an object o is an instance of a class B 
use a cast"


It does a bit inelegant to me.. Or are casts simply extremely 
cheap?





Re: InstanceOf

2013-06-23 Thread Timon Gehr

On 06/23/2013 01:26 PM, Lemonfiend wrote:

foreach (I i; array) {
if (B b = cast(B) i) { ... }
}


Thanks all 3 of you for the quick and identical answers. :)

It had not occurred to me to use a cast for this, but indeed the
language ref says the same:
"In order to determine if an object o is an instance of a class B use a
cast"

It does a bit inelegant to me.. Or are casts simply extremely cheap?




Casts are as cheap as testing whether an object is an instance of a 
certain class. Having the cast evaluate to a nullable reference is 
certainly more elegant than having instanceof and cast as separate 
constructs, where the cast may throw.


Re: Can call static method with null reference

2013-06-23 Thread monarch_dodra

On Sunday, 23 June 2013 at 10:59:06 UTC, Jonathan M Davis wrote:

On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote:

C++ doesn't allow it. I don't know about the rest.


Yes it does.

- Jonathan M Davis


Oh. Wow. That's news to me actually. I thought I new everything 
about C++ ^^


Re: Good Candy Doc Forks?

2013-06-23 Thread David
Am 23.06.2013 11:47, schrieb Michal Minich:
> Does anybody know some good looking or with good features?
> 
> btw, I'm wondering why is some basic version of Candy Doc bundled with DMD.
> 
> Thanks.

There is cuteDoc: https://github.com/JakobOvrum/cuteDoc - But it seems
like Robik deleted his repo...

And there is bootDoc: https://github.com/JakobOvrum/bootDoc (which
requires JS)


Re: alias c=mixin(expr); disallowed, why?

2013-06-23 Thread Artur Skawina
On 06/23/13 13:23, Timon Gehr wrote:
> On 06/23/2013 12:19 PM, Artur Skawina wrote:
>> On 06/22/13 21:52, Timothee Cour wrote:
>>> Is there a reason the language spec disallows this?
>>>
>>> 
>>> void main(){
>>> auto a=mixin("1");//OK
>>> alias b=a;//OK
>>> mixin("alias c=a;");//OK
>>> // alias c=mixin("a");//NG : Error: basic type expected, not mixin
>>> }
>>
>> How would that be different from "auto c=mixin("a");"?
>>
>> It's probably clear, but that error message is misleading, so i'll say
>> it anyway - the reason why your 'alias' line does not work is because
>> alias requires a symbol, but 'mixin()' is an expression.
>> Special-casing mixin-expressions (so that they propagate the symbol when
>> that is possible would be a bad idea); the other possibility is to allow
>> aliasing /expressions/. But that's a bad idea too, and would likely not
>> do what you expect it to do. A mixin-less version could be made to work,
>> but there are already other ways to get the same effect.
>> Hence the above question.
> 
> mixin template T(alias x){ }
> 
> void foo(){ import std.stdio; writeln("foo"); }
> 
> void main(){
> auto a=mixin("1");
> mixin T!a; // ok
> mixin T!(mixin("a")); // ok
> mixin T!1; // ok (!)
> mixin T!(mixin("foo")); // ok (no implicit call)
> }

Yes, template parms and literals are special (literals are useful as template
parms, obviously).

What would be the arguments for allowing these two:

> mixin T!(mixin("a")); // ok
> mixin T!(mixin("foo")); // ok (no implicit call)

?
I didn't realize they were currently accepted. Is this actually
documented somewhere? The fact that `mixin("foo")` and `mixin("foo+1")`
mean subtly different things when used as a template parameter is a problem.

artur


Re: Problem with object understanding and datatypes

2013-06-23 Thread Nordlöw

Is this code available in any repo/archive somewhere?

/Per


Range analysis result printing?

2013-06-23 Thread bearophile
I am thinking about opening an enhancement request, but this time 
I first prefer to ask your opinion here.


For this code:

void main() {
ubyte x;
ubyte y = x << 1;
}


The range analysis determines that it's conceivable to the result 
of that expression to not fit in y, so the D compiler 2.064alpha 
gives:



temp.d(3): Error: cannot implicitly convert expression 
(cast(int)x << 1) of type int to ubyte



To help the programmer understand faster the mistake in his/her 
code when expressions become more complex I think it's also 
useful to print the range resulting from the analysis, like:



temp.d(3): Error: cannot implicitly convert expression 
(cast(int)x << 1) in interval [0 ... 510] of type int to ubyte



It uses 3 dots because it's an interval that includes the right 
end. Otherwise if you print an interval open on the right in a 
case like this you have to print a ulong.max+1 value:



void main() {
ulong x;
int y = x;
}


Do you like?

Bye,
bearophile


Re: Can call static method with null reference

2013-06-23 Thread Jacob Carlborg

On 2013-06-23 12:04, Jonathan M Davis wrote:


I would have thought that that was obvious, and I fail to see why that would
be a problem. The only risk I see in allowing static and non-static functions
to be overloaded, is that if you have static function being called with an
instance, and you add a non-static overload, then the code would silently
change to call the non-static function. But we have that exact same problem
with UFCS and member functions as it is, and that wouldn't break any existing
code (since you can't overload on static right now). It would just be a future
risk of breaking code.


That's true, I didn't think of that.

--
/Jacob Carlborg


Re: alias c=mixin(expr); disallowed, why?

2013-06-23 Thread Jacob Carlborg

On 2013-06-23 13:27, Timon Gehr wrote:


Example?


@(3) int a;
alias Tuple!(__traits(getAttributes, mixin("a"))) attrs;

--
/Jacob Carlborg


Re: InstanceOf

2013-06-23 Thread Jacob Carlborg

On 2013-06-23 13:26, Lemonfiend wrote:

foreach (I i; array) {
if (B b = cast(B) i) { ... }
}


Thanks all 3 of you for the quick and identical answers. :)

It had not occurred to me to use a cast for this, but indeed the
language ref says the same:
"In order to determine if an object o is an instance of a class B use a
cast"

It does a bit inelegant to me.. Or are casts simply extremely cheap?


You can do something like this as well:

if (i.classinfo is B.classinfo) { }

But doing the cast is more efficient if you want to use the object of as 
the type you're checking for.


You can also hide the cast in a function if you want to be a bit more 
clear of the intent:


T instanceOf (T) (Object value)
{
return cast(T) value);
}

if (i.instanceOf!(B)) { }

--
/Jacob Carlborg


Re: InstanceOf

2013-06-23 Thread Lemonfiend

On Sunday, 23 June 2013 at 15:15:16 UTC, Jacob Carlborg wrote:

On 2013-06-23 13:26, Lemonfiend wrote:

foreach (I i; array) {
   if (B b = cast(B) i) { ... }
}


Thanks all 3 of you for the quick and identical answers. :)

It had not occurred to me to use a cast for this, but indeed 
the

language ref says the same:
"In order to determine if an object o is an instance of a 
class B use a

cast"

It does a bit inelegant to me.. Or are casts simply extremely 
cheap?


You can do something like this as well:

if (i.classinfo is B.classinfo) { }

But doing the cast is more efficient if you want to use the 
object of as the type you're checking for.


Using the .classinfo is what I looked at before asking here.
However, according to the specs:
".classinfo applied to an interface gives the information for the 
interface, not the class it might be an instance of."

So the i.classinfo and B.classinfo would be different?

You can also hide the cast in a function if you want to be a 
bit more clear of the intent:


T instanceOf (T) (Object value)
{
return cast(T) value);
}

if (i.instanceOf!(B)) { }


This is indeed what I did :)



Re: InstanceOf

2013-06-23 Thread Jacob Carlborg

On 2013-06-23 17:29, Lemonfiend wrote:


Using the .classinfo is what I looked at before asking here.
However, according to the specs:
".classinfo applied to an interface gives the information for the
interface, not the class it might be an instance of."
So the i.classinfo and B.classinfo would be different?


That might be the case, didn't think of that. In that case you need 
casts anyway.


--
/Jacob Carlborg


Re: A little of coordination for Rosettacode

2013-06-23 Thread bearophile

Adam D. Ruppe:


code:
http://arsdnet.net/dcode/rpc-example.d

library:
https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/rpc.d


It's online:
http://rosettacode.org/wiki/Distributed_programming#D

Bye,
bearophile


Re: Can call static method with null reference

2013-06-23 Thread Jonathan M Davis
On Sunday, June 23, 2013 13:35:55 monarch_dodra wrote:
> On Sunday, 23 June 2013 at 10:59:06 UTC, Jonathan M Davis wrote:
> > On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote:
> >> C++ doesn't allow it. I don't know about the rest.
> > 
> > Yes it does.
> > 
> > - Jonathan M Davis
> 
> Oh. Wow. That's news to me actually. I thought I new everything
> about C++ ^^

LOL. I know a lot about C++ and _try_ to know it all, but C++ is just way too 
complicated for that (at least for me). Even if I learn all of the stray 
esoteric stuff, I can't retain it all. There's just too much of it.

With D, I feel like I _might_ be able to do it. I definitely don't know 
everything that there is to know about D, and I don't always remember all of 
the little details that I learn (plus some of them change over time), but I do 
a much better job of remembering it. It doesn't have anywhere near as many 
dark corners to it, and so in spite of its complexity, it at least feels like 
it could all be understood and remembered by one person (unlike C++). So, 
_maybe_ someday I'll be able to claim that I know the D language through and 
through, but I'll definitely _never_ be able to claim that with C++.

- Jonathan M Davis


Re: Range analysis result printing?

2013-06-23 Thread Jonathan M Davis
On Sunday, June 23, 2013 16:20:51 bearophile wrote:
> It uses 3 dots because it's an interval that includes the right
> end.

The way that you normally indicate exclusive and inclusive intervals in math 
is ) vs ], where ) is exclusive and ] is inclusive. Some folks will understand 
that. I don't think that anyone will understand that ... says anything about 
whether the end is inclusive or exclusive - not unless that's commonly used 
somewhere else that I'm not familiar with.

- Jonathan M Davis


Re: Range analysis result printing?

2013-06-23 Thread bearophile

Jonathan M Davis:

The way that you normally indicate exclusive and inclusive 
intervals in math
is ) vs ], where ) is exclusive and ] is inclusive. Some folks 
will understand
that. I don't think that anyone will understand that ... says 
anything about
whether the end is inclusive or exclusive - not unless that's 
commonly used somewhere else that I'm not familiar with.


I agree that such mathematical syntaxes are more commonly known 
than the ... syntax that is used in Perl and I think Ruby and few 
other languages.


In other nations mathematicians use [x, y[ to represent open or 
close intervals (that syntax is used in std.random too).


So maybe instead of (in interval x ... y) it's better to use (in 
interval [x, y]) and hope people will understand this doesn't 
follow the normal D/Python usage of closed-on-the-right intervals.


I have added a note in the ER:
http://d.puremagic.com/issues/show_bug.cgi?id=10455

Bye,
bearophile


indexing a tuple containing a struct strange result

2013-06-23 Thread cal

What is going on here?

import std.stdio, std.typecons;

struct S
{
int x;
Tuple!(S) foo() { return tuple(this); }
}

void main()
{
S s;
s.x = 8;
writeln((s.foo())); //output: Tuple!(S)(S(8))
writeln((s.foo())[0]);  //output: S(0)
}


Re: indexing a tuple containing a struct strange result

2013-06-23 Thread Anthony Goins

On Monday, 24 June 2013 at 01:22:12 UTC, cal wrote:

What is going on here?

import std.stdio, std.typecons;

struct S
{
int x;
Tuple!(S) foo() { return tuple(this); }
}

void main()
{
S s;
s.x = 8;
writeln((s.foo())); //output: Tuple!(S)(S(8))
writeln((s.foo())[0]);  //output: S(0)
}


import std.stdio, std.typecons;

struct S
{
int x;
int y;
int z;

auto foo() { return tuple(this.tupleof); }
}

void main()
{
S s;
s.x = 8;
s.y = 9;
s.z = 10;
writeln((s.foo())); //output: Tuple!(int, int, int)(8, 9, 
10)


writeln(s.foo()[2]);  //output: 10
}

Is this what you expected?
I would explain what's going on but I'd be wrong.


Re: Ping qznc: Re: A little of coordination for Rosettacode

2013-06-23 Thread Brian Rogoff

On Saturday, 22 June 2013 at 21:27:01 UTC, bearophile wrote:

Ali Çehreli:

The code compiles under 32-bit (e.g. with the -m32 compiler 
switch) where size_t is an alias of uint.


Thanks, Ali! I'm always compiling on 64 bit systems; I'll add the 
32 bit switch to my diagnostic approach now.



Oh, I see. I compile most of the code on a 32 bit system.

I asked Walter to warn d programmers against such mistakes, and 
Walter closed it down. Someone else has opened the ER again...


In general, I think implicit conversions of any kind are a 
misfeature, but better error messages would be enough for me 
here. At least in Scala, you need to bring the conversion into 
scope yourself, or have it accidentally imported...


Thanks for your help.

-- Brian


Re: indexing a tuple containing a struct strange result

2013-06-23 Thread Ali Çehreli

On 06/23/2013 09:40 PM, Anthony Goins wrote:

> On Monday, 24 June 2013 at 01:22:12 UTC, cal wrote:

>> Tuple!(S) foo() { return tuple(this); }

> import std.stdio, std.typecons;
>
> struct S
> {
>  int x;
>  int y;
>  int z;
>
>  auto foo() { return tuple(this.tupleof); }
> }
>
> void main()
> {
>  S s;
>  s.x = 8;
>  s.y = 9;
>  s.z = 10;
>  writeln((s.foo())); //output: Tuple!(int, int, int)(8, 9, 10)
>
>  writeln(s.foo()[2]);  //output: 10
> }
>
> Is this what you expected?

I think the OP is asking about the difference from when foo() is a 
non-member function:


import std.stdio, std.typecons;

struct S
{
int x;
}

Tuple!(S) foo(S s)
{
return tuple(s);
}

void main()
{
S s;
s.x = 8;
writeln((s.foo())); //output: Tuple!(S)(S(8))
writeln((s.foo())[0]);  //output: S(8)
}

This time the output is S(8).

I think it is a compiler bug.

Ali



Re: indexing a tuple containing a struct strange result

2013-06-23 Thread Ali Çehreli

On 06/23/2013 10:07 PM, Ali Çehreli wrote:

> I think it is a compiler bug.

Make that a Phobos bug. :)

The following is a reduced program that exhibits the problem. The 
presence or absence of the unused member function makes a difference:


import std.typecons;

struct S
{
int x;

// Bizarre: Comment-out this function to pass the assert in main.
Tuple!(S) unused()
{
return tuple(S(7));
}
}

void main()
{
auto s = S(8);

assert(tuple(s).expand[0] == S(8));
}

Ali



Re: indexing a tuple containing a struct strange result

2013-06-23 Thread cal

On Monday, 24 June 2013 at 05:31:29 UTC, Ali Çehreli wrote:

On 06/23/2013 10:07 PM, Ali Çehreli wrote:

> I think it is a compiler bug.

Make that a Phobos bug. :)

The following is a reduced program that exhibits the problem. 
The presence or absence of the unused member function makes a 
difference:


import std.typecons;

struct S
{
int x;

// Bizarre: Comment-out this function to pass the assert in 
main.

Tuple!(S) unused()
{
return tuple(S(7));
}
}

void main()
{
auto s = S(8);

assert(tuple(s).expand[0] == S(8));
}

Ali


Actually I hadn't tried with free functions, but this test 
captures my problem. I'll file it now. Thanks!