Re: DDoc with cross-references

2012-04-01 Thread Jacob Carlborg

On 2012-04-02 07:52, Ary Manzana wrote:

On 4/2/12 12:39 PM, Jonathan M Davis wrote:

Phobos' macros are in

https://github.com/D-Programming-Language/d-programming-
language.org/blob/master/std.ddoc

As for linking macros,

LREF is used for references within a module.
XREF is used for references to std modules.
CXREF is used for references to core modules.
ECXREF is used for references to etc.c modules.


Again, the same things. D has ddoc and it tries to do everything with
ddoc. No, that's plain wrong. Links to other module members should be
done automatically. And the links should come from the compiler. The
compiler has that knowledge already, why loose it and work on a less
powerful level (ddoc)?


In general I think the compiler should automatically output 
cross-references. But there are cases when you want to manually refer to 
other parts of the documentation and in these cases you would needed 
these macros.


--
/Jacob Carlborg


Re: DDoc with cross-references

2012-04-01 Thread Jacob Carlborg

On 2012-04-02 06:20, Ary Manzana wrote:

I'm planning to add cross-references to the default ddoc output. At
least that's the simplest thing I could do right now that might improve
ddoc somehow.


That would be so nice to have.

--
/Jacob Carlborg


Re: Getting only the data members of a type

2012-04-01 Thread Jacob Carlborg

On 2012-04-02 02:43, Ary Manzana wrote:


This is what I don't like about D. It gives you a hammer and everyone
tries to solve all problems with that single hammer. Then you get
duplicated code for basic stuff, like getting the type of a field, in
many projects.

It's a waste of time for a developer to have to sit down and think how
we can cheat the compiler or make it talk to give us something it
already knows, but only having a hammer to do so.

Either put that in the language, or in the core library. But don't make
people waste time.

I'd suggest sending pull request with methods that accomplish those
annoyances.

On the other hand, take a look at the implementation of std.traits. Is
it really a win to implement functionLinkage in D? Right here:

https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L704


you are repeating the linkages with their names, when that information
is already available to the compiler. What's the point in duplicating
information? The compiler already knows it, and much better than D. It
could be implemented in a much simpler way. Is it just the pride of
saying "Look what I can do with my powerful compile time reflection
capabilities (basically stringof in that module)?"

I'm not angry, but I don't think things are taking the correct direction...


I agree.

--
/Jacob Carlborg


Re: DDoc with cross-references

2012-04-01 Thread Ary Manzana

On 4/2/12 2:16 PM, Ary Manzana wrote:

On 4/2/12 2:07 PM, Jonathan M Davis wrote:

On Monday, April 02, 2012 13:52:47 Ary Manzana wrote:

On 4/2/12 12:39 PM, Jonathan M Davis wrote:

On Monday, April 02, 2012 12:20:31 Ary Manzana wrote:

I'm planning to add cross-references to the default ddoc output. At
least that's the simplest thing I could do right now that might
improve
ddoc somehow.

I see the documentation generated for phobos, for example:

http://dlang.org/phobos/std_array.html#Appender

has anchors to the many symbols (in fact, now I notice it's flawed,
because they are not fully-qualified).

Does anyone know where can I get the macros for generating such
output?
I will need it for generating the cross-links.

But a more appropriate question is: why the default ddoc output
doesn't
generate such anchors by default? At least putting an ID to the
generated DT...


Phobos' macros are in

https://github.com/D-Programming-Language/d-programming-
language.org/blob/master/std.ddoc

As for linking macros,

LREF is used for references within a module.
XREF is used for references to std modules.
CXREF is used for references to core modules.
ECXREF is used for references to etc.c modules.


Again, the same things. D has ddoc and it tries to do everything with
ddoc. No, that's plain wrong. Links to other module members should be
done automatically. And the links should come from the compiler. The
compiler has that knowledge already, why loose it and work on a less
powerful level (ddoc)?


I'm not arguing it one way or another. I'm just pointing out how it
works now.


As for Appender, I don't see any links at all, so I don't know what
you're
talking about. The generic D macro (which just designates D code) is
used
by it in some places, and ddoc does put some stuff in italics in some
cases (e.g. the name of a function's parameter in the documentation for
that function), but there are no links in Appender's documentation.


What I meant is, every member in the module has an anchor. In the case
of Appender it looks like this in the generated HTML:



That's why I can give you this link:

http://dlang.org/phobos/std_array.html#Appender

and it scrolls down to Appender (I know you know it already, but it
seems I wasn't clear in my previous post).

Now, that is flawed because the name is not fully qualified. And there's
no macro to get a fully qualified name or link to other members modules.


The anchors have been a big problem for a long time. A prime example
of where
they're horrible is std.datetime. They maintain _no_ hierarchy
whatsoever. So,
_everything_ gets lumped together as it were a free function, and if
anything
has the same name (e.g. DateTime and SysTime both have a year
property), then
they end up with identical anchors. The result is that the links at
the top of
std.datetime are nearly useless.

It's ddoc's biggest problem IMHO.


Thanks again. This is what I want to fix.

I see this in the source code:

DDOC_DECL = $(DT $(BIG $0))\n\

So what I want to do is to change that so that it includes an anchor.
Should I change it to:

DDOC_DECL = $(DT  $(BIG $1))\n\

or something like that, and then pass two arguments?

I find it hard to change the documentation output while having to deal
with all those macros...


Nevermind, found how to do it. I hope I can make it soon, hehe... :-P


Re: "ref const" parameters in functions

2012-04-01 Thread L-MAN

On Monday, 2 April 2012 at 05:03:48 UTC, Jonathan M Davis wrote:

On Sunday, April 01, 2012 21:23:50 Jonathan M Davis wrote:

On Monday, April 02, 2012 05:46:24 L-MAN wrote:
Sure, if you have large structs, making a lot of copies of 
them can be
expensive. But to avoid that, you're going to have to avoid 
coding in a way

which creates temporaries, and expressions like

(abc1+abc2*20.0)+(abc1*abc2+abc1*20.0)

will _always_ create temporaries. The classic, arithmetic 
operators are
classic examples of functions which create temporaries (all of 
which are
rvalues). So, you can't code that way and expect to avoid 
temporaries.


I should point out that with optimizations turned on, in some 
cases the
compiler can optimize out the copying of temporaries, though 
not generally the

temporaries themselves. For instance

auto a = abc1 + abc2 * 20.0

results in a temporary for the result of * and a temporary for 
the result of
+. But the temporary for the result of + will be optimized out 
(probably even
without turning on optimizations), because you're using that 
result to
initialize a variable. And while the result of * will result in 
a temporary,
the copy that gets made when it's passed to opBinary!"+" should 
be optimized
out when compiled with optimizations turned on. So, the 
optimizer should be
able to reduce the problem a fair bit if you compile with -O. 
-inline may be
able to reduce it even further. So, with optimizations turned 
on, you may not

get anywhere near as many copies as you expected.

And using auto ref for the parameters (which is easy with the 
overloaded
arithmetic operators, since they're already templated) should 
also help reduce
the number of copies made, but it _is_ up to the compiler 
whether it makes a

copy or not with auto ref, so that depends on the compiler.

So, you should be able to reduce the number of copies simply by 
compiling with
-O and -inline, but the temporaries themselves will exist 
regardless.


- Jonathan M Davis

 Thank you)) it's very good for me))



Re: Add Element to list not Working

2012-04-01 Thread Chris Pons

Thanks. I tried doing this and the list didn't update:

void AddToList( SList!int list, int i )
{
list.insert( i );
}

SList!int intList;

AddToList( intList, 42 );

but when I switched to this, it worked:

SList!int intList;

void AddToList( int i )
{
intList.insert( i );
}

AddToList( 42 );

The first method didn't give an error it just didn't update the 
list as I thought. Any idea?


On Monday, 2 April 2012 at 06:07:40 UTC, Ali Çehreli wrote:

On 04/01/2012 10:45 PM, Chris Pons wrote:
I'm trying to add an element to a list with insert but that 
doesn't seem
to do anything at all. If I try using ~= it says that "Error: 
cannot
append type Node to type SList!(Node). I'm pretty confused 
about using
~= because it works fine for arrays but apperantly not for 
lists.


How do I add an element to a list?


import std.stdio;
import std.container;

void main()
{
auto l = SList!int();

l.insert(42);// inserts front
l.insert(43);// this too

assert(l == SList!int(43, 42));

// inserts after the specified range (l[] is the entire 
list)

l.insertAfter(l[], 44);

assert(l == SList!int(43, 42, 44));

// This doesn't work because SList.Range doesn't define 
opOpAssign!"~"

// l[] ~= 45;
}

Ali





Re: DDoc with cross-references

2012-04-01 Thread Ary Manzana

On 4/2/12 2:07 PM, Jonathan M Davis wrote:

On Monday, April 02, 2012 13:52:47 Ary Manzana wrote:

On 4/2/12 12:39 PM, Jonathan M Davis wrote:

On Monday, April 02, 2012 12:20:31 Ary Manzana wrote:

I'm planning to add cross-references to the default ddoc output. At
least that's the simplest thing I could do right now that might improve
ddoc somehow.

I see the documentation generated for phobos, for example:

http://dlang.org/phobos/std_array.html#Appender

has anchors to the many symbols (in fact, now I notice it's flawed,
because they are not fully-qualified).

Does anyone know where can I get the macros for generating such output?
I will need it for generating the cross-links.

But a more appropriate question is: why the default ddoc output doesn't
generate such anchors by default? At least putting an ID to the
generated DT...


Phobos' macros are in

https://github.com/D-Programming-Language/d-programming-
language.org/blob/master/std.ddoc

As for linking macros,

LREF is used for references within a module.
XREF is used for references to std modules.
CXREF is used for references to core modules.
ECXREF is used for references to etc.c modules.


Again, the same things. D has ddoc and it tries to do everything with
ddoc. No, that's plain wrong. Links to other module members should be
done automatically. And the links should come from the compiler. The
compiler has that knowledge already, why loose it and work on a less
powerful level (ddoc)?


I'm not arguing it one way or another. I'm just pointing out how it works now.


As for Appender, I don't see any links at all, so I don't know what you're
talking about. The generic D macro (which just designates D code) is used
by it in some places, and ddoc does put some stuff in italics in some
cases (e.g. the name of a function's parameter in the documentation for
that function), but there are no links in Appender's documentation.


What I meant is, every member in the module has an anchor. In the case
of Appender it looks like this in the generated HTML:



That's why I can give you this link:

http://dlang.org/phobos/std_array.html#Appender

and it scrolls down to Appender (I know you know it already, but it
seems I wasn't clear in my previous post).

Now, that is flawed because the name is not fully qualified. And there's
no macro to get a fully qualified name or link to other members modules.


The anchors have been a big problem for a long time. A prime example of where
they're horrible is std.datetime. They maintain _no_ hierarchy whatsoever. So,
_everything_ gets lumped together as it were a free function, and if anything
has the same name (e.g. DateTime and SysTime both have a year property), then
they end up with identical anchors. The result is that the links at the top of
std.datetime are nearly useless.

It's ddoc's biggest problem IMHO.


Thanks again. This is what I want to fix.

I see this in the source code:

DDOC_DECL  = $(DT $(BIG $0))\n\

So what I want to do is to change that so that it includes an anchor. 
Should I change it to:


DDOC_DECL  = $(DT  $(BIG $1))\n\

or something like that, and then pass two arguments?

I find it hard to change the documentation output while having to deal 
with all those macros...


Re: Add Element to list not Working

2012-04-01 Thread James Miller
On 2 April 2012 17:45, Chris Pons  wrote:
> I'm trying to add an element to a list with insert but that doesn't seem to
> do anything at all. If I try using ~= it says that "Error: cannot append
> type Node to type SList!(Node). I'm pretty confused about using ~= because
> it works fine for arrays but apperantly not for lists.
>
> How do I add an element to a list?

opAppend (or whatever it is) isn't defined for alot of types that it
probably should be. There should be an append method that you can use
though.

--
James Miller


Re: Add Element to list not Working

2012-04-01 Thread Ali Çehreli

On 04/01/2012 10:45 PM, Chris Pons wrote:

I'm trying to add an element to a list with insert but that doesn't seem
to do anything at all. If I try using ~= it says that "Error: cannot
append type Node to type SList!(Node). I'm pretty confused about using
~= because it works fine for arrays but apperantly not for lists.

How do I add an element to a list?


import std.stdio;
import std.container;

void main()
{
auto l = SList!int();

l.insert(42);// inserts front
l.insert(43);// this too

assert(l == SList!int(43, 42));

// inserts after the specified range (l[] is the entire list)
l.insertAfter(l[], 44);

assert(l == SList!int(43, 42, 44));

// This doesn't work because SList.Range doesn't define opOpAssign!"~"
// l[] ~= 45;
}

Ali


Re: DDoc with cross-references

2012-04-01 Thread Jonathan M Davis
On Monday, April 02, 2012 13:52:47 Ary Manzana wrote:
> On 4/2/12 12:39 PM, Jonathan M Davis wrote:
> > On Monday, April 02, 2012 12:20:31 Ary Manzana wrote:
> >> I'm planning to add cross-references to the default ddoc output. At
> >> least that's the simplest thing I could do right now that might improve
> >> ddoc somehow.
> >> 
> >> I see the documentation generated for phobos, for example:
> >> 
> >> http://dlang.org/phobos/std_array.html#Appender
> >> 
> >> has anchors to the many symbols (in fact, now I notice it's flawed,
> >> because they are not fully-qualified).
> >> 
> >> Does anyone know where can I get the macros for generating such output?
> >> I will need it for generating the cross-links.
> >> 
> >> But a more appropriate question is: why the default ddoc output doesn't
> >> generate such anchors by default? At least putting an ID to the
> >> generated DT...
> > 
> > Phobos' macros are in
> > 
> > https://github.com/D-Programming-Language/d-programming-
> > language.org/blob/master/std.ddoc
> > 
> > As for linking macros,
> > 
> > LREF is used for references within a module.
> > XREF is used for references to std modules.
> > CXREF is used for references to core modules.
> > ECXREF is used for references to etc.c modules.
> 
> Again, the same things. D has ddoc and it tries to do everything with
> ddoc. No, that's plain wrong. Links to other module members should be
> done automatically. And the links should come from the compiler. The
> compiler has that knowledge already, why loose it and work on a less
> powerful level (ddoc)?

I'm not arguing it one way or another. I'm just pointing out how it works now.

> > As for Appender, I don't see any links at all, so I don't know what you're
> > talking about. The generic D macro (which just designates D code) is used
> > by it in some places, and ddoc does put some stuff in italics in some
> > cases (e.g. the name of a function's parameter in the documentation for
> > that function), but there are no links in Appender's documentation.
> 
> What I meant is, every member in the module has an anchor. In the case
> of Appender it looks like this in the generated HTML:
> 
> 
> 
> That's why I can give you this link:
> 
> http://dlang.org/phobos/std_array.html#Appender
> 
> and it scrolls down to Appender (I know you know it already, but it
> seems I wasn't clear in my previous post).
> 
> Now, that is flawed because the name is not fully qualified. And there's
> no macro to get a fully qualified name or link to other members modules.

The anchors have been a big problem for a long time. A prime example of where 
they're horrible is std.datetime. They maintain _no_ hierarchy whatsoever. So, 
_everything_ gets lumped together as it were a free function, and if anything 
has the same name (e.g. DateTime and SysTime both have a year property), then 
they end up with identical anchors. The result is that the links at the top of 
std.datetime are nearly useless.

It's ddoc's biggest problem IMHO.

- Jonathan M Davis


Re: DDoc with cross-references

2012-04-01 Thread Ary Manzana

On 4/2/12 12:39 PM, Jonathan M Davis wrote:

On Monday, April 02, 2012 12:20:31 Ary Manzana wrote:

I'm planning to add cross-references to the default ddoc output. At
least that's the simplest thing I could do right now that might improve
ddoc somehow.

I see the documentation generated for phobos, for example:

http://dlang.org/phobos/std_array.html#Appender

has anchors to the many symbols (in fact, now I notice it's flawed,
because they are not fully-qualified).

Does anyone know where can I get the macros for generating such output?
I will need it for generating the cross-links.

But a more appropriate question is: why the default ddoc output doesn't
generate such anchors by default? At least putting an ID to the
generated DT...


Phobos' macros are in

https://github.com/D-Programming-Language/d-programming-
language.org/blob/master/std.ddoc

As for linking macros,

LREF is used for references within a module.
XREF is used for references to std modules.
CXREF is used for references to core modules.
ECXREF is used for references to etc.c modules.


Again, the same things. D has ddoc and it tries to do everything with 
ddoc. No, that's plain wrong. Links to other module members should be 
done automatically. And the links should come from the compiler. The 
compiler has that knowledge already, why loose it and work on a less 
powerful level (ddoc)?




As for Appender, I don't see any links at all, so I don't know what you're
talking about. The generic D macro (which just designates D code) is used by
it in some places, and ddoc does put some stuff in italics in some cases (e.g.
the name of a function's parameter in the documentation for that function),
but there are no links in Appender's documentation.


What I meant is, every member in the module has an anchor. In the case 
of Appender it looks like this in the generated HTML:




That's why I can give you this link:

http://dlang.org/phobos/std_array.html#Appender

and it scrolls down to Appender (I know you know it already, but it 
seems I wasn't clear in my previous post).


Now, that is flawed because the name is not fully qualified. And there's 
no macro to get a fully qualified name or link to other members modules.




Add Element to list not Working

2012-04-01 Thread Chris Pons
I'm trying to add an element to a list with insert but that 
doesn't seem to do anything at all. If I try using ~= it says 
that "Error: cannot append type Node to type SList!(Node). I'm 
pretty confused about using ~= because it works fine for arrays 
but apperantly not for lists.


How do I add an element to a list?


Re: std.typecons.Ref(T).opImplicitCastTo()

2012-04-01 Thread Jonathan M Davis
On Monday, April 02, 2012 07:23:23 Alex Rønne Petersen wrote:
> On 02-04-2012 06:25, Jonathan M Davis wrote:
> > alias this is not supposed to be restricted such that you can only have
> > one
> > per type. That's a temporary, implementation problem. TDPL specifically
> > talks about having multiple alias thises per type.
> > 
> > - Jonathan M Davis
> 
> What is the reason it hasn't been realized yet?

I don't know. While we're getting closer to having everything in TDPL 
implemented correctly each release, there's still plenty of stuff left to do, 
and no one has tackled the alias this issue yet. I expect that it's not an 
entirely easy thing to fix and that other stuff has been higher priority.

http://d.puremagic.com/issues/show_bug.cgi?id=6083

The major thing being tackled this release has been const-correctness, and 
it's not done yet (in spite of there now being a beta for 2.059). I believe 
that that's been one of Walter's major focuses this release cycle, and I 
wouldn't really expect him to tackle anything else major until Object's const-
correctness been sorted out. Nothing is stopping someone else from doing it, 
but no one has. Plenty of other stuff has been fixed though.

- Jonathan M Davis


Re: std.typecons.Ref(T).opImplicitCastTo()

2012-04-01 Thread Alex Rønne Petersen

On 02-04-2012 06:25, Jonathan M Davis wrote:

On Monday, April 02, 2012 05:41:00 Alex Rønne Petersen wrote:

On 30-03-2012 19:28, Jonathan M Davis wrote:

On Friday, March 30, 2012 16:27:44 simendsjo wrote:

Is opImplicitCastTo a planned feature?
It's only used in this type as I can see, and it doesn't add implicit
casting.


It's been discussed, but I don't think that it's ever been agreed upon. In
theory, alias this is meant to deal with implicit casts. I don't know whay
anything in Phobos would have such a function. And I don't know what the
point of std.typecons.Ref really is. It's undocumented (and clearly is
_intended_ to be undocumented given what the comment is started with). I
suspect that it's an old idea that just hasn't been cleaned out. If
you'll notice, it also has opDot, which is being removed from the
language.

- Jonathan M Davis


But you can only have one alias this per type. It is outright
incompatible with the idea of implicit cast operators. It's like
restricting opCast to only one overload per function - a
not-very-pragmatic decision if you ask me...


alias this is not supposed to be restricted such that you can only have one
per type. That's a temporary, implementation problem. TDPL specifically talks
about having multiple alias thises per type.

- Jonathan M Davis


What is the reason it hasn't been realized yet?

--
- Alex


Re: "ref const" parameters in functions

2012-04-01 Thread Jonathan M Davis
On Sunday, April 01, 2012 21:23:50 Jonathan M Davis wrote:
> On Monday, April 02, 2012 05:46:24 L-MAN wrote:
> Sure, if you have large structs, making a lot of copies of them can be
> expensive. But to avoid that, you're going to have to avoid coding in a way
> which creates temporaries, and expressions like
> 
> (abc1+abc2*20.0)+(abc1*abc2+abc1*20.0)
> 
> will _always_ create temporaries. The classic, arithmetic operators are
> classic examples of functions which create temporaries (all of which are
> rvalues). So, you can't code that way and expect to avoid temporaries.

I should point out that with optimizations turned on, in some cases the 
compiler can optimize out the copying of temporaries, though not generally the 
temporaries themselves. For instance

auto a = abc1 + abc2 * 20.0

results in a temporary for the result of * and a temporary for the result of 
+. But the temporary for the result of + will be optimized out (probably even 
without turning on optimizations), because you're using that result to 
initialize a variable. And while the result of * will result in a temporary, 
the copy that gets made when it's passed to opBinary!"+" should be optimized 
out when compiled with optimizations turned on. So, the optimizer should be 
able to reduce the problem a fair bit if you compile with -O. -inline may be 
able to reduce it even further. So, with optimizations turned on, you may not 
get anywhere near as many copies as you expected.

And using auto ref for the parameters (which is easy with the overloaded 
arithmetic operators, since they're already templated) should also help reduce 
the number of copies made, but it _is_ up to the compiler whether it makes a 
copy or not with auto ref, so that depends on the compiler.

So, you should be able to reduce the number of copies simply by compiling with 
-O and -inline, but the temporaries themselves will exist regardless.

- Jonathan M Davis


Re: DDoc with cross-references

2012-04-01 Thread Jonathan M Davis
On Monday, April 02, 2012 12:20:31 Ary Manzana wrote:
> I'm planning to add cross-references to the default ddoc output. At
> least that's the simplest thing I could do right now that might improve
> ddoc somehow.
> 
> I see the documentation generated for phobos, for example:
> 
> http://dlang.org/phobos/std_array.html#Appender
> 
> has anchors to the many symbols (in fact, now I notice it's flawed,
> because they are not fully-qualified).
> 
> Does anyone know where can I get the macros for generating such output?
> I will need it for generating the cross-links.
> 
> But a more appropriate question is: why the default ddoc output doesn't
> generate such anchors by default? At least putting an ID to the
> generated DT...

Phobos' macros are in

https://github.com/D-Programming-Language/d-programming-
language.org/blob/master/std.ddoc

As for linking macros,

LREF is used for references within a module.
XREF is used for references to std modules.
CXREF is used for references to core modules.
ECXREF is used for references to etc.c modules.

As for Appender, I don't see any links at all, so I don't know what you're 
talking about. The generic D macro (which just designates D code) is used by 
it in some places, and ddoc does put some stuff in italics in some cases (e.g. 
the name of a function's parameter in the documentation for that function), 
but there are no links in Appender's documentation.

- Jonathan M Davis


Re: std.typecons.Ref(T).opImplicitCastTo()

2012-04-01 Thread Jonathan M Davis
On Monday, April 02, 2012 15:36:01 James Miller wrote:
> On 31 March 2012 06:28, Jonathan M Davis  wrote:
> > it also has
> > opDot, which is being removed from the language.
> 
> Out of curiosity, what was opDot?

An overload of the dot operator. So, if you had

A a = foo();
a.func();

and A implemented opDot, instead of A's func being called, the overloaded 
opDot would be called. I don't know exactly how it was implemented. It's 
either a D1-only thing or an early D2 thing, but I've never used it, and it's 
not supposed to be in the language anymore (though like a number of other 
features that are supposed to be gone, it may not have actually have been 
deprecated yet).

It's probably similar to how -> is overloadable in C++, which can then be 
useful for stuff like smart pointer types so that they can forward function 
calls to the object pointed to by the smart pointer.

- Jonathan M Davis


Re: DDoc with cross-references

2012-04-01 Thread Ary Manzana

On 4/2/12 12:20 PM, Ary Manzana wrote:

I'm planning to add cross-references to the default ddoc output. At
least that's the simplest thing I could do right now that might improve
ddoc somehow.

I see the documentation generated for phobos, for example:

http://dlang.org/phobos/std_array.html#Appender

has anchors to the many symbols (in fact, now I notice it's flawed,
because they are not fully-qualified).

Does anyone know where can I get the macros for generating such output?
I will need it for generating the cross-links.

But a more appropriate question is: why the default ddoc output doesn't
generate such anchors by default? At least putting an ID to the
generated DT...


I also wonder why it's not implemented. I mean, it seems *so* easy to do 
it. Just add a toDdocChars() method to every Dsymbol. For basic types, 
just output their string representation (int, float, etc.). For classes, 
structs, etc, just output:


struct_name

or something like that...


Re: std.typecons.Ref(T).opImplicitCastTo()

2012-04-01 Thread Jonathan M Davis
On Monday, April 02, 2012 05:41:00 Alex Rønne Petersen wrote:
> On 30-03-2012 19:28, Jonathan M Davis wrote:
> > On Friday, March 30, 2012 16:27:44 simendsjo wrote:
> >> Is opImplicitCastTo a planned feature?
> >> It's only used in this type as I can see, and it doesn't add implicit
> >> casting.
> > 
> > It's been discussed, but I don't think that it's ever been agreed upon. In
> > theory, alias this is meant to deal with implicit casts. I don't know whay
> > anything in Phobos would have such a function. And I don't know what the
> > point of std.typecons.Ref really is. It's undocumented (and clearly is
> > _intended_ to be undocumented given what the comment is started with). I
> > suspect that it's an old idea that just hasn't been cleaned out. If
> > you'll notice, it also has opDot, which is being removed from the
> > language.
> > 
> > - Jonathan M Davis
> 
> But you can only have one alias this per type. It is outright
> incompatible with the idea of implicit cast operators. It's like
> restricting opCast to only one overload per function - a
> not-very-pragmatic decision if you ask me...

alias this is not supposed to be restricted such that you can only have one 
per type. That's a temporary, implementation problem. TDPL specifically talks 
about having multiple alias thises per type.

- Jonathan M Davis


DDoc with cross-references

2012-04-01 Thread Ary Manzana
I'm planning to add cross-references to the default ddoc output. At 
least that's the simplest thing I could do right now that might improve 
ddoc somehow.


I see the documentation generated for phobos, for example:

http://dlang.org/phobos/std_array.html#Appender

has anchors to the many symbols (in fact, now I notice it's flawed, 
because they are not fully-qualified).


Does anyone know where can I get the macros for generating such output? 
I will need it for generating the cross-links.


But a more appropriate question is: why the default ddoc output doesn't 
generate such anchors by default? At least putting an ID to the 
generated DT...


Re: "ref const" parameters in functions

2012-04-01 Thread Jonathan M Davis
On Monday, April 02, 2012 05:46:24 L-MAN wrote:
> About temporaries in operators +-/*.. you're right, it is not a
> secret.
> references in other functions (not in operators) too.
> 
> 
> I can't understand one thing:
>   ABC abc; // ABC is a struct that consists of some 4x4 matrix for
> example
>   ABC abc2 = ABC(20);
>   ABC abc3 = ABC(..);
>   .
>   abc+=abc2+abc3;
> 
>   operation "+" return the copy of it result to the internal
> temporary stack variable $temp (it creates automatically and it
> disable to use and invisible to see), but

> $temp is a variable and
> it must be an lvalue always.

No. It's not. It's a temporary, and temporaries are almost always rvalues. The 
sole (and very bizarre) exception is struct literals (e.g. ABC(20) is 
currently considered an lvalue). It results in the bizarre situation that a 
function which takes a const ref will work with ABC(20) but won't work with a 
function that returns ABC(20). It's a point of debate and may be changed, in 
which case ABC(20) would not be an lvalue anymore. But regardless, the result 
of operations such as + are _always_ rvalues.

Normally, the only items that are lvalues are variables and return values 
which are ref. The result of a function or operator such as + is most 
definitely _not_ an lvalue, since you can't return their results by ref. It's a 
classic example on an rvalue.

If you want to avoid making copies, then you're going to need to make your 
parameters auto ref (and hope that the compiler decides that making a copy is 
more expensive - I don't know how it decides that) or make them const ref and 
use lvalues - and using lvalues generally means creating explicit variables 
and _not_ using temporaries. So, your long expression with + and * would have 
to be changed to use += and *=.

> when I draw to the screen 5 graphical objects by OpenGL, it
> uses a matrices operation via D-language structures (uses all
> math operators and makes some matrices operations for every
> graphical object on the scene for each time), the unnecessary
> copyes of it(matrices) is very bad for engine performance.

Sure, if you have large structs, making a lot of copies of them can be 
expensive. But to avoid that, you're going to have to avoid coding in a way 
which creates temporaries, and expressions like

(abc1+abc2*20.0)+(abc1*abc2+abc1*20.0)

will _always_ create temporaries. The classic, arithmetic operators are 
classic examples of functions which create temporaries (all of which are 
rvalues). So, you can't code that way and expect to avoid temporaries.

- Jonathan M Davis


Re: "ref const" parameters in functions

2012-04-01 Thread L-MAN

On Sunday, 1 April 2012 at 08:22:08 UTC, Jonathan M Davis wrote:

On Sunday, April 01, 2012 09:10:58 L-MAN wrote:

On Saturday, 31 March 2012 at 21:42:05 UTC, Jonathan M Davis

wrote:
> On Saturday, March 31, 2012 23:25:51 L-MAN wrote:
>> Hello everybody!
>> 
>> I'm trying to use some function FN like this:
>> 
>> struct X

>> {
>> 
>>   protected double _x;  // double type for example

>>   public @property double X() const { return _x; }
>> 
>>   // ctor
>>   public this(double x) { _x = x; } // double type for 
>> example
>> 
>>   void FN(ref const(double) in_x) // double type for example

>>   {
>> 
>> // ... do some operations with _x
>> 
>>   }
>> 
>> }
>> 
>> main(..)

>> {
>> 
>>   

>>   X x = X(20);
>> 
>>   x.FN(30); // getting an error
>> 
>> }
>> 
>>   why x.FN(20) gets me an error?

>>   the construction "ref const(double)" or "ref
>> 
>> immutable(double)"
>> must be an rvalue by default I think, but in FN parameter 
>> the

>> compiler expects an lvalue...
>> 
>>   this strategy is the way to some unnecessary copy 
>> operations,
>> 
>> when value 20 (or some big struct instead of it) will copy 
>> to

>> the
>> stack..
>> 
>> How can I resolve this problem?
> 
> Unlike C++, const ref _must_ be an lvalue just like ref. If 
> you

> use auto ref
> instead of const ref, the compiler is supposed to choose
> between ref and non-
> ref based on which it thinks would be more efficient, but it
> currently only
> works with templated types.
> 
> You can duplicate the function and have a version whose

> parameter is const ref
> and one which is not, but be careful if you try and make the
> non-const ref
> version call the const ref version (to avoid duplicating the
> function's body)
> and make sure that you don't get infinite recursion. It 
> usually

> works, but I've
> run into cases before where I ended up with infinite 
> recursion,

> so make sure
> that you have unit tests which check.
> 
> Regardless, if you're dealing with a primitive type like

> double, don't bother
> with const ref. It's not going to be more efficient. It's 
> with

> large structs
> that you can see a difference.
> 
> - Jonathan M Davis


Thank you for reply, but how can I exclude some copy 
operations?

Look at this sample:

struct ABC // simple class
{
private double _d=0;
@property
{
double D() const { return _d; }
double D(double val) { return _d=val; }
}

this(double d)
{
_d = d;
writeln(" *** ctor ABC, d = ", _d);
}

ABC opAdd(ABC abc)
{
//ABC temp = ABC(this._d+abc._d);
//return temp;
return ABC(this._d+abc._d);
}

ABC opMul(double d)
{
//ABC temp = ABC(this._d*d);
//return temp;
return ABC(this._d*d);
}

ref ABC opAssign(ABC abc)
{
this._d = abc.D;
return this;
}

~this()
{
writeln(" *** dtor ABC, d = ", _d);
}
}


struct F {

private ABC _abc;

@property double D() const { return _abc.D; }

public this(ABC abc)
{
_abc = abc;

//abc.D=90;
//pnt.X = 30;
}
}


void main(string[] args)
{
   ABC abc1 = ABC(10);
   ABC abc2 = ABC(20);
   F f = F(abc1+abc2*20.0);
   writeln(f.D);
  ...
}

Operation abc1+abc2*20.0 consists of 2 ABC copy:
1. Copy result of abc2*20.0 temp value to opAdd function
2. Copy result of abc1+abc2*20.0 temp2 value to F() ctor
two temp variables and two copy operations.
But if I can use "ref const" rvalue operations 0 copies will be
need:
   abc2*20.0 creates temp valiable $$$temp
   opAdd(ref const ABC abc)  use a ref rvalue to $$$temp, is 
not a

copy
   opAdd return a $$$temp2 that use as ref rvalue for F() ctor
And try to imagine how many unnecessary copies of ABC will 
create

a simple operation like this:
  ((abc1+abc2*20.0)/0.25) + (abc1/abc2)*(abc2-1)
   it killing a time of application, especially if time is
critical.

The constructions "auto ref" in return functions values are not
working well, if I use it in a "auto ref opAdd(ref const ABC)"
"auto ref opMul(double d)" " F.this(ref const ABC)" to exclude
some copy operations it gives me a strange result :-((


You misunderstood what I meant by auto ref. I meant that you 
use auto ref

instead of const ref. e.g.

void func(auto ref T param) {}

At present, func would have to be templated to use auto ref

void func(T)(auto ref T param) {}

but eventually, auto ref shouldn't need the function to be 
templated.
Returning auto ref is completely different. It says that the 
return type is
inferred (just like with returning auto by itself) except that 
it's a
reference to the type which is inferred. And that requires that 
the value
being returned by an lvalue which is _not_ a local var

Re: std.typecons.Ref(T).opImplicitCastTo()

2012-04-01 Thread Alex Rønne Petersen

On 30-03-2012 19:28, Jonathan M Davis wrote:

On Friday, March 30, 2012 16:27:44 simendsjo wrote:

Is opImplicitCastTo a planned feature?
It's only used in this type as I can see, and it doesn't add implicit
casting.


It's been discussed, but I don't think that it's ever been agreed upon. In
theory, alias this is meant to deal with implicit casts. I don't know whay
anything in Phobos would have such a function. And I don't know what the point
of std.typecons.Ref really is. It's undocumented (and clearly is _intended_ to
be undocumented given what the comment is started with). I suspect that it's
an old idea that just hasn't been cleaned out. If you'll notice, it also has
opDot, which is being removed from the language.

- Jonathan M Davis


But you can only have one alias this per type. It is outright 
incompatible with the idea of implicit cast operators. It's like 
restricting opCast to only one overload per function - a 
not-very-pragmatic decision if you ask me...


--
- Alex


Re: std.typecons.Ref(T).opImplicitCastTo()

2012-04-01 Thread James Miller
On 31 March 2012 06:28, Jonathan M Davis  wrote:
> it also has
> opDot, which is being removed from the language.

Out of curiosity, what was opDot?

--
James Miller


Re: Getting only the data members of a type

2012-04-01 Thread Ary Manzana

On 4/1/12 8:09 PM, Jacob Carlborg wrote:

On 2012-04-01 08:18, Ali Çehreli wrote:

On 03/31/2012 09:09 PM, Artur Skawina wrote:



>
> enum s = cast(S*)null;
> foreach (i, m; s.tupleof) {
> enum name = S.tupleof[i].stringof[4..$];
> alias typeof(m) type;
> writef("(%s) %s\n", type.stringof, name);
> }
>
> Real Programmers don't use std.traits. ;)
>
> artur

Your method works but needing to iterate on a struct variable by
s.tupleof and having to use the struct type as S.tupleof in the loop
body is strange.


Yeah, it's a bit strange. One could think that it would be possible to
use "m.stringof" but that just returns the type. Instead of using
"s.tupleof" it's possible to use "typeof(S.tupleof)".

Have a look at:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L212


It's possible to get the type of a field as well, based on the name:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L237


This is what I don't like about D. It gives you a hammer and everyone 
tries to solve all problems with that single hammer. Then you get 
duplicated code for basic stuff, like getting the type of a field, in 
many projects.


It's a waste of time for a developer to have to sit down and think how 
we can cheat the compiler or make it talk to give us something it 
already knows, but only having a hammer to do so.


Either put that in the language, or in the core library. But don't make 
people waste time.


I'd suggest sending pull request with methods that accomplish those 
annoyances.


On the other hand, take a look at the implementation of std.traits. Is 
it really a win to implement functionLinkage in D? Right here:


https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d#L704

you are repeating the linkages with their names, when that information 
is already available to the compiler. What's the point in duplicating 
information? The compiler already knows it, and much better than D. It 
could be implemented in a much simpler way. Is it just the pride of 
saying "Look what I can do with my powerful compile time reflection 
capabilities (basically stringof in that module)?"


I'm not angry, but I don't think things are taking the correct direction...


Re: UFCS for types?

2012-04-01 Thread James Miller
On 31 March 2012 21:37, simendsjo  wrote:
> Is is possible to use UFCS for types to simulate static members?
>
> struct S {
>    static void f();
> }
>
> void ext(S)() {
>    S.f();
> }
>
> void main() {
>    ext!S(); // ok
>    S.ext(); // Error: no property 'ext' for type 'S'
> }

As far as I know UFCS just rewrites `a.f(b,c)` to `f(a,b,c)`, so
probably not, since `S.ext()` would be re-written to `ext(S)`, which
obviously makes no sense. Its pretty much just syntatic sugar with a
few disambiguation rules.

Basically you're asking for UFCS for template parameters, but that
would introduce too many ambiguities, especially considering things
like alias parameters:

ext(alias T, U)(U a);
int foo = 1;
foo.ext() //does the alias T get the value, or the U a?

If you just remember that UFCS is just for functions, not templates,
or rather its Uniform Function-Call Syntax, not Uniform
Template-Instantiation Syntax (UTIS?). Because even ext(T)(); is just
sugar for:

template ext(T) {
   void ext();
}

--
James Miller


Re: std.json dynamic initialization of JSONValue

2012-04-01 Thread Piotr Szturmaj

Nicolas Silva wrote:

On Sat, Mar 31, 2012 at 12:25 PM, Piotr Szturmaj  wrote:

I have written streaming json parser using ranges. It returns slices when
possible. Benchmarked it and it's about 2.05x the speed of std.json.

It gives possibility to "dig" into the structure and stream (using ranges)
by member fields, array elements, or characters of field names and string
values. It's possible to parse JSON without a single allocation. For
convenience, one can get objects, arrays and strings as a whole.

I plan to add a streaming json writer and release it (currently it outputs
json using toString()). I've seen questions on stackoverflow about parsing
500 MB JSON... so streaming feature makes it really universal. This approach
should be good for XML parser too.

Currently, I don't have time to improve it. But if someone is interested I
can send it as is :-)


I'm very interested in your json lib. I just started writing my own
but you have more advanced stuff already so I'd better build something
on top of your work. Is it on a repository somewhere on the web?


I just uploaded it here: 
https://github.com/pszturmaj/json-streaming-parser. Hope you like it :-)


Re: Whats the best way to get a struct/class member type?

2012-04-01 Thread Simen Kjærås

On Sat, 31 Mar 2012 15:20:42 +0200, simendsjo  wrote:


Seems __traits doesn't have a __traits(getMemberType, T, name).
Now I'm doing the following:
T t; // instance to use in getMember
alias typeof( __traits(getMember, t, name) ) MemberType;

Is this the only way to get the type of a field based on the name?


I'd think so, apart from tupleof, as Jacob's already mentioned.

It's easily factored out, though:

template getMemberType(T, string name) if (is(typeof(__traits(getMember,  
T, name {

alias typeof(__traits(getMember, T, name)) getMemberType;
}


Re: Where does "U" in Rebindable.Rebindable come from?

2012-04-01 Thread Simen Kjærås

On Fri, 30 Mar 2012 19:52:50 +0200, simendsjo  wrote:

On Fri, 30 Mar 2012 17:13:25 +0200, Simen Kjærås  
 wrote:


Indeed. The thing is - U is basically *set* by the isExpression. It says
'yes, there is such a U, so I'll add it to the local scope.'. This means
that U will be set for the entire scope within which the static if
exists.

Due to the way the criteria are phrased, U is defined when the criteria
are not met, and as such are defined in the else clause instead of the
if clause.


{ // Outer scope starts here.
   static if ( !is( const(int) t == const(U), U ) ) {
 // isExpression returned false, so U is undefined
   } else {
 // But here it is defined, because we're still in the same,
 // broader scope.
   }
}
// And here it's no longer defined.

Was that any better? I admit I didn't understand it at first either, but
then I remembered that static if does not introduce a new scope. That
helped.


I knew static if didn't create a new scope, but I still thought U would  
not be defined if it didn't match, but it seems it is defined just by  
existing in the scope.
I had a bug when I tried to reproduce the behavior: I used typeof(U),  
which is, of course, not possible as U is a type :)


Thanks for the explanation. Allowed to use D at work yet btw?


Not really. I use it a lot for scripts and fast prototyping, but it's
not the most flexible of organizations. Could use it for internal tools,
likely.


Re: Nested interface

2012-04-01 Thread Read Bixby

Thanks; entered as issue 7807.

On Sunday, 1 April 2012 at 20:17:09 UTC, Timon Gehr wrote:

On 04/01/2012 08:13 PM, Read Bixby wrote:
Hm, I guess it's much simpler than that.  I must not be 
understanding
something about covariance.  The following code produces the 
same error
message (it has nothing to do with nestedness or shared 
classes):



interface Interface
{
Interface getNext();
const(Interface) getNext() const;
}

class Implementation : Interface
{
Implementation getNext()
{
return null;
}

const(Implementation) getNext() const
{
return null;
}
}



This is a compiler bug. It works if 'Interface' is changed to 
an abstract class.


Please report this issue to the bug tracker:
http://d.puremagic.com/issues/





Re: Nested interface

2012-04-01 Thread Timon Gehr

On 04/01/2012 08:13 PM, Read Bixby wrote:

Hm, I guess it's much simpler than that.  I must not be understanding
something about covariance.  The following code produces the same error
message (it has nothing to do with nestedness or shared classes):


interface Interface
{
 Interface getNext();
 const(Interface) getNext() const;
}

class Implementation : Interface
{
 Implementation getNext()
 {
 return null;
 }

 const(Implementation) getNext() const
 {
 return null;
 }
}



This is a compiler bug. It works if 'Interface' is changed to an 
abstract class.


Please report this issue to the bug tracker:
http://d.puremagic.com/issues/



Re: Read a unicode character from the terminal

2012-04-01 Thread Jacob Carlborg

On 2012-04-01 16:02, Ali Çehreli wrote:


No difference in that example because it consumes the entire input as
dchars.

But in general, with that inefficient range, it is possible to pull just
one dchar from the input and leave the rest of the stream untouched. For
example, it would be possible to readf() an int right after that:

auto u = byUnicode();

dchar d = u.front; // <-- reads just one dchar from the range

int i;
readf("%s", &i); // <-- continues with std.stdio functions
writeln(i);

With the getline() method, the int must be looked up in the line first,
then from the input.

Ali


Ok, I see, thanks.

--
/Jacob Carlborg


Re: Nested interface

2012-04-01 Thread Read Bixby
Hm, I guess it's much simpler than that.  I must not be 
understanding something about covariance.  The following code 
produces the same error message (it has nothing to do with 
nestedness or shared classes):



interface Interface
{
Interface getNext();
const(Interface) getNext() const;
}

class Implementation : Interface
{
Implementation getNext()
{
return null;
}

const(Implementation) getNext() const
{
return null;
}
}


On Sunday, 1 April 2012 at 16:40:55 UTC, Read Bixby wrote:
I was working on a small personal project, and ran across 
something I think might (or might not) be a bug.  I'm posting 
in this particular group just in case it's a restriction 
somewhere that I just don't know about, or maybe just the way 
that covariance gets resolved.  The obvious workaround is to 
return NestedInterface from the two methods of the derived 
class rather than NestedImplementation, but I was kind of 
surprised it didn't compile (in the actual code, both the 
nested interface and the nested implementation were called 
"Node" which was stupid on my part).  I got the error message:  
"Error: class Implementation.NestedImplementation ambiguous 
virtual function getNext"


Is this something anyone is likely to care about?

shared interface Interface
{
public static shared interface NestedInterface
{
public shared(NestedInterface) getNext();
public shared(const(NestedInterface)) getNext() const;
}
}

shared class Implementation : Interface
{
	public static shared class NestedImplementation : 
Interface.NestedInterface

{
public override shared(NestedImplementation) getNext()
{
return null;
}

		public override shared(const(NestedImplementation)) getNext() 
const

{
return null;
}
}
}





Nested interface

2012-04-01 Thread Read Bixby
I was working on a small personal project, and ran across 
something I think might (or might not) be a bug.  I'm posting in 
this particular group just in case it's a restriction somewhere 
that I just don't know about, or maybe just the way that 
covariance gets resolved.  The obvious workaround is to return 
NestedInterface from the two methods of the derived class rather 
than NestedImplementation, but I was kind of surprised it didn't 
compile (in the actual code, both the nested interface and the 
nested implementation were called "Node" which was stupid on my 
part).  I got the error message:  "Error: class 
Implementation.NestedImplementation ambiguous virtual function 
getNext"


Is this something anyone is likely to care about?

shared interface Interface
{
public static shared interface NestedInterface
{
public shared(NestedInterface) getNext();
public shared(const(NestedInterface)) getNext() const;
}
}

shared class Implementation : Interface
{
	public static shared class NestedImplementation : 
Interface.NestedInterface

{
public override shared(NestedImplementation) getNext()
{
return null;
}

		public override shared(const(NestedImplementation)) getNext() 
const

{
return null;
}
}
}



Re: Simulating multiple inheritance

2012-04-01 Thread bls

On 03/31/2012 10:05 AM, Andrej Mitrovic wrote:

One issue with the new wxWidgets 2.9.x series is that there seem to be
more multiply-inherited classes than before


A bit more complete snippet.

interface Foo
{
void doFoo();
}
// Foo implementation
mixin template FooMixin()
{
alias typeof(this) thisClass;

void doFoo()
{
thisClass.init();
}
}

class Bar
{
void doFoo() {}
}

class Baz :Bar, Foo
{
alias Bar.doFoo BarFoo;

mixin FooMixin;

void init() {}

}

hth


Re: Read a unicode character from the terminal

2012-04-01 Thread Ali Çehreli

On 04/01/2012 05:00 AM, Jacob Carlborg wrote:

On 2012-04-01 01:17, Ali Çehreli wrote:

On 03/31/2012 11:53 AM, Ali Çehreli wrote:

> The solution is to use ranges when pulling Unicode characters out of
> strings. std.stdin does not provide this yet, but it will eventually
> happen (so I've heard :)).

Here is a Unicode character range, which is unfortunately pretty
inefficient because it relies on an exception that is thrown from
isValidDchar! :p


Ok, what's the differences compared to the example in your first post:

void main()
{
string line = readln();

foreach (dchar c; line) {
writeln(c);
}
}



No difference in that example because it consumes the entire input as 
dchars.


But in general, with that inefficient range, it is possible to pull just 
one dchar from the input and leave the rest of the stream untouched. For 
example, it would be possible to readf() an int right after that:


auto u = byUnicode();

dchar d = u.front;  // <-- reads just one dchar from the range

int i;
readf("%s", &i);// <-- continues with std.stdio functions
writeln(i);

With the getline() method, the int must be looked up in the line first, 
then from the input.


Ali


Re: std.json dynamic initialization of JSONValue

2012-04-01 Thread Nicolas Silva
On Sat, Mar 31, 2012 at 12:25 PM, Piotr Szturmaj  wrote:
> Andrej Mitrovic wrote:
>>
>> On 12/1/11, Kai Meyer  wrote:
>>>
>>> I'm finding std.json extremely well written, with one glaring exception.
>>
>>
>> I'm finding it to be crap. The last time I used it I just kept getting
>> access violations (or was that std.xml? They're both crap when I used
>> them.). ae.json beats its pants off for its simplicity + you get
>> toJson/jsonParse for serialization and a way to skip serializing
>> fields since a recent commit . It's easy to write your own
>> tree-walking routines as well.
>>
>> But whatever works for people. :)
>
>
> I have written streaming json parser using ranges. It returns slices when
> possible. Benchmarked it and it's about 2.05x the speed of std.json.
>
> It gives possibility to "dig" into the structure and stream (using ranges)
> by member fields, array elements, or characters of field names and string
> values. It's possible to parse JSON without a single allocation. For
> convenience, one can get objects, arrays and strings as a whole.
>
> I plan to add a streaming json writer and release it (currently it outputs
> json using toString()). I've seen questions on stackoverflow about parsing
> 500 MB JSON... so streaming feature makes it really universal. This approach
> should be good for XML parser too.
>
> Currently, I don't have time to improve it. But if someone is interested I
> can send it as is :-)

I'm very interested in your json lib. I just started writing my own
but you have more advanced stuff already so I'd better build something
on top of your work. Is it on a repository somewhere on the web?


Re: Getting only the data members of a type

2012-04-01 Thread Artur Skawina
On 04/01/12 14:10, Jacob Carlborg wrote:
> On 2012-04-01 11:27, Artur Skawina wrote:
> 
>> That's because the compiler won't accept "foreach (i, t; S.tupleof)" and
> 
> But it accepts "foreach (i, t; typeof(S.tupleof))".

It does - thank you.

This means that that ugly null-to-pointer cast from my example can go,
and all that's needed is:

   foreach (i, type; typeof(S.tupleof)) {
  enum name = S.tupleof[i].stringof[4..$];
  writef("(%s) %s\n", type.stringof, name);
   }

artur


Re: Simulating multiple inheritance

2012-04-01 Thread bls

On 03/31/2012 10:05 AM, Andrej Mitrovic wrote:

This is related to wrapping wxWidgets.

One issue with the new wxWidgets 2.9.x series is that there seem to be
more multiply-inherited classes than before


As Jacob already said mixin templates and Interfaces are the way to go.
I think you have to define the mixin template as
*mixin* template mixin_name.

interface Baz
{}

mixin template Baz()
{
// In case that you need to access the parent class
alias typeof(this) ThisClass;
}

class Bar
{}

class Foo : Bar , Baz
{
mixin Baz;
}

Good to know that you are still develop the wxWidget bindings. Keep us 
informed.


Re: Getting only the data members of a type

2012-04-01 Thread Jacob Carlborg

On 2012-04-01 11:27, Artur Skawina wrote:


That's because the compiler won't accept "foreach (i, t; S.tupleof)" and
"*.tupleof[i].stringof" is necessary to get the original name. This would
have worked too:

   enum name = *s.tupleof[i].stringof[4..$];

but obfuscates the code more and looks like dereferencing a null pointer.

artur


But it accepts "foreach (i, t; typeof(S.tupleof))".

--
/Jacob Carlborg


Re: Getting only the data members of a type

2012-04-01 Thread Jacob Carlborg

On 2012-04-01 08:18, Ali Çehreli wrote:

On 03/31/2012 09:09 PM, Artur Skawina wrote:



 >
 > enum s = cast(S*)null;
 > foreach (i, m; s.tupleof) {
 > enum name = S.tupleof[i].stringof[4..$];
 > alias typeof(m) type;
 > writef("(%s) %s\n", type.stringof, name);
 > }
 >
 > Real Programmers don't use std.traits. ;)
 >
 > artur

Your method works but needing to iterate on a struct variable by
s.tupleof and having to use the struct type as S.tupleof in the loop
body is strange.


Yeah, it's a bit strange. One could think that it would be possible to 
use "m.stringof" but that just returns the type. Instead of using 
"s.tupleof" it's possible to use "typeof(S.tupleof)".


Have a look at:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L212

It's possible to get the type of a field as well, based on the name:

https://github.com/jacob-carlborg/orange/blob/master/orange/util/Reflection.d#L237

--
/Jacob Carlborg


Re: Read a unicode character from the terminal

2012-04-01 Thread Jacob Carlborg

On 2012-04-01 00:14, Stewart Gordon wrote:

On 31/03/2012 16:56, Jacob Carlborg wrote:

How would I read a unicode character from the terminal? I've tried using
"std.cstream.din.getc" but it seems to only work for ascii characters.
If I try to read
and print something that isn't ascii, it just prints a question mark.


What OS are you using?

And what codepage is the console set to?


I'm using Mac OS X and the terminal is set to handle UTF-8.


You might want to try the console module in my utility library:

http://pr.stewartsplace.org.uk/d/sutil/

(For D1 at the moment, but a D2 version will be available any day now!)

Stewart.


I'll have a look, thanks.

--
/Jacob Carlborg


Re: Read a unicode character from the terminal

2012-04-01 Thread Jacob Carlborg

On 2012-04-01 01:17, Ali Çehreli wrote:

On 03/31/2012 11:53 AM, Ali Çehreli wrote:

 > The solution is to use ranges when pulling Unicode characters out of
 > strings. std.stdin does not provide this yet, but it will eventually
 > happen (so I've heard :)).

Here is a Unicode character range, which is unfortunately pretty
inefficient because it relies on an exception that is thrown from
isValidDchar! :p


Ok, what's the differences compared to the example in your first post:

void main()
{
string line = readln();

foreach (dchar c; line) {
writeln(c);
}
}

--
/Jacob Carlborg


Re: Read a unicode character from the terminal

2012-04-01 Thread Jacob Carlborg

On 2012-03-31 20:53, Ali Çehreli wrote:

I recommend using stdin. The destiny of std.cstream is uncertain and
stdin is sufficient. (I know that it lacks support for BOM but I don't
need them.)


I thought std.cstream was a stream wrapper around stdin.


The word 'character' used to mean characters of the Latin-based
alphabets but with Unicode support that's not the case anymore. In D,
'character' means UTF code unit, nothing else. Unfortunately, although
'Unidode character' is just the correct term to use, it conflicts with
D's characters which are not Unicode characters.

'Unicode code point' is the non-conflicting term that matches what we
mean with 'Unicode character.' Only dchar can hold code points.

That's the part about characters.


Yeah, exactly. When I think about it, I don't know why I thought "getc" 
would work since it only returns a "char" and not a "dchar".



The other side is what is being fed into the program through its
standard input. On my Linux consoles, the text comes as a stream of
chars, i.e. a UTF-8 encoded text. You must ensure that your terminal is
capable of supporting Unicode through its settings. On Windows
terminals, one must enter 'chcp 65001' to set the terminal to UTF-8.


I'm on Mac OS X, the terminal is capable of handling Unicode.


Then, it is the program that must know what the data represents. If you
are expecting a Unicode code point, then you may think that is should be
as simple as reading into a dchar:

import std.stdio;

void main()
{
dchar letter;
readf("%s", &letter); // <-- does not work!
writeln(letter);
}

The output:

$ ./deneme
ç
à <-- will be different on different consoles


I tried that as well.


The problem is, char can implicitly be converted to dchar. Since the
letter ç consists of two chars (two UTF-8 code units), dchar gets the
first one converted as a dchar.

To see this, read and write two chars in a loop without a newline in
between:

import std.stdio;

void main()
{
foreach (i; 0 .. 2) {
char code;
readf("%s", &code);
write(code);
}

writeln();
}

This time two code units are read and then outputted to form a Unicode
character on the console:

$ ./deneme
ç
ç <-- result of two write(code) expressions

The solution is to use ranges when pulling Unicode characters out of
strings. std.stdin does not provide this yet, but it will eventually
happen (so I've heard :)).

For now, this is a way of getting Unicode characters from the input:

import std.stdio;

void main()
{
string line = readln();

foreach (dchar c; line) {
writeln(c);
}
}

Once you have the input as a string, std.utf.decode can also be used.

Ali



I'll give that a try, thanks.

--
/Jacob Carlborg


Re: Simulating multiple inheritance

2012-04-01 Thread Jacob Carlborg

On 2012-03-31 19:05, Andrej Mitrovic wrote:

This is related to wrapping wxWidgets.

One issue with the new wxWidgets 2.9.x series is that there seem to be
more multiply-inherited classes than before. In particular some of the
main classes have become MI classes (e.g. wxApp derives from
wxAppConsole which is now an MI class). Some wrappers (like wx.net)
maintain these classes manually and simply discard MI altogether and
make every class a singly-inherited class. SWIG does a similar thing
too. E.g. in wx.net wxApp on the C# side looks like this:


The first thing that pops up in my mind is using interfaces and template 
mixins, something like this: http://pastebin.com/jWMKQ6yy


--
/Jacob Carlborg


Re: Problem with receiveOnly and classes

2012-04-01 Thread Ghislain
> Either way, I once tried to pass over "ownership" of trees of objects to
> other threads but gave up on that. I don't think std.concurrency and D
> really can work like that. (?) Concurrency seems to work much better
> when you pass messages and data, structs are fine, and then build object
> trees from that on the other side etc. Sorry I can't help more.

I finally found a solution, thanks to your post: 
make a struct holding the object (and alias it so I can use it "nearly"
transparently).

I do not really like it, but it solves my problem. 
Would it be possible to integrate this into std.concurrency? 
I am newbie in D (my background is C++)

Here is sample code:


import std.stdio;
import std.concurrency;
class A{
public:
void fun()const{ writeln("A.fun()");}
}
class B : A{
public:
override void fun()const{ writeln("B.fun()");}
}
immutable struct P(T){
public:
immutable(T) t;
alias t this;
this(immutable(T) _t)immutable{
t = _t;
}
}
void producer(Tid t){
auto a = new immutable(A);
auto b = new immutable(B);

auto p1 = new P!A(a);
auto p2 = new P!A(b);
t.send(p1);
t.send(p2);
}


void main(){
auto t = spawn(&producer, thisTid);
while(1){
receive( 
(P!A* a){
writeln("matched P!A*"); 
a.fun();
},
(Variant v){
writeln("Unknown");
}
);
}
}


Re: Getting only the data members of a type

2012-04-01 Thread Artur Skawina
On 04/01/12 11:27, Artur Skawina wrote:
> On 04/01/12 08:18, Ali Çehreli wrote:
>> On 03/31/2012 09:09 PM, Artur Skawina wrote:
>>> This will print all fields of struct/class S:
>>>
>>> enum s = cast(S*)null;
>>> foreach (i, m; s.tupleof) {
>>>enum name = S.tupleof[i].stringof[4..$];
>>>alias typeof(m) type;
>>>writef("(%s) %s\n", type.stringof, name);
>>> }
>>>
>>> Real Programmers don't use std.traits. ;)
>>>
>>> artur
>>
>> Your method works but needing to iterate on a struct variable by s.tupleof 
>> and having to use the struct type as S.tupleof in the loop body is strange.
> 
> That's because the compiler won't accept "foreach (i, t; S.tupleof)" and 
> "*.tupleof[i].stringof" is necessary to get the original name. This would
> have worked too:
> 
>   enum name = *s.tupleof[i].stringof[4..$];
> 
> but obfuscates the code more and looks like dereferencing a null pointer.

That should have been:

  enum name = typeof(*s).tupleof[i].stringof[4..$];

artur


Re: Getting only the data members of a type

2012-04-01 Thread Artur Skawina
On 04/01/12 08:18, Ali Çehreli wrote:
> On 03/31/2012 09:09 PM, Artur Skawina wrote:
>> On 03/31/12 21:09, Ali Çehreli wrote:
>>> How can I determine just the data members of a struct or class, excluding 
>>> the member functions? isCallable() comes short as member variable that have 
>>> opCall() defined are also callable:
>> [...]
>>> Wait! I found a solution before sending this message. :P isIntegral() works:
>>>
>>>  if (isIntegral!(typeof(mixin("S." ~ member {
>>>
>>> Now the output is:
>>>
>>>  i is a member function
>>>  m is a member variable<-- good but dubious
>>>foo is a member variable
>> [...]
>>
>> Don't forget about templates (appear as members too, but don't have a type).
> 
> I see. We can't even use isCallable or isIntegral with a template member. 
> Assuming S has this member function template:
> 
> void bar(T)()
> {}
> 
> Then we get the following error:
> 
> /usr/include/d/dmd/phobos/std/traits.d(3223): Error: (S).bar(T) has no value
> 
> I don't know a way of saying "if a template".
  
eg:
   static if (!__traits(compiles, &__traits(getMember, obj, name)))
or just
   static if (!is(typeof(member))) 

>> This will print all fields of struct/class S:
>>
>> enum s = cast(S*)null;
>> foreach (i, m; s.tupleof) {
>>enum name = S.tupleof[i].stringof[4..$];
>>alias typeof(m) type;
>>writef("(%s) %s\n", type.stringof, name);
>> }
>>
>> Real Programmers don't use std.traits. ;)
>>
>> artur
> 
> Your method works but needing to iterate on a struct variable by s.tupleof 
> and having to use the struct type as S.tupleof in the loop body is strange.

That's because the compiler won't accept "foreach (i, t; S.tupleof)" and 
"*.tupleof[i].stringof" is necessary to get the original name. This would
have worked too:

  enum name = *s.tupleof[i].stringof[4..$];

but obfuscates the code more and looks like dereferencing a null pointer.

artur


Re: "ref const" parameters in functions

2012-04-01 Thread Jonathan M Davis
On Sunday, April 01, 2012 09:10:58 L-MAN wrote:
> On Saturday, 31 March 2012 at 21:42:05 UTC, Jonathan M Davis
> 
> wrote:
> > On Saturday, March 31, 2012 23:25:51 L-MAN wrote:
> >> Hello everybody!
> >> 
> >> I'm trying to use some function FN like this:
> >> 
> >> struct X
> >> {
> >> 
> >>   protected double _x;  // double type for example
> >>   public @property double X() const { return _x; }
> >>   
> >>   // ctor
> >>   public this(double x) { _x = x; } // double type for example
> >>   
> >>   void FN(ref const(double) in_x) // double type for example
> >>   {
> >>   
> >> // ... do some operations with _x
> >>   
> >>   }
> >> 
> >> }
> >> 
> >> main(..)
> >> {
> >> 
> >>   
> >>   X x = X(20);
> >>   
> >>   x.FN(30); // getting an error
> >> 
> >> }
> >> 
> >>   why x.FN(20) gets me an error?
> >>   the construction "ref const(double)" or "ref
> >> 
> >> immutable(double)"
> >> must be an rvalue by default I think, but in FN parameter the
> >> compiler expects an lvalue...
> >> 
> >>   this strategy is the way to some unnecessary copy operations,
> >> 
> >> when value 20 (or some big struct instead of it) will copy to
> >> the
> >> stack..
> >> 
> >> How can I resolve this problem?
> > 
> > Unlike C++, const ref _must_ be an lvalue just like ref. If you
> > use auto ref
> > instead of const ref, the compiler is supposed to choose
> > between ref and non-
> > ref based on which it thinks would be more efficient, but it
> > currently only
> > works with templated types.
> > 
> > You can duplicate the function and have a version whose
> > parameter is const ref
> > and one which is not, but be careful if you try and make the
> > non-const ref
> > version call the const ref version (to avoid duplicating the
> > function's body)
> > and make sure that you don't get infinite recursion. It usually
> > works, but I've
> > run into cases before where I ended up with infinite recursion,
> > so make sure
> > that you have unit tests which check.
> > 
> > Regardless, if you're dealing with a primitive type like
> > double, don't bother
> > with const ref. It's not going to be more efficient. It's with
> > large structs
> > that you can see a difference.
> > 
> > - Jonathan M Davis
> 
> Thank you for reply, but how can I exclude some copy operations?
> Look at this sample:
> 
> struct ABC // simple class
> {
>   private double _d=0;
>   @property
>   {
>   double D() const { return _d; }
>   double D(double val) { return _d=val; }
>   }
> 
>   this(double d)
>   {
>   _d = d;
>   writeln(" *** ctor ABC, d = ", _d);
>   }
> 
>   ABC opAdd(ABC abc)
>   {
>   //ABC temp = ABC(this._d+abc._d);
>   //return temp;
>   return ABC(this._d+abc._d);
>   }
> 
>   ABC opMul(double d)
>   {
>   //ABC temp = ABC(this._d*d);
>   //return temp;
>   return ABC(this._d*d);
>   }
> 
>   ref ABC opAssign(ABC abc)
>   {
>   this._d = abc.D;
>   return this;
>   }
> 
>   ~this()
>   {
>   writeln(" *** dtor ABC, d = ", _d);
>   }
> }
> 
> 
> struct F {
> 
>   private ABC _abc;
> 
>   @property double D() const { return _abc.D; }
> 
>   public this(ABC abc)
>   {
>   _abc = abc;
> 
>   //abc.D=90;
>   //pnt.X = 30;
>   }
> }
> 
> 
> void main(string[] args)
> {
>ABC abc1 = ABC(10);
>ABC abc2 = ABC(20);
>F f = F(abc1+abc2*20.0);
>writeln(f.D);
>   ...
> }
> 
> Operation abc1+abc2*20.0 consists of 2 ABC copy:
> 1. Copy result of abc2*20.0 temp value to opAdd function
> 2. Copy result of abc1+abc2*20.0 temp2 value to F() ctor
> two temp variables and two copy operations.
> But if I can use "ref const" rvalue operations 0 copies will be
> need:
>abc2*20.0 creates temp valiable $$$temp
>opAdd(ref const ABC abc)  use a ref rvalue to $$$temp, is not a
> copy
>opAdd return a $$$temp2 that use as ref rvalue for F() ctor
> And try to imagine how many unnecessary copies of ABC will create
> a simple operation like this:
>   ((abc1+abc2*20.0)/0.25) + (abc1/abc2)*(abc2-1)
>it killing a time of application, especially if time is
> critical.
> 
> The constructions "auto ref" in return functions values are not
> working well, if I use it in a "auto ref opAdd(ref const ABC)"
> "auto ref opMul(double d)" " F.this(ref const ABC)" to exclude
> some copy operations it gives me a strange result :-((

You misunderstood what I meant by auto ref. I meant that you use auto ref 
instead of const ref. e.g.

void func(auto ref T param) {}

At present, func would have to be templated to use auto ref

void func(T)(auto ref T param) {}

but eventually, auto ref shouldn't need the function to be templated. 
Returning auto ref is completely different. It says that the return type is 
inferred (just like with returning auto by itself) 

Re: "ref const" parameters in functions

2012-04-01 Thread L-MAN
On Saturday, 31 March 2012 at 21:42:05 UTC, Jonathan M Davis 
wrote:

On Saturday, March 31, 2012 23:25:51 L-MAN wrote:

Hello everybody!

I'm trying to use some function FN like this:

struct X
{
  protected double _x;  // double type for example
  public @property double X() const { return _x; }

  // ctor
  public this(double x) { _x = x; } // double type for example

  void FN(ref const(double) in_x) // double type for example
  {
// ... do some operations with _x
  }

}

main(..)
{
  
  X x = X(20);

  x.FN(30); // getting an error
}


  why x.FN(20) gets me an error?
  the construction "ref const(double)" or "ref 
immutable(double)"

must be an rvalue by default I think, but in FN parameter the
compiler expects an lvalue...
  this strategy is the way to some unnecessary copy operations,
when value 20 (or some big struct instead of it) will copy to 
the

stack..

How can I resolve this problem?


Unlike C++, const ref _must_ be an lvalue just like ref. If you 
use auto ref
instead of const ref, the compiler is supposed to choose 
between ref and non-
ref based on which it thinks would be more efficient, but it 
currently only

works with templated types.

You can duplicate the function and have a version whose 
parameter is const ref
and one which is not, but be careful if you try and make the 
non-const ref
version call the const ref version (to avoid duplicating the 
function's body)
and make sure that you don't get infinite recursion. It usually 
works, but I've
run into cases before where I ended up with infinite recursion, 
so make sure

that you have unit tests which check.

Regardless, if you're dealing with a primitive type like 
double, don't bother
with const ref. It's not going to be more efficient. It's with 
large structs

that you can see a difference.

- Jonathan M Davis


Thank you for reply, but how can I exclude some copy operations?
Look at this sample:

struct ABC // simple class
{
private double _d=0;
@property
{
double D() const { return _d; }
double D(double val) { return _d=val; }
}

this(double d)
{
_d = d;
writeln(" *** ctor ABC, d = ", _d);
}

ABC opAdd(ABC abc)
{
//ABC temp = ABC(this._d+abc._d);
//return temp;
return ABC(this._d+abc._d);
}

ABC opMul(double d)
{
//ABC temp = ABC(this._d*d);
//return temp;
return ABC(this._d*d);
}

ref ABC opAssign(ABC abc)
{
this._d = abc.D;
return this;
}

~this()
{
writeln(" *** dtor ABC, d = ", _d);
}
}


struct F {

private ABC _abc;

@property double D() const { return _abc.D; }

public this(ABC abc)
{
_abc = abc;

//abc.D=90;
//pnt.X = 30;
}
}


void main(string[] args)
{
  ABC abc1 = ABC(10);
  ABC abc2 = ABC(20);
  F f = F(abc1+abc2*20.0);
  writeln(f.D);
 ...
}

Operation abc1+abc2*20.0 consists of 2 ABC copy:
1. Copy result of abc2*20.0 temp value to opAdd function
2. Copy result of abc1+abc2*20.0 temp2 value to F() ctor
two temp variables and two copy operations.
But if I can use "ref const" rvalue operations 0 copies will be 
need:

  abc2*20.0 creates temp valiable $$$temp
  opAdd(ref const ABC abc)  use a ref rvalue to $$$temp, is not a 
copy

  opAdd return a $$$temp2 that use as ref rvalue for F() ctor
And try to imagine how many unnecessary copies of ABC will create 
a simple operation like this:

 ((abc1+abc2*20.0)/0.25) + (abc1/abc2)*(abc2-1)
  it killing a time of application, especially if time is 
critical.


The constructions "auto ref" in return functions values are not 
working well, if I use it in a "auto ref opAdd(ref const ABC)" 
"auto ref opMul(double d)" " F.this(ref const ABC)" to exclude 
some copy operations it gives me a strange result :-((


Thank you!!!