Re: DDoc with cross-references
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: a name=Appender/a 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: Add Element to list not Working
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: Add Element to list not Working
On 2 April 2012 17:45, Chris Pons cmp...@gmail.com 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: DDoc with cross-references
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: a name=Appender/a 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 a name=$0 / $(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
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: ref const parameters in functions
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: DDoc with cross-references
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: a name=Appender/a 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 a name=$0 / $(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: Getting only the data members of a type
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
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: DDoc with cross-references
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: std.typecons.Ref(T).opImplicitCastTo()
On 02-04-2012 07:32, Jonathan M Davis wrote: 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 To clarify, I mean to ask whether there are any design flaws in the strategy of having multiple alias this in one type, or whether it is purely an issue in the implementation (i.e. just plain hasn't been done yet)? -- - Alex
Re: Whats the best way to get a struct/class member type?
On Mon, 02 Apr 2012 00:04:58 +0200, Simen Kjærås simen.kja...@gmail.com wrote: On Sat, 31 Mar 2012 15:20:42 +0200, simendsjo simend...@gmail.com 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; } getMember requires an instance, not a type, so it should be template getMemberType(T, string name) if(__traits(hasMember, T, name) { T t; alias typeof(__traits(getMember, t, name)) getMemberType; }
Re: Whats the best way to get a struct/class member type?
On Mon, 02 Apr 2012 09:58:18 +0200, simendsjo simend...@gmail.com wrote: On Mon, 02 Apr 2012 00:04:58 +0200, Simen Kjærås simen.kja...@gmail.com wrote: On Sat, 31 Mar 2012 15:20:42 +0200, simendsjo simend...@gmail.com 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; } getMember requires an instance, not a type, so it should be template getMemberType(T, string name) if(__traits(hasMember, T, name) { T t; alias typeof(__traits(getMember, t, name)) getMemberType; } Tested and works for me under 2.058 with just the type.
Re: Whats the best way to get a struct/class member type?
On Mon, 02 Apr 2012 10:51:35 +0200, Simen Kjaeraas simen.kja...@gmail.com wrote: On Mon, 02 Apr 2012 09:58:18 +0200, simendsjo simend...@gmail.com wrote: On Mon, 02 Apr 2012 00:04:58 +0200, Simen Kjærås simen.kja...@gmail.com wrote: On Sat, 31 Mar 2012 15:20:42 +0200, simendsjo simend...@gmail.com 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; } getMember requires an instance, not a type, so it should be template getMemberType(T, string name) if(__traits(hasMember, T, name) { T t; alias typeof(__traits(getMember, t, name)) getMemberType; } Tested and works for me under 2.058 with just the type. You're right - works on 2.059 trunk too.. The documentation explicitly says it shouldn't work for other than static members though. http://dlang.org/traits.html#getMember
Re: Whats the best way to get a struct/class member type?
On Mon, 02 Apr 2012 10:56:41 +0200, simendsjo simend...@gmail.com wrote: The documentation explicitly says it shouldn't work for other than static members though. http://dlang.org/traits.html#getMember http://d.puremagic.com/issues/show_bug.cgi?id=7809
Re: Whats the best way to get a struct/class member type?
On Mon, 02 Apr 2012 12:22:16 +0200, Simen Kjaeraas simen.kja...@gmail.com wrote: On Mon, 02 Apr 2012 12:07:38 +0200, simendsjo simend...@gmail.com wrote: On Mon, 02 Apr 2012 10:56:41 +0200, simendsjo simend...@gmail.com wrote: The documentation explicitly says it shouldn't work for other than static members though. http://dlang.org/traits.html#getMember http://d.puremagic.com/issues/show_bug.cgi?id=7809 struct Foo { int n; } void main( ) { static assert(is(typeof(Foo.n) == int)); } Yup, it compiles. Mayhap it shouldn't, but it does. Of course, trying to use it for anything but typeof gives you an error. From this we can conclude that either this behavior is also buggy, or getMember should work that way. It's convenient that it works this way. Probably a change that didn't get reflected to the documentation.
Re: DDoc with cross-references
On Monday, 2 April 2012 at 04:20:16 UTC, Ary Manzana wrote: (in fact, now I notice it's flawed, because they are not fully-qualified). I have a dmd pull request waiting for a few fixes from me that will help with this. It adds fully qualified names to one of the outputs so we can do anchors from it, and also fixes the godawful mess that is proper character encoding right now (by doing custom character replacement prior to macros. This disables the embedded HTML misfeature, which breaks a lot of the website right now, but is a big win for sanity.)
Re: Add Element to list not Working
On 04/01/2012 11:18 PM, Chris Pons wrote: Thanks. I tried doing this and the list didn't update: void AddToList( SList!int list, int i ) { list.insert( i ); } Oh, that has nothing to do with SList. SList is a struct and as a fundamental rule of D, structs are copied to functions. SList happens to be a struct. The list parameter of AddToList and the list variable that is passed to the function as an argument are two different variables. SList!int intList; AddToList( intList, 42 ); but when I switched to this, it worked: SList!int intList; void AddToList( int i ) { intList.insert( i ); } Global variables are not a good solution of course. :( The solution here is to pass the argument by-reference by the 'ref' keyword: void AddToList( ref SList!int list, int i ) { // ... } Ali P.S. There is this chapter that covers 'ref' and most (but not all) types of function parameters: http://ddili.org/ders/d.en/function_parameters.html
Help with C++
Hi, I'm trying to make some additions to DMD. First I want to add a virtual function: virtual void emitLink(OutBuffer *buf) to the struct Type. I did that. Then on doc.c I implement it empty: void Type::emitLink(OutBuffer *buf) { } Then I use it somewhere, like in AliasDeclaration::toDocBuffer: type-emitLink(buf); I compile it, it's fine. When I run DMD with the -D switch I get: Bus error: 10 I thought maybe the type is null, so: if (type) type-emitLink(buf); But no luck. I tried to copy the prototype of: virtual TypeBasic *isTypeBasic() without luck. What am I doing wrong? Thanks, Ary
Re: std.typecons.Ref(T).opImplicitCastTo()
On Monday, April 02, 2012 09:37:04 Alex Rønne Petersen wrote: On 02-04-2012 07:32, Jonathan M Davis wrote: 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 To clarify, I mean to ask whether there are any design flaws in the strategy of having multiple alias this in one type, or whether it is purely an issue in the implementation (i.e. just plain hasn't been done yet)? As far as I know, it's purely an implementation issue, but I don't know. - Jonathan M Davis
Re: Add Element to list not Working
Ah, thank you. I didn't realize taht SList is a struct and that it used value semantics. That clears this up. On Monday, 2 April 2012 at 14:22:25 UTC, Ali Çehreli wrote: On 04/01/2012 11:18 PM, Chris Pons wrote: Thanks. I tried doing this and the list didn't update: void AddToList( SList!int list, int i ) { list.insert( i ); } Oh, that has nothing to do with SList. SList is a struct and as a fundamental rule of D, structs are copied to functions. SList happens to be a struct. The list parameter of AddToList and the list variable that is passed to the function as an argument are two different variables. SList!int intList; AddToList( intList, 42 ); but when I switched to this, it worked: SList!int intList; void AddToList( int i ) { intList.insert( i ); } Global variables are not a good solution of course. :( The solution here is to pass the argument by-reference by the 'ref' keyword: void AddToList( ref SList!int list, int i ) { // ... } Ali P.S. There is this chapter that covers 'ref' and most (but not all) types of function parameters: http://ddili.org/ders/d.en/function_parameters.html
Re: Add Element to list not Working
On Monday, April 02, 2012 20:27:18 Chris Pons wrote: Ah, thank you. I didn't realize taht SList is a struct and that it used value semantics. That clears this up. It really shouldn't be using value semantics (though it wouldn't surprise me if it is - I haven't used it). std.container's containers are supposed to be reference types, but how that's going to be implemented exactly is still in flux - in part due to the pending custom allocator design. In the long run, std.container's containers will likely be ref-counted structs in the long run, but they may end up being classes. - Jonathan M Davis
Re: Help with C++
On 02.04.2012 18:27, Ary Manzana wrote: Hi, I'm trying to make some additions to DMD. First I want to add a virtual function: virtual void emitLink(OutBuffer *buf) to the struct Type. I did that. Then on doc.c I implement it empty: void Type::emitLink(OutBuffer *buf) { } Then I use it somewhere, like in AliasDeclaration::toDocBuffer: type-emitLink(buf); I compile it, it's fine. When I run DMD with the -D switch I get: Bus error: 10 Looks like a link-time breakage, i.e. some object file compiled against an older version of header/src and consequently older v-table. Maybe the dmd makefile is faulty and doesn't trigger proper rebuilds, do a 'make clean' to be sure. -- Dmitry Olshansky
Length of an SLIst ?
I'm trying to find the length of a Slist. I've tried using the built in .length function but it generates this error: Error: no property 'length' for type 'SList!(Node)'. Are there any other built in ways to find the length?
Re: Length of an SLIst ?
On Mon, 02 Apr 2012 22:42:23 +0200, Chris Pons wrote: I'm trying to find the length of a Slist. I've tried using the built in .length function but it generates this error: Error: no property 'length' for type 'SList!(Node)'. Are there any other built in ways to find the length? Classic singly-linked lists must be iterated to determine length, so use std.range.walkLength on it.
Re: ref const parameters in functions
On Mon, 02 Apr 2012 00:23:50 -0400, Jonathan M Davis jmdavisp...@gmx.com wrote: 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. Also, 'this' is passed as a reference, even though it could be an rvalue. This makes for some WTF cases. For example: struct S { int x; S opBinary(string op)(ref const S other) const { return S(other.x + x);} } void main() { auto s = S(1); auto s2 = S(2); auto s3 = (s + s2) + s2; // ok auto s4 = s2 + (s + s2); // error } I think the current state of affairs is far from ideal, and really should get some more attention, but it's quite low on the priority list. -Steve 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: Length of an SLIst ?
On 4/2/12, Justin Whear jus...@economicmodeling.com wrote: Classic singly-linked lists must be iterated to determine length, so use std.range.walkLength on it. Specifically call it on its range. You can get a range by slicing the slist, e.g.: import std.range; import std.container; void main() { auto s = SList!int(1, 2, 5, 10); assert(walkLength(s[]) == 4); }
Re: Length of an SLIst ?
On 4/2/12, Justin Whear jus...@economicmodeling.com wrote: Classic singly-linked lists must be iterated to determine length I'm no algorithms buff, but I don't understand the benefit of not storing the length in the SList. What does it cost to maintain an extra variable? It's a single increment/decrement on each add/remove and a little bit of memory to store the count.
Re: Length of an SLIst ?
On 04/02/2012 02:10 PM, Andrej Mitrovic wrote: On 4/2/12, Justin Whearjus...@economicmodeling.com wrote: Classic singly-linked lists must be iterated to determine length I'm no algorithms buff, but I don't understand the benefit of not storing the length in the SList. What does it cost to maintain an extra variable? It's a single increment/decrement on each add/remove and a little bit of memory to store the count. Length is not a property of singly-linked lists partly because they are supposed to be very light weight data structures. Imagine a hash table with buckets based on singly-linked lists. The length property would not add any value there but would double the table size. I remember Matt Austern's presentation on a C++ singly linked list implementation where he had explicitly mentioned that he had decided to not provide length for the same reason. (I vaguely remember that his implementation was for addition to the C++ library, perhaps only to support the hash table? I don't remember now.) Ali
Re: Length of an SLIst ?
On Mon, 02 Apr 2012 17:10:40 -0400, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 4/2/12, Justin Whear jus...@economicmodeling.com wrote: Classic singly-linked lists must be iterated to determine length I'm no algorithms buff, but I don't understand the benefit of not storing the length in the SList. What does it cost to maintain an extra variable? It's a single increment/decrement on each add/remove and a little bit of memory to store the count. It all depends on how you model the data. If the data is contained/owned by a single instance, then you can store the length inside that instance. If it's not owned (i.e. sublists are also valid SLists) then you cannot do that. In terms of tradeoffs, generally you have to choose between O(1) splicing (i.e. removing the tail elements of a list, or splicing in another list in the middle) and O(1) length. -Steve
Re: Length of an SLIst ?
On Mon, 02 Apr 2012 23:10:40 +0200, Andrej Mitrovic wrote: On 4/2/12, Justin Whear jus...@economicmodeling.com wrote: Classic singly-linked lists must be iterated to determine length I'm no algorithms buff, but I don't understand the benefit of not storing the length in the SList. What does it cost to maintain an extra variable? It's a single increment/decrement on each add/remove and a little bit of memory to store the count. Generally a singly-linked list is not a single container object, but a chain of nodes. Each node knows only of the existence of the next node, so operations such as insertion and deletion require just snapping a new node into the chain and are constant-time. By contrast, random-access operations require walking the chain to find the requested node. In many respects, slists and arrays are opposites, with one's weakness being the other's strength.
Re: Length of an SLIst ?
On 4/2/12, Steven Schveighoffer schvei...@yahoo.com wrote: (i.e. sublists are also valid SLists) I haven't thought of that, good point. :)
Re: Length of an SLIst ?
Steven Schveighoffer: It all depends on how you model the data. If the data is contained/owned by a single instance, then you can store the length inside that instance. If it's not owned (i.e. sublists are also valid SLists) then you cannot do that. Let me add something to your answer. With Dependent Types (http://en.wikipedia.org/wiki/Dependent_types ) you are sometimes able to use the list length, encoded in the types, despite at run-time the lengths aren't stored in the run-time data structure :-) This is not always possible, and it generally requires a type system more powerful than the D type system if you also want it to be sufficiently handy to use. Bye, bearophile
Re: ref const parameters in functions
On 04/02/2012 06:23 AM, Jonathan M Davis wrote: 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). DMD 2.059head treats struct literals as rvalues.
Re: ref const parameters in functions
On Tuesday, April 03, 2012 00:28:03 Timon Gehr wrote: On 04/02/2012 06:23 AM, Jonathan M Davis wrote: 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). DMD 2.059head treats struct literals as rvalues. Awesome! - Jonathan M Davis
Min-Heap and Hash Table help
I'm trying to work with and implement and priority queue( min-heap ) and a hash table. This is the first time I've worked with these data structures so I looked up some information about them to gain an understanding. From what I read, a min-heap is a binary tree that is sorted by a priority. In my case I have a struct called Node for an A* algorithm that I wanted to place in a min-heap sorted by an integer, their f score. Initially the min-heap will only have one item in it with others added later. From looking at the Library reference I have gathered this: struct Node { bool walkable; //Whether this node is blocked or open vect2 position; //The tile's position on the map in pixels int xIndex, yIndex; //The index values of the tile in the array Node*[4] connections; //An array of pointers to nodes this current node connects to Node* parent; int gScore; int hScore; int fScore; } Class AStar { Node[] a; Node start; void FindPath(Node[] PathGraph ) { a ~= start; //Heapify as min-heap by f Score? openList = heapify(a, a.fScore b.fScore ); //...After some work If I want to add a new Node Node new; //Will the list stay sorted?? openList.insert( new ); } } How would I create a min-heap sorted by fScore? Will the list stay sorted after I add a new node? As far as hash tables goes, it seems like I need to use an associative array, is that right? What exactly would the key/hash be? How would I implement this if the hash table is supposed to contain the struct Node?
Re: Min-Heap and Hash Table help
On Tue, 03 Apr 2012 00:47:56 +0200, Chris Pons wrote: I'm trying to work with and implement and priority queue( min-heap ) and a hash table. This is the first time I've worked with these data structures so I looked up some information about them to gain an understanding. From what I read, a min-heap is a binary tree that is sorted by a priority. In my case I have a struct called Node for an A* algorithm that I wanted to place in a min-heap sorted by an integer, their f score. Initially the min-heap will only have one item in it with others added later. How would I create a min-heap sorted by fScore? Will the list stay sorted after I add a new node? As far as hash tables goes, it seems like I need to use an associative array, is that right? What exactly would the key/hash be? How would I implement this if the hash table is supposed to contain the struct Node? BinaryHeap in std.container can be made to work as a min-heap, in fact the documentation specifically mentions such a use: http://dlang.org/ phobos/std_container.html#BinaryHeap
Re: Min-Heap and Hash Table help
Yes, I did see that. How would I set the predicate to sort by fScore? An integer in my struct. On Monday, 2 April 2012 at 22:53:55 UTC, Justin Whear wrote: On Tue, 03 Apr 2012 00:47:56 +0200, Chris Pons wrote: I'm trying to work with and implement and priority queue( min-heap ) and a hash table. This is the first time I've worked with these data structures so I looked up some information about them to gain an understanding. From what I read, a min-heap is a binary tree that is sorted by a priority. In my case I have a struct called Node for an A* algorithm that I wanted to place in a min-heap sorted by an integer, their f score. Initially the min-heap will only have one item in it with others added later. How would I create a min-heap sorted by fScore? Will the list stay sorted after I add a new node? As far as hash tables goes, it seems like I need to use an associative array, is that right? What exactly would the key/hash be? How would I implement this if the hash table is supposed to contain the struct Node? BinaryHeap in std.container can be made to work as a min-heap, in fact the documentation specifically mentions such a use: http://dlang.org/ phobos/std_container.html#BinaryHeap
Re: Min-Heap and Hash Table help
On Tue, 03 Apr 2012 01:06:54 +0200, Chris Pons wrote: Yes, I did see that. How would I set the predicate to sort by fScore? An integer in my struct. auto myHeap = BinaryHeap!`a.fScore b.fScore`( rangeOfNodes );
Re: Min-Heap and Hash Table help
On Monday, 2 April 2012 at 23:30:38 UTC, Justin Whear wrote: On Tue, 03 Apr 2012 01:06:54 +0200, Chris Pons wrote: Yes, I did see that. How would I set the predicate to sort by fScore? An integer in my struct. auto myHeap = BinaryHeap!`a.fScore b.fScore`( rangeOfNodes ); Ok, makes sense, will the heap be automatically sorted every time I add a new item ? Might be a dumb question, but i'm going to be removing and adding many nodes.
Equivalents to policy classes in D
Hello all, I'm coming to D from a background programming in C and C++, though I wouldn't describe myself as an expert in either. One of the C++ techniques I picked up over the last couple of years was the use of policy classes, and I'm wondering how D addresses this issue of combining various small components together to implement a given interface. D's interfaces seem an obvious starting point, but from the documentation I've read, it seems like each implementation has to be written separately. So, if I have an interface, interface FooBar { void foo(); void bar(); } ... I can of course write two different implementations, class FooBarOne : FooBar { override void foo() { // Foo function implementation ... } override void bar() { // Bar function implementation ... } } class FooBarTwo : FooBar { override void foo() { // Foo function implementation ... } override void bar() { // Bar function implementation ... } } ... but suppose that I'd like the foo() function to be identical in both; how do I avoid rewriting the code? In C++ I'd think of a policy class, template class Foo, class Bar class FooBar : public Foo, public Bar { ... }; and then have, typedef FooBarFooGeneric,BarOne FooBarOne; typedef FooBarFooGeneric,BarTwo FooBarTwo; ... but I don't see how to do something equivalent with D's interfaces and implementations. Can anyone advise? Thanks and best wishes, -- Joe
Re: Equivalents to policy classes in D
Mixins templates would be the answer: import std.exception; mixin template UncheckedIndices( T ) { ref T opIndex( int i ) { return this.get_( i ); } } mixin template CheckedIndices( T ) { ref T opIndex( int i ) { enforce( i 0 i this.size ); return this.get_( i ); } } struct Array( T, alias IndexPolicy ) { private T* array; private int size_; this( size_t n ) { array = (new T[ n ]).ptr; } @property size_t size() { return size_; } private ref T get_( size_t i ) { return array[ i ]; } mixin IndexPolicy!T; } void main() { auto arr1 = Array!(int, UncheckedIndices)( 10 ); auto arr2 = Array!(int, CheckedIndices)( 10 ); arr2[ 11 ] = 5; } --- Cristi Cobzarenco BSc in Artificial Intelligence and Computer Science University of Edinburgh Profile: http://www.google.com/profiles/cristi.cobzarenco On 3 April 2012 00:15, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: Hello all, I'm coming to D from a background programming in C and C++, though I wouldn't describe myself as an expert in either. One of the C++ techniques I picked up over the last couple of years was the use of policy classes, and I'm wondering how D addresses this issue of combining various small components together to implement a given interface. D's interfaces seem an obvious starting point, but from the documentation I've read, it seems like each implementation has to be written separately. So, if I have an interface, interface FooBar { void foo(); void bar(); } ... I can of course write two different implementations, class FooBarOne : FooBar { override void foo() { // Foo function implementation ... } override void bar() { // Bar function implementation ... } } class FooBarTwo : FooBar { override void foo() { // Foo function implementation ... } override void bar() { // Bar function implementation ... } } ... but suppose that I'd like the foo() function to be identical in both; how do I avoid rewriting the code? In C++ I'd think of a policy class, template class Foo, class Bar class FooBar : public Foo, public Bar { ... }; and then have, typedef FooBarFooGeneric,BarOne FooBarOne; typedef FooBarFooGeneric,BarTwo FooBarTwo; ... but I don't see how to do something equivalent with D's interfaces and implementations. Can anyone advise? Thanks and best wishes, -- Joe
Re: Help with C++
On 4/3/12 4:01 AM, Dmitry Olshansky wrote: On 02.04.2012 18:27, Ary Manzana wrote: Hi, I'm trying to make some additions to DMD. First I want to add a virtual function: virtual void emitLink(OutBuffer *buf) to the struct Type. I did that. Then on doc.c I implement it empty: void Type::emitLink(OutBuffer *buf) { } Then I use it somewhere, like in AliasDeclaration::toDocBuffer: type-emitLink(buf); I compile it, it's fine. When I run DMD with the -D switch I get: Bus error: 10 Looks like a link-time breakage, i.e. some object file compiled against an older version of header/src and consequently older v-table. Maybe the dmd makefile is faulty and doesn't trigger proper rebuilds, do a 'make clean' to be sure. Yes, that was it. Thanks!
Re: Equivalents to policy classes in D
On 3 April 2012 12:24, Cristi Cobzarenco cristi.cobzare...@gmail.com wrote: Mixins templates would be the answer: import std.exception; mixin template UncheckedIndices( T ) { ref T opIndex( int i ) { return this.get_( i ); } } mixin template CheckedIndices( T ) { ref T opIndex( int i ) { enforce( i 0 i this.size ); return this.get_( i ); } } struct Array( T, alias IndexPolicy ) { private T* array; private int size_; this( size_t n ) { array = (new T[ n ]).ptr; } @property size_t size() { return size_; } private ref T get_( size_t i ) { return array[ i ]; } mixin IndexPolicy!T; } void main() { auto arr1 = Array!(int, UncheckedIndices)( 10 ); auto arr2 = Array!(int, CheckedIndices)( 10 ); arr2[ 11 ] = 5; } Another option is to use alias this to forward method calls on. Currently you can only have 1 alias this in a class/struct, but that is a temporary and D is supposed to allow multiple alias this declarations. Depending on the scope of your situation, you could also use conditional compilation in conjunction with templates to implement your policies, often interfaces aren't needed when you only want/need a minor change, I only use them for polymorphism in D. -- James Miller
Re: Min-Heap and Hash Table help
On Monday, 2 April 2012 at 23:42:45 UTC, Chris Pons wrote: On Monday, 2 April 2012 at 23:30:38 UTC, Justin Whear wrote: On Tue, 03 Apr 2012 01:06:54 +0200, Chris Pons wrote: Yes, I did see that. How would I set the predicate to sort by fScore? An integer in my struct. auto myHeap = BinaryHeap!`a.fScore b.fScore`( rangeOfNodes ); Ok, makes sense, will the heap be automatically sorted every time I add a new item ? Might be a dumb question, but i'm going to be removing and adding many nodes. I haven't looked at the heap docs for Phobos, but the whole point of a heap is that when you add/remove elements it remains in heap order. In the case of a min-heap: the smallest node is at the root and each child node is another heap in heap order.
Re: Min-Heap and Hash Table help
each child node is another heap in heap order. That should be: each child node is the root node of another heap in heap order.
Re: Equivalents to policy classes in D
I'm not all that familiar with policy classes but, if I understand what you are asking correctly, you can provide implementations in interfaces if the methods are final or static. Is this the sort of thing you mean? import std.stdio; interface Foo { final string foo() { return foo; } } interface Bar { final string bar() { return bar; } } template IsInterface(T) { enum IsInterface = is(T == interface); } class Policy(T, U) if(IsInterface!T IsInterface!U) : T, U { } alias Policy!(Foo, Bar) FooBar; void main() { auto fb = new FooBar(); writeln(fb.foo(), and , fb.bar()); }
Re: Min-Heap and Hash Table help
I'm still having troubles with the min-heap. Node[] a; auto b = BinaryHeap!a.fScore b.fScore( a[] ); Error 1 Error: template instance BinaryHeap!(a.fScore b.fScore) BinaryHeap!(a.fScore b.fScore) does not match template declaration BinaryHeap(Store,alias less = a b) if (isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[]))) C:\Users\CP\Documents\Visual Studio 2010\Projects\D\STDS\NPC.d 252
Custom Allocators
I've been doing some reading on dlang.org and the newsgroup archives and have seen talk about allocators and things around the garbage collector. I have a few questions about the entire thing: - I understand that allocators are all about memory management, but how does this affect D and the way allocators are integrated into the language? - How are allocators supposed to work with the GC? I know that you can manually allocate memory and add the range to the GC, but why do you have to do this? - I've read that custom allocators aren't implemented, but I see references to using new() and delete() in classes in the docs? Is this one of the cases where the docs are what it should be and the reality is different? If there aren't custom allocators, then are there any major blockers to the addition (or is it just because nobody has added it?)? - Would it be possible to use custom allocators to write a completely GC-free application (using ref-counting instead for example)? Or would the GC still be used anyway? If I'm way off base on anything, feel free to say so, memory management and garbage collection aren't exactly my strong suits. Thanks -- James Miller
parallel unzip in progress
I'm working on a parallel unzip. I started with phobos std.zip, but found that to be too monolithic. I needed to separate out the tasks that get the directory entries, create the directory tree, get the compressed data, expand the data and create the uncompressed files on disk. It currently unzips a 2GB directory struct in about 18 secs while 7zip takes around 55 secs. Only about 4 seconds of this is the creation of the directory structure and the expanding. The other 14 secs is writing the regular files. The subtasks needed to be separated not only because of the need to run them in parallel, but also because the current std.zip implementation is a memory hog, keeping the whole compressed and expanded data sections in memory. I was running out of memory in a 32 bit application just attempting to unzip the test file with the std.zip operations. The parallel version peaks at around 150MB memory used during the operation. The parallel version is still missing the operation of restoring the original file attributes, and I see no example in the documents of what would normally be done. Am I missing this somewhere? I'll have to dig around...