Re: param2 = param1
On Tuesday, 27 August 2013 at 21:21:31 UTC, Timon Gehr wrote: - Safe alloca wrapper using the alloca default argument hack together with this. (i.e. bearophile's dynamically-sized strongly typed stack-based arrays.) Oh Yes please! I've been waiting for this for a long time, there even was an enhancement request written to facilitate the alloca default argument hack! http://d.puremagic.com/issues/show_bug.cgi?id=8075
Re: Range interface for std.serialization
On 2013-08-27 22:12, Dmitry Olshansky wrote: I see... That depends on the format and for these that have no keys or markers of any kind versioning might help here. For instance JSON/BSON could handle permutation of fields, but I then it falls short of handling links e.g. pointers (maybe there is a trick to get it, but I can't think of any right away). For pointers and reference types I currently serializing all fields with an id then when there's a pointer or reference I can just do this: 3 1 I suspect it would be best to somehow see archives by capbilities: 1. Rigid (most binary) - in-order, depends on the order of fields, may need to fit a scheme (in this cases D types implicitly define one) Rigid archivers may also enjoy (per format in the future) a code generator that given a scheme defines D types with a bit of CTFE+mixin. 2. Flexible - can survive reordering, is scheme-less, data defines structure etc. easer handles versioning e.g. XML is one. Yes, that's a good idea. In the binary archiver I'm working on I'm cheating quite a bit and relax the requirements made by the serializer. This also neatly answers the question about scheme vs scheme-less serialization. Protocol buffers/Thrift may be absorbed into Rigid category if we can get the versioning right. Also solving versioning is the last roadblock (after ranges) mentioned on the path to making this an epic addition to Phobos. Versioning shouldn't be that hard, I think. + Some kind of capability flag (compile-time) if it can serialize full graphs or if the format is to limited for such. Taking that with Rigid would cover most adhoc binary formats in the wild, with Flexible it would handle some simple hierarchical formats as well. Sounds like a good idea. Was it DOM-ish too? Yes. I've meant at least a check of 'mode' on each call to (de)serialize + some other branch-y stuff that tests overridden serializers etc. It could be a relatively new idiom to follow but there is a great value in having a lean common path aka 90% of use cases that need no extras should go the fastest route potentially at the _expense_ of *less frequent cases*. Simplified - the earlier you can elide extra work the better performance you get. To do that you may need to do double the overhead (checks) in less frequent case to remove some of it in the common case. Yes, I understand the checking for "mode" wasn't the best approach. The internals are mostly coded to be straight forward and just work. See below. I was talking namely about calling functions to see that no events are fired anyway. I can probably add a static-if before calling the functions. Yeah, I see, but it's still a call to delegate that's hard to inline (well LDC/GDC might). Would it be hard to do a compile-time check if there are any events with the type in question at all and then call triggerEvent(s)? No, I don't think so. I can also make the triggerEvents take the delegate by alias parameter, if that helps. Or inline it manually. While we are on the subject of delegates - you absolutely should use 'scope delegate' as most (all?) delegates are never stored anywhere but rather pass blocks of code to call deeper down the line. (I guess it's somewhat Ruby-style, but it's not a problem). Good idea. The reasons for the delegates is to avoid begin/end functions. This also forces the use of the API correctly. Hmm, actually it may not. Since the Serializer technically is the user of the archiver API and that is already correctly implemented. The developer do need to implement the archiver API correctly, but there's nothing that stops him/her from _not_ calling the delegate. Am I over thinking this? Aye, as any faithful Phobos dev absolutely :) Seriously though ATM I just _suspect_ there is no need for Archive to be an interface. I would need to think this bit through more deeply but virtual call per field alone make me nervous here. Originally it was using templates. One of my design goals back then was to not have to use templates. Templates forces slightly more complicated API for the user: auto serializer = new Serializer!(XmlArchive); Which is fine, but I'm not very about the API for custom serialization: class Foo { void toData (Archive) (Serializer!(Archive) serializer); } The user is either forced to use templates here as well, or: class Foo { void toData (Serializer!(XmlArchive) serializer); } ... use a single type of archive. It's also possible to pass in anything as Archive. Now we have template constraints, which didn't exist back then, make it a bit better. About the large API to implement for an Archive, this is the criteria I had when creating the API, in order of importance. 1. Should be easy for a consumer to use 2. Should be easy for an archive implementor 3. Should be easy to implement the serializer In this case, point 1 made it less easy for point 2. Point 2 made me push as much as possible to the serializer instead of
Re: Best practices
On 2013-08-27 23:29, H. S. Teoh wrote: It is surprisingly pleasant to read, and very much how regular D code should look like (except for a few dark corners that, hopefully, will be cleaned up eventually). The fact that there are modules with 35+k lines of code, I would say that's a dark room rather than a corner :) -- /Jacob Carlborg
Re: param2 = param1
On 2013-08-27 23:51, Andrej Mitrovic wrote: Personally I think a much more useful feature would be (and this doesn't block this feature but it's related to default arguments): struct S { void foo(int x = this.y) { } int y; } I agree, I've wanted this a couple of times. -- /Jacob Carlborg
Re: param2 = param1
On 2013-08-27 21:56, Walter Bright wrote: No reason. It simply never occurred to anyone. I've never heard of anyone wanting this in all my years of C, C++, and D. void foo (ubyte[] source, ubyte[] destination = source); Do some operation, by default override "source": void scale (int width, int height = width); I'd reject an enhancement request for this unless someone could demonstrate significant utility for it. So consistency is not a good argument? -- /Jacob Carlborg
Re: [dox] enum specs vs reality
On 2013-08-28 04:27, Andre Artus wrote: 2. The example from p.69 [TDPL]. It seems to be missing a colon after "enum". enum size_t g_maxDataSize = 100_000_000, g_maxMemory = 1_000_000_000; I hope someone can clear up what is and isn't a valid enum. I haven't looked at this in TPL but the above is a manifest constant. Which basically has nothing to do with enums. It's a way to declare a constant that doesn't have any storage and which address cannot be taken. Basically the same as "#define foo 0" in C. -- /Jacob Carlborg
Re: [dox] enum specs vs reality
On 2013-08-28 01:53, captaindet wrote: i admit that i am not very good at reading/understanding language definition syntax. but yet i think the given enum specs ( http://dlang.org/enum.html ) are not quite in order. they seem to imply that both enum ; enum WhatAmI ; That doesn't look entirely correct. Currently the docs read: EnumDeclaration: enum EnumBody Should probably be: EnumDeclaration: enum EnumMembersBody: are correct. while the first one throws an error as expected, the second one passes and is partially usable, potentially similar to C's #define OPTION. however, typedef's throwing of an error makes me doubt that this is legal: import std.stdio, std.traits; enum test;// passes but is it really legal? int main(string[] args) { writeln( __traits(compiles, test) );// true writeln( is( test == enum ) );// true writeln( isBasicType!(test) );// true writeln( isSomeFunction!(test) );// false // writeln( typeof(test).stringof );// Error: argument test to typeof is not an expression return 0; } The last one will fail since "typeof" expects an expression and not a type. -- /Jacob Carlborg
Re: Range interface for std.serialization
On 2013-08-27 22:12, Dmitry Olshansky wrote: Feel free to nag me on the NG and personally for any deficiency you come across on the way there ;) About making Serializer a struct. Actually I think the semantics of Serializer should be a reference type. I see no use case in passing a Serializer by value. Although I do see the overhead of allocating a class and calling methods on it. I do plan to add a free function for deserializing, for convenience. In that function Serializer, if it's a class, would be allocated using emplace to make it stack allocated. -- /Jacob Carlborg
Re: Range interface for std.serialization
28-Aug-2013 11:13, Jacob Carlborg пишет: On 2013-08-27 22:12, Dmitry Olshansky wrote: I see... That depends on the format and for these that have no keys or markers of any kind versioning might help here. For instance JSON/BSON could handle permutation of fields, but I then it falls short of handling links e.g. pointers (maybe there is a trick to get it, but I can't think of any right away). For pointers and reference types I currently serializing all fields with an id then when there's a pointer or reference I can just do this: 3 1 That would be tricky in JSON and quite overheadish (e.g. wrapping everything into object just in case there is a pointer there). I suspect it would be best to somehow see archives by capbilities: 1. Rigid (most binary) - in-order, depends on the order of fields, may need to fit a scheme (in this cases D types implicitly define one) Rigid archivers may also enjoy (per format in the future) a code generator that given a scheme defines D types with a bit of CTFE+mixin. 2. Flexible - can survive reordering, is scheme-less, data defines structure etc. easer handles versioning e.g. XML is one. Yes, that's a good idea. In the binary archiver I'm working on I'm cheating quite a bit and relax the requirements made by the serializer. Yes, instead of cheating you can just define them as different kinds. It would ease the friction and prevent some "impedance mismatch" problems. This also neatly answers the question about scheme vs scheme-less serialization. Protocol buffers/Thrift may be absorbed into Rigid category if we can get the versioning right. Also solving versioning is the last roadblock (after ranges) mentioned on the path to making this an epic addition to Phobos. Versioning shouldn't be that hard, I think. Then collect some info on how to approach this problem. See e.g. Boost serialziation, Protocol Buffers and Thrift. The key point is that it's many things to many different people. Was it DOM-ish too? Yes. That nails it. DOM isn't quite serialization but rather a hierarchical DB. BTW Sqlite and other DBs may be an interesting backend for serialization (though they wouldn't have lookup untill deserialization). Yeah, I see, but it's still a call to delegate that's hard to inline (well LDC/GDC might). Would it be hard to do a compile-time check if there are any events with the type in question at all and then call triggerEvent(s)? No, I don't think so. I can also make the triggerEvents take the delegate by alias parameter, if that helps. Or inline it manually. Great, anything to lessen the extra load. While we are on the subject of delegates - you absolutely should use 'scope delegate' as most (all?) delegates are never stored anywhere but rather pass blocks of code to call deeper down the line. (I guess it's somewhat Ruby-style, but it's not a problem). Good idea. The reasons for the delegates is to avoid begin/end functions. This also forces the use of the API correctly. Hmm, actually it may not. Since the Serializer technically is the user of the archiver API and that is already correctly implemented. The developer do need to implement the archiver API correctly, but there's nothing that stops him/her from _not_ calling the delegate. Am I over thinking this? Seems like, after all library implementors should be trusted to not do truly awful things. Aye, as any faithful Phobos dev absolutely :) Seriously though ATM I just _suspect_ there is no need for Archive to be an interface. I would need to think this bit through more deeply but virtual call per field alone make me nervous here. Originally it was using templates. One of my design goals back then was to not have to use templates. Templates forces slightly more complicated API for the user: auto serializer = new Serializer!(XmlArchive); Which is fine, but I'm not very about the API for custom serialization: class Foo { void toData (Archive) (Serializer!(Archive) serializer); } Rather this: void toData(Serializer)(Serializer serializer) if(isSerializer!Serializer) { ... } There is no need to even know how archiver looks like for the user code (wasn't it one of the goals of archivers?). The user is either forced to use templates here as well, or: class Foo { void toData (Serializer!(XmlArchive) serializer); } The main problem would be that it can't overriden as templates are final. After all of this I think Archivers are just fine as templates user only ever interacts with them during creation. Then it's serializers templates that pick up the right types. Serializers themselves on the other hand are present in user code and may need one common polymorphic abstract class that provides 'put' and forwards it to a set of abstract methods. All polymorphic wrappers would inherit from it. This won't prevent folks from using templated version of toData/fromData if need be. ... use a single type of archive. It's also possible to
Re: Range interface for std.serialization
28-Aug-2013 12:08, Jacob Carlborg пишет: On 2013-08-27 22:12, Dmitry Olshansky wrote: Feel free to nag me on the NG and personally for any deficiency you come across on the way there ;) About making Serializer a struct. Actually I think the semantics of Serializer should be a reference type. I see no use case in passing a Serializer by value. Although I do see the overhead of allocating a class and calling methods on it. Here you are quite right... just add a factory that hides away its true origin (and ctor as well so it can be changed later if need be) we.g.: auto serializer = serializerFor!(XmlArchiver)(archiver); I do plan to add a free function for deserializing, for convenience. In that function Serializer, if it's a class, would be allocated using emplace to make it stack allocated. Good idea. API should have many layers so that power users may keep digging to the bottom and these that just need to get the job done can do it in one stroke. -- Dmitry Olshansky
Re: Range interface for std.serialization
28-Aug-2013 13:58, Dmitry Olshansky пишет: 28-Aug-2013 11:13, Jacob Carlborg пишет: On 2013-08-27 22:12, Dmitry Olshansky wrote: Rather this: void toData(Serializer)(Serializer serializer) if(isSerializer!Serializer) { ... } There is no need to even know how archiver looks like for the user code (wasn't it one of the goals of archivers?). The user is either forced to use templates here as well, or: class Foo { void toData (Serializer!(XmlArchive) serializer); } The main problem would be that it can't overriden as templates are final. After all of this I think Archivers are just fine as templates user only ever interacts with them during creation. Then it's serializers templates that pick up the right types. Serializers themselves on the other hand are present in user code and may need one common polymorphic abstract class that provides 'put' and forwards it to a set of abstract methods. All polymorphic wrappers would inherit from it. Taking into account that you've settled on keeping Serializers as classes just finalize all methods of a concrete serializer that is templated on archiver (and make it a final class). Should be as simple as: class Serializer { void put(T)(T item){ ...} //other methods per specific type } final class ConcreteSerializer(Archiver) : Serializer { final: ... //use Archiver here to implement these hooks } Then users that use templates in their code would have concrete types, for others it quickly "decays" to the base class they use. The boilerplate of defining a lot of methods now moves to Serializer but there should be only one such (template) class anyway. -- Dmitry Olshansky
Re: Prevention of UFCS hijacking
On 8/27/13, Maxim Fomin wrote: > What should I tell except you are surprising of current state of > things? I'm just raising awareness of the issue. And it's surprising when you're coding and not expecting it. Imagine adding an import to a 3rd party library and no longer getting errors at compile time when you assign to a field that doesn't exist. Anyone could be caught off-guard by this.
Re: Prevention of UFCS hijacking
On Wed, Aug 28, 2013 at 08:41:39AM +0200, Jacob Carlborg wrote: > On 2013-08-27 20:40, Maxim Fomin wrote: > > >Let's start from basics: > > > >writeln = 42; > > > >and this is also by design. > > I see no reasons for why this should be allowed. I say: > > * Getters marked with @property: call without parentheses > * Getters not marked with @property: call with or without parentheses > * Setters marked with @property: require assignment syntax > * Setters not marked with @property: disallow assignment syntax [...] +1, I agree with all of the above. T -- Старый друг лучше новых двух.
Re: Best practices
On Wed, Aug 28, 2013 at 09:19:24AM +0200, Jacob Carlborg wrote: > On 2013-08-27 23:29, H. S. Teoh wrote: > > >It is surprisingly pleasant to read, and very much how regular D code > >should look like (except for a few dark corners that, hopefully, will > >be cleaned up eventually). > > The fact that there are modules with 35+k lines of code, I would say > that's a dark room rather than a corner :) [...] lol... well, then, let's get cracking on that pull request to split up std.algorithm. :) std.datetime is another dark room, but Jonathan is working on that already. T -- What do you get if you drop a piano down a mineshaft? A flat minor.
Re: [dox] enum specs vs reality
On 2013-08-28 02:21, Jacob Carlborg wrote: On 2013-08-28 04:27, Andre Artus wrote: 2. The example from p.69 [TDPL]. It seems to be missing a colon after "enum". enum size_t g_maxDataSize = 100_000_000, g_maxMemory = 1_000_000_000; I hope someone can clear up what is and isn't a valid enum. I haven't looked at this in TPL but the above is a manifest constant. Which basically has nothing to do with enums. It's a way to declare a constant that doesn't have any storage and which address cannot be taken. Basically the same as "#define foo 0" in C. don't know what you mean. since they are defined with the enum keyword they have everything to do with enum, especially the official syntax presented here: http://dlang.org/enum.html enum keyword covers both, enumeration constants and manifest constants. the specs cover both in one. moreover, they explain that manifest constants are only syntactic sugar for anonymous enums: enum { A = 2, B = 4 } is the same as enum A = 2; enum B = 4;
Re: [dox] enum specs vs reality
On 2013-08-28 02:26, Jacob Carlborg wrote: That doesn't look entirely correct. Currently the docs read: EnumDeclaration: enum EnumBody Should probably be: EnumDeclaration: enum EnumMembersBody: agreed. The last one will fail since "typeof" expects an expression and not a type. a) so are you saying enum WhatAmI; is legal? (just asking because i don't know) b) what typeof expects/tolerates seems to be a bit of a minefield by itself. enum test = true; writeln( typeof(test).stringof ); //prints: bool enum wtf; writeln( typeof(wtf).stringof );//Error: argument wtf to typeof is not an expression /det
Re: std.serialization: pre-voting review / discussion
On Friday, 23 August 2013 at 13:39:47 UTC, Dicebot wrote: On Friday, 23 August 2013 at 13:34:04 UTC, ilya-stromberg wrote: It's a serious issue. May be it's more important than range support. For example, I have to change class (bug fixing, new features, etc.), but it comparable with previos version (example: it's always possible to convert "int" to "long"). I that case I can't use std.serialization and have to write own solution (for examle, save data in csv file). I don't think it as an issue at all. Behavior you want can't be defined in a generic way, at least not without lot of UDA help or similar declarative approach. In other words, the fact that those two classes are interchangeable in the context of the serialization exists only in the mind of programmer, not in D type system. More than that, such behavior goes seriously out of the line of D being strongly typed language. I think functionality you want does belong to a more specialized module, not generic std.serialization - maybe even format-specific. Maybe you are right. But I think it's not so difficult to implement, at least for simle cases. We can follow a simple rules, for example like this: Does element "b" exists in the archive? - Yes. Does element "b" has type "long"? - No, the type is "int". Can we convert type "int" to "long"? - Yes, load element "b" to tempory variable and convert it to "long": int _b = 4; long b = to!long(_b); Is it difficult to implement? Also, we can provide a few deserialize models: strict (like current behavior) and smart (like example above). May be even 3 levels: strict, implicit conversions (like int to long) and explicit conversions (like long to int).
Re: std.serialization: pre-voting review / discussion
On Wednesday, 28 August 2013 at 16:02:09 UTC, ilya-stromberg wrote: ... There was a good proposal by Dmitry to separate sequential strict serialization for random-access one as two distinct entities. I like it and I think it that is also can solve your problem.
Re: std.serialization: pre-voting review / discussion
On Wednesday, 28 August 2013 at 16:10:03 UTC, Dicebot wrote: There was a good proposal by Dmitry to separate sequential strict serialization for random-access one as two distinct entities. I like it and I think it that is also can solve your problem. The problem is not only my. Actually, I didn't use C# serialization due this problem - any minimal code change breaks all previously serialized data. But I used .Net 1, maybe in current version solve this. Can you print the link, please?
Re: std.getopt error
On Mon, Aug 26, 2013 at 09:20:09AM +0200, Ramon wrote: > On Monday, 26 August 2013 at 07:06:07 UTC, growler wrote: > >Given: > > > >int colOrder = 1; > >... > >Could it be that "-c 1" is ignored because it is in invalid and > >the default colOrder value is used? > > Sorry for expressing myself clumsily. > > if the commandline arg is "-c 1" (which according to getopt doc is > illegal) it actually *does* work properly. > > if the commandline arg is "-c1" (which according to getopt doc is > legal) then the result of getopt is false/wrong. > "-c 1" then sets the variable to -1. > > Same with 2. So the problem is not 1 or 1 being the var default. [...] I'd say file a bug for this, since the docs claim that -c1 works, but actually it doesn't. T -- It only takes one twig to burn down a forest.
Re: std.serialization: pre-voting review / discussion
On Wednesday, 28 August 2013 at 16:19:20 UTC, ilya-stromberg wrote: Can you print the link, please? http://forum.dlang.org/post/kvj17t$1ash$1...@digitalmars.com (Rigid vs Flexible part)
Re: New Lagged Fib. PRNG gen and random2.d
On 27/08/13 20:41, monarch_dodra wrote: The BAD news though, is that it would appear the floating point generation on linux is *bad*. As in, so bad, it's faster to just generate integrals and divide. Arguably, I think the "native" double generation might be of slightly higher quality, but I don't think it is worth the cost. "Bad" is a relative term. It might be slower, but you might (I don't know) be getting something that has better statistical quality. So, what you might prefer to use depends on your use-case.
Re: param2 = param1
On Tuesday, 27 August 2013 at 21:51:48 UTC, Andrej Mitrovic wrote: On 8/27/13, "@puremagic.com <"\"Luís".Marques"> wrote: // Not OK int foo(int x, int y = x) { return x*y; } Personally I think a much more useful feature would be (and this doesn't block this feature but it's related to default arguments): struct S { void foo(int x = this.y) { } int y; } I used to do something similar to that in another language. Something like... void toggle(bool newState = !this.state) { this.state = newState; } A function that could set state to a given value, or toggle it if omitted. Then again, that language didn't have overloading at all. Another example, but with more complex processing. void speak(string msg, bool bypassMute = this.channel.isAdmin(this.username)) { ... }
Re: [dox] enum specs vs reality
On Tuesday, 27 August 2013 at 23:52:59 UTC, captaindet wrote: enum WhatAmI ; I suppose this is legal for the same reasons as class A; or struct S; is legal - forward declaration (although in case of enums it is pretty useless).
Re: New Lagged Fib. PRNG gen and random2.d
On 25/08/13 18:58, Joseph Rushton Wakeling wrote: (2) Should we provide a generic payload wrapper, or require RNG creators to implement everything manually? I strongly support a generic wrapper, as there is too great a risk of implementation error if we require the wrapping-of-a-reference to be done manually each time. A few issues I ran into when trying to create such a wrapper: * Function properties are not necessarily (easily) consistent between different RNGs. For example, it makes sense that popFront() should be @safe pure nothrow, but in the Linear Congruential generator there are casts which mean that it can't be @safe. Now, we _could_ go with the lowest common denominator, but that's not a very nice state of affairs. Is there any way for a wrapper to effectively inherit the properties of the functions it's wrapping? * @disable this() doesn't seem appropriate for all RNGs, e.g. Xorshift. In fact, for _all_ RNGs you probably want to have a default initialization. So, in this case, classes rather than structs start to look appealing.
Re: A Class in Composition
On Tue, Aug 27, 2013 at 04:13:24PM +0200, Chris wrote: > I had a very simple method that would read a text file, parse it and > create a lexicon of the type string[string]. > > public void loadLexicon(ref string[string] lex, string src) > > It was high time I made the method more sophisticated and flexible > (allowing for comments in the source file, checking for formatting > errors etc). Because neither the comment bit (C-style line comments > "//") nor the formatting check are too demanding I decided to do it > in the existing loop that looked something like: > > while (file.readln(buf)) { > line = to!string(buf); > // Do something with line > } > > Soon, very soon indeed, I ran into all the problems associated with > loops, which basically boils down to "Where the f.. am I now?". Yep, this is a typical structure conflict caused by the mismatch between the lines in a file and the structures they represent. :) > So I said to myself that component programming was the perfect fit for > this kind of problem. I rearranged the program and now I have one line > in the function that does the job: > > public void loadLexicon(ref string[string] lex, string src) { > // ... > // arr is of type string[] and holds the lines of the source file. > auto dictionary = Lexicon(); // The output range > lex = arr.byCommentFilter().byEntry().copy(dictionary).lexicon; > } > > It's very nice indeed. The beauty of it is not only that I now have > a nice, sequentially ordered "one-liner", the outsourcing of checks > and filters freed my head from the loop logic, which helped me to > focus on the respective algorithms. This lead to a leaner and > cleaner implementation of each algorithm, because there are no > dependecies on loop conditions or the position in the loop. I usually separate out the loop body into smaller functions that handle each part of the parsing. Since code is the most straightforward when its structure matches that of the data, this usually means the outer loop no longer iterates over lines, but over larger, logical structures (e.g., an entry in your lexicon). That way, your code becomes something like: void loadLexicon(...) { auto dictionary = Lexicon(); do { dictionary.put(parseEntry(input, ...)); } while (!input.empty); } Entry parseEntry(...) { skipDelimitingBlankLines(...); auto key = parseHeadword(...); auto value = parseBody(...); return Entry(key, value); } Key parseHeadword(...) { ... } Value parseBody(...) { ... } This way, your code structure has 1-to-1 correspondence with the format of your input, which makes it far more readable and less bug-prone. Of course, we can then take this to the next level, which is to encapsulate each of these functions into a range-based component, and so we end up with your nice one-line function. :) > I could easily remove the comment filter, if the deployment version > of the program ships with tidied up source files, or I could add a > new component if necessary. In a loop, however trivial it may appear > at first glance, it would not be so simple to add or remove parts of > the logic. Yeah, when loops get beyond the simplest incarnations, their complexity quickly explodes into something unmanageable, usually resulting in tight coupling between distant parts of the code. That makes it very hard (or outright impossible) to add/remove parts. > One drawback is, that using ranges creates some overheads and code > duplication. But the neatness of it is amazing, and I daresay that a > lot of bugs are hidden in loops simply because the loop logic > distracts and confuses the programmer and bugs finally find > loopholes they can slip through. Overly complex loops make a programmer go loopy and bugs crawl out from loopholes... ;-) As for overheads, I wonder if, given enough experience over time, we can one day identify common patterns that the compiler can take advantage of and optimize into more efficient code. For example, if the compiler recognizes a linear composition of range-based components, it could transform them into optimized nested loops that eliminate some of the overhead involved. I'm not sure how feasible this is with the current DMD implementation, though. But it's certainly something to keep in mind for the future. > Another drawback is that ranges demand a lot of boilerplate code. If > properly implemented, there is a lot of code you have to write over > and over again such as > > if (isInputRange!Range && isInputRange!(ElementType!Range) && > is(ElementType!(ElementType!Range) == MyType)) > > I don't know if this could possibly be reduced. Or maybe it's just > my lack of experience. You can encapsulate this into a template: template isRoR(R, ElemType) { enum isRoRMyType = isInputRange!R &&
Re: Range interface for std.serialization
On 2013-08-28 11:58, Dmitry Olshansky wrote: That would be tricky in JSON and quite overheadish (e.g. wrapping everything into object just in case there is a pointer there). Yes. Yes, instead of cheating you can just define them as different kinds. It would ease the friction and prevent some "impedance mismatch" problems. Yes, that's better. Then collect some info on how to approach this problem. See e.g. Boost serialziation, Protocol Buffers and Thrift. The key point is that it's many things to many different people. I'll do that. Rather this: void toData(Serializer)(Serializer serializer) if(isSerializer!Serializer) { ... } There is no need to even know how archiver looks like for the user code (wasn't it one of the goals of archivers?). Right, didn't think of using a template argument for the whole serializer. Serializers themselves on the other hand are present in user code and may need one common polymorphic abstract class that provides 'put' and forwards it to a set of abstract methods. All polymorphic wrappers would inherit from it. This won't prevent folks from using templated version of toData/fromData if need be. That's a good idea. I'd suggest to maximally hide away (Un)Archivers API from end users and as such it would be more convenient to just stay templated as it won't be seen. Yes. -- /Jacob Carlborg
Re: Range interface for std.serialization
On 2013-08-28 13:20, Dmitry Olshansky wrote: Taking into account that you've settled on keeping Serializers as classes Not necessary. just finalize all methods of a concrete serializer that is templated on archiver (and make it a final class). Should be as simple as: class Serializer { void put(T)(T item){ ...} //other methods per specific type } final class ConcreteSerializer(Archiver) : Serializer { final: ... //use Archiver here to implement these hooks } Then users that use templates in their code would have concrete types, for others it quickly "decays" to the base class they use. The boilerplate of defining a lot of methods now moves to Serializer but there should be only one such (template) class anyway. This is a good idea. -- /Jacob Carlborg
Re: std.serialization: pre-voting review / discussion
On 2013-08-28 18:02, ilya-stromberg wrote: Maybe you are right. But I think it's not so difficult to implement, at least for simle cases. We can follow a simple rules, for example like this: Does element "b" exists in the archive? - Yes. Does element "b" has type "long"? - No, the type is "int". Can we convert type "int" to "long"? - Yes, load element "b" to tempory variable and convert it to "long": int _b = 4; long b = to!long(_b); Is it difficult to implement? Also, we can provide a few deserialize models: strict (like current behavior) and smart (like example above). May be even 3 levels: strict, implicit conversions (like int to long) and explicit conversions (like long to int). I don't think we should add too much of this kind of functionality. There's a reason for why it supports custom serialization. This is a perfect example. -- /Jacob Carlborg
Re: [dox] enum specs vs reality
On 2013-08-28 19:31, Maxim Fomin wrote: I suppose this is legal for the same reasons as class A; or struct S; is legal - forward declaration (although in case of enums it is pretty useless). It's useful for UDA's: enum foo; @foo bar (); -- /Jacob Carlborg
Re: [dox] enum specs vs reality
On 2013-08-28 17:34, captaindet wrote: The last one will fail since "typeof" expects an expression and not a type. a) so are you saying enum WhatAmI; is legal? (just asking because i don't know) Yes, it's sometimes usable to be able to declare dummy types like this. Especially now when we have UAD's (User Defined Attribute): enum foo; @foo bar (); b) what typeof expects/tolerates seems to be a bit of a minefield by itself. enum test = true; writeln( typeof(test).stringof );//prints: bool enum wtf; writeln( typeof(wtf).stringof );//Error: argument wtf to typeof is not an expression That seems strange. Perhaps worth a bugzilla report: http://d.puremagic.com/issues/ -- /Jacob Carlborg
Re: New Lagged Fib. PRNG gen and random2.d
On Wednesday, 28 August 2013 at 17:57:13 UTC, Joseph Rushton Wakeling wrote: On 25/08/13 18:58, Joseph Rushton Wakeling wrote: (2) Should we provide a generic payload wrapper, or require RNG creators to implement everything manually? I strongly support a generic wrapper, as there is too great a risk of implementation error if we require the wrapping-of-a-reference to be done manually each time. A few issues I ran into when trying to create such a wrapper: * Function properties are not necessarily (easily) consistent between different RNGs. For example, it makes sense that popFront() should be @safe pure nothrow, but in the Linear Congruential generator there are casts which mean that it can't be @safe. Now, we _could_ go with the lowest common denominator, but that's not a very nice state of affairs. Is there any way for a wrapper to effectively inherit the properties of the functions it's wrapping? * @disable this() doesn't seem appropriate for all RNGs, e.g. Xorshift. In fact, for _all_ RNGs you probably want to have a default initialization. So, in this case, classes rather than structs start to look appealing. I agree that classes over structs is appealing, but I still think that having "semi-Public payload implementations" is important. There are a lot of devs out there that don't use the GC, in particular video games. It would be nice for them to not have to re-write the wheel. With that said, even with classes, we'd need an easy way to create the classes from the payloads.
Re: [dox] enum specs vs reality
On 8/28/13, Jacob Carlborg wrote: > Yes, it's sometimes usable to be able to declare dummy types like this. > Especially now when we have UAD's (User Defined Attribute): > > enum foo; > > @foo bar (); Good tip, I used to use structs for this but I wanted something non-instantiable.
Re: [dox] enum specs vs reality
On Wed, Aug 28, 2013 at 09:12:44PM +0200, Andrej Mitrovic wrote: > On 8/28/13, Jacob Carlborg wrote: > > Yes, it's sometimes usable to be able to declare dummy types like > > this. Especially now when we have UAD's (User Defined Attribute): > > > > enum foo; > > > > @foo bar (); > > Good tip, I used to use structs for this but I wanted something > non-instantiable. Good idea! I also don't like using structs everywhere just for UDA's. T -- MSDOS = MicroSoft's Denial Of Service
New linker error with xml2
I have been seeing a new linker error while building xml2. OPTLINK (R) for Win32 Release 8.00.12 Copyright (C) Digital Mars 1989-2010 All rights reserved. http://www.digitalmars.com/ctg/optlink.html sxmltest.obj(sxmltest) Error 42: Symbol Undefined _D3alt7zstring22__T9KeyValRecTAyaTAyaZ9KeyValRec 8opEqualsMxFKxS3alt7zstring22__T9KeyValRecTAyaTAyaZ9KeyValRecZb (demangled for your convenience) const(bool function(ref const(alt.zstring.KeyValRec!(immutable(char)[], immutable(char)[]).KeyValRec))) alt.zstring.KeyValRec!(immutable(char)[], immutable(char)[]).KeyValRec.opEquals The error starts with commit: commit 751353c8217596726ab219b7d3a690e8950e409e Author: k-hara Date: Sat Aug 24 15:07:18 2013 +0900 To compile xml2, I have made the following changes: change struct Array member toConstArray from @safe to @trusted because pointers cannot be transformed into arrays in safe code. changed several occurences of 'delete this;' to 'this.destroy();' changed auto doc = new Document(TagData("catalog"); to auto td = TagData("catalog"); auto doc = new Document(td); because of an lvalue problem. (should td be allocated on heap instead?) changed some readln to return to a string instead of passing a string. I am using Win32 with Walter's snn.lib with HeapAlloc calls and obviously git head for dmd etal. Anyone have any ideas why dmd would generate that template function for test\sxml.d after that commit but not before?
Re: New linker error with xml2
If anyone is interested, here is the patch I use to compile xml2: diff --git a/alt/zstring.d b/alt/zstring.d index 356cfda..e021cca 100644 --- a/alt/zstring.d +++ b/alt/zstring.d @@ -674,7 +674,7 @@ struct Array(T) } /// Return unwriteable slice of the buffer. -const(T[]) toConstArray() const @safe @property nothrow +const(T[]) toConstArray() const @trusted @property nothrow { if (ptr_ !is null) return ptr_[0..length_]; @@ -1350,7 +1350,8 @@ struct PackedArray(T) /// Element of sortable array of pairs on key struct KeyValRec(K,V) { - alias KeyValRec!(K,V) SameType; +// alias KeyValRec!(K,V) SameType; +alias SameType = KeyValRec!(K,V); K id; V value; @@ -1723,4 +1724,4 @@ unittest put(cd["standalone"]); put(cd["encoding"]); -} \ No newline at end of file +} diff --git a/build.bat b/build.bat index 4be9aaf..052d670 100644 --- a/build.bat +++ b/build.bat @@ -1,7 +1,7 @@ rem Delete all outputs del xmlp.lib sxmltest.exe bookstest.exe conformance.exe 2>NUL -dmd -property -lib -ofxmlp.lib -O -noboundscheck -release -w ^ +dmd -lib -ofxmlp.lib -O -noboundscheck -release -w ^ "alt/zstring.d" "std/xml1.d" "std/xml2.d" ^ "std/xmlp/arraydom.d" "std/xmlp/arraydombuild.d" "std/xmlp/builder.d" ^ "std/xmlp/domparse.d" "std/xmlp/dtdtype.d" ^ @@ -17,15 +17,15 @@ dmd -property -lib -ofxmlp.lib -O -noboundscheck -release -w ^ IF ERRORLEVEL 1 exit /B -dmd -property -ofsxmltest -O -noboundscheck -release "./test/sxml" xmlp.lib +dmd -ofsxmltest -O -noboundscheck -release "./test/sxml" xmlp.lib IF ERRORLEVEL 1 exit /B -dmd -property -ofbookstest -O -noboundscheck -release "./test/books" xmlp.lib +dmd -ofbookstest -O -noboundscheck -release "./test/books" xmlp.lib IF ERRORLEVEL 1 exit /B -dmd -property -ofconformance -O -noboundscheck -release ^ +dmd -ofconformance -O -noboundscheck -release ^ "./test/conformance.d" std/xmlp/jisx0208.d xmlp.lib IF ERRORLEVEL 1 exit /B diff --git a/std/xml1.d b/std/xml1.d index 941c373..3799474 100644 --- a/std/xml1.d +++ b/std/xml1.d @@ -905,7 +905,7 @@ class Tag if (tag_.attr.length > 0) tag_.attr.explode(del); if (del) - delete this; + this.destroy(); } } @@ -1398,7 +1398,7 @@ abstract class Item void explode(bool del) { if (del) - delete this; + this.destroy(); } } @@ -1663,7 +1663,7 @@ public: init(); if (del) - delete this; + this.destroy(); } /** @@ -2130,4 +2130,4 @@ void UnitTest1() unittest { UnitTest1(); -} \ No newline at end of file +} diff --git a/std/xmlp/arraydom.d b/std/xmlp/arraydom.d index 0b7a34c..75e23da 100644 --- a/std/xmlp/arraydom.d +++ b/std/xmlp/arraydom.d @@ -62,7 +62,7 @@ abstract class Item void explode(bool del) { if (del) - delete this; + this.destroy(); } /// This item as text diff --git a/std/xmlp/builder.d b/std/xmlp/builder.d index 98cc176..3274d63 100644 --- a/std/xmlp/builder.d +++ b/std/xmlp/builder.d @@ -69,7 +69,7 @@ abstract class Builder { void explode(bool del) { if (del) - delete this; + this.destroy(); } } diff --git a/std/xmlp/coreprint.d b/std/xmlp/coreprint.d index 1a81011..6cf191a 100644 --- a/std/xmlp/coreprint.d +++ b/std/xmlp/coreprint.d @@ -204,7 +204,7 @@ struct XmlPrinter uintptr_t i = indent; buf[i++] = '<'; buf[i++] = '/'; -buf[i .. i + taglen] = tag; +buf[i .. i + taglen] = tag[]; i += taglen; buf[i] = '>'; } @@ -384,7 +384,7 @@ struct XmlPrinter uintptr_t i = indent; if(i > 0) buf[0..i] = ' '; -buf[i .. $] = s; +buf[i .. $] = s[]; options.putDg(buf); } } diff --git a/std/xmlp/linkdom.d b/std/xmlp/linkdom.d index 582fb9b..678c2a7 100644 --- a/std/xmlp/linkdom.d +++ b/std/xmlp/linkdom.d @@ -1319,7 +1319,7 @@ public: void explode(bool del) { if (del) - delete this; + this.destroy(); } /// Not supported diff --git a/test/Conformance.d b/test/Conformance.d index 68dd9a6..ab7518b 100644 --- a/test/Conformance.d +++ b/test/Conformance.d @@ -755,7 +755,7 @@ int main(string[] args) } } string dinp; -stdin.readln(dinp); +dinp = stdin.readln(); return 0; } diff --git a/test/books.d b/test/books.d index 6c14403..7c6bd71 100644 --- a/test/books.d +++ b/test/books.d @@ -182,7 +182,8 @@ void std_xml1(string s) Book[] books; auto
Re: param2 = param1
On 8/28/2013 12:16 AM, Jacob Carlborg wrote: On 2013-08-27 21:56, Walter Bright wrote: No reason. It simply never occurred to anyone. I've never heard of anyone wanting this in all my years of C, C++, and D. void foo (ubyte[] source, ubyte[] destination = source); Do some operation, by default override "source": void scale (int width, int height = width); Is this really a problem that needs solving? I'd reject an enhancement request for this unless someone could demonstrate significant utility for it. So consistency is not a good argument? Is it really consistent if you have to add a new section in the documentation explaining it?
Building 2.063.2 from source produces non-working toolchain??
While trying to track down a 2.063.2 problem someone posted to the D.learn forum, I tried to build dmd/druntime/phobos 2.063.2 from source, and to my chagrin, discovered that the resulting toolchain is non-functional. Even the simplest program: void main() {} doesn't compile: /mnt/1/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o: In function `_start': (.text+0x20): undefined reference to `main' test.o: In function `no symbol': test.d:(.text+0x6): undefined reference to `_Dmodule_ref' collect2: error: ld returned 1 exit status --- errorlevel 1 Attempting to run Phobos unittests also aborts with undefined references to `_Dmodule_ref'. Am I doing something wrong?? How did 2.063.2 even build in the first place? P.S. I'm on Linux 64-bit, in case that matters. (Also, I don't have 32-bit development libraries installed -- could that be a problem?) T -- May you live all the days of your life. -- Jonathan Swift
bug in typeof or wrong enum specs?
a recent discussion ( http://forum.dlang.org/thread/kvje4r$1tff$1...@digitalmars.com ) about the official enum dox ( http://dlang.org/enum.html ) was not conclusive whether enum IDENTIFIER; is officially allowed/supported. jacob pointed out that it has an important use case in that it can serve as UDA. as UDAs are fairly new, this cannot be the reason why this syntax was allowed in the first place though, *if* it is allowed. also, it might be used in meta stuff similar to "#define IDENTIFIER" in C - playing with this idea i run into this issue... while much code behaves with such an empty enum declaration, writeln( __traits(compiles, IDENTIFIER) ); // true writeln( is( IDENTIFIER == enum ) );// true typeof() is not happy at all (DMD 2.063.2): writeln( typeof(IDENTIFIER).stringof ); // Error: argument IDENTIFIER to typeof is not an expression typeof() expects an expression and a bare identifier is a "PrimaryExpression" ( http://dlang.org/expression.html#PrimaryExpression ) and hence a valid argument. either the empty enum declaration is not allowed (and should be removed from the dox and throw a compilation error) or there is a bug in typeof(). /det
Re: bug in typeof or wrong enum specs?
On Wednesday, 28 August 2013 at 23:28:14 UTC, captaindet wrote: a recent discussion ( http://forum.dlang.org/thread/kvje4r$1tff$1...@digitalmars.com ) about the official enum dox ( http://dlang.org/enum.html ) was not conclusive whether enum IDENTIFIER; is officially allowed/supported. jacob pointed out that it has an important use case in that it can serve as UDA. as UDAs are fairly new, this cannot be the reason why this syntax was allowed in the first place though, *if* it is allowed. also, it might be used in meta stuff similar to "#define IDENTIFIER" in C - playing with this idea i run into this issue... while much code behaves with such an empty enum declaration, writeln( __traits(compiles, IDENTIFIER) ); // true writeln( is( IDENTIFIER == enum ) );// true typeof() is not happy at all (DMD 2.063.2): writeln( typeof(IDENTIFIER).stringof ); // Error: argument IDENTIFIER to typeof is not an expression typeof() expects an expression and a bare identifier is a "PrimaryExpression" ( http://dlang.org/expression.html#PrimaryExpression ) and hence a valid argument. either the empty enum declaration is not allowed (and should be removed from the dox and throw a compilation error) or there is a bug in typeof(). /det typeof only accepts expressions, not types. enum symbol acts as a type here as it does not have associated value (typeof(int) will result in same error message)
Re: New Lagged Fib. PRNG gen and random2.d
On Wednesday, 28 August 2013 at 18:43:53 UTC, monarch_dodra wrote: With that said, even with classes, we'd need an easy way to create the classes from the payloads. Don't understand. With classes you don't need payloads. Just converting existing RNG structs to final classes is sufficient.
obsolete D libraries/modules
Apologies if this is the wrong forum or even the wrong place but it seems to me there is a kind of tight connection between dlang and dsource.org (to which the following relates). I can perfectly well understand that any group around a not yet globally known language with a not yet richly endowed assortment of libraries isn't eager to push the kill button on 3rd party/user created modules. And yes, it sure gives a new user a warm nice feeling to discover lots of available modules (which after all translates to a quick start and efficiency for many taskS). Let me, however, also share my experience and feelings as a (exited and pleased) newbie to D when one finds out that what seems to be easily 2/3rd of seemingly available modules are "dead, exitus, this bird is passed away, gone, dead, and only sitting there because someone drove a nail through the poor animal" or, at best optimistically pre-early-alpha (speaking with a friendly grin). Feels like a 16 ton weight coming down (if I may borrow again from Python, here). And there is another unpleasant side effect: It doesn't feel profoundly attractive to write something and put it in between all those dead parrots. I'd like to suggest therefore that we begin to mildly weed out dead or stuck-in-dream stage modules or at least discreetly mark them as RIP. In case someone is interested in what disappointed me most, it's hto2 and bcd-gen, bot of which address an important need and both of which don't look healthy and useful. This is particularly troublesome as "make C libs work in D" type tools are essential in any effort to bring D forward in the world out there. In case someone feels like hitting me: Hold it. This thread was written with good intention and the honest worry that a lack of libs and a lack of some support for bringing in C stuff might turn out to be regrettable bumps in the road. A+ -R
Re: Dynamic array of pointers to opaque structs
On Wednesday, 5 June 2013 at 20:34:17 UTC, Johan F. wrote: I'm fiddling around with SDL2 using Derelict3, and I'm trying to make an array of SDL_Texture pointers, like so: SDL_Texture*[] frames; ... make texture ... frames ~= texture; However, this yields the following error: /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture is forward referenced when looking for 'toHash' /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture is forward referenced when looking for 'opCmp' /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture is forward referenced when looking for 'toString' /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture unknown size /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture no size yet for forward reference /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture unknown size /Users/jaffe1/prog/Derelict3/import/derelict/sdl2/types.d(1865): Error: struct derelict.sdl2.types.SDL_Texture no size yet for forward reference At line 1865 in types.d is the opaque struct declaration struct SDL_Texture; The program compiles and works fine if I change this line to struct SDL_Texture {}; This seems weird to me. Why is making an array of _pointers_ to SDL_Texture dependant on how the SDL_Texture struct is declared? Also, is simply adding {} the right way of fixing it, or will that possibly break something else? For anyone stumbling across this thread in the future, there's a report for this in bugzilla[1]. It's an issue in the compiler with the handling of opaque structs. [1] http://d.puremagic.com/issues/show_bug.cgi?id=10451
Re: New linker error with xml2
2013/8/29 ollie > I have been seeing a new linker error while building xml2. > > OPTLINK (R) for Win32 Release 8.00.12 > Copyright (C) Digital Mars 1989-2010 All rights reserved. > http://www.digitalmars.com/ctg/optlink.html > sxmltest.obj(sxmltest) >Error 42: Symbol Undefined >_D3alt7zstring22__T9KeyValRecTAyaTAyaZ9KeyValRec >8opEqualsMxFKxS3alt7zstring22__T9KeyValRecTAyaTAyaZ9KeyValRecZb > >(demangled for your convenience) >const(bool function(ref const(alt.zstring.KeyValRec!(immutable(char)[], > immutable(char)[]).KeyValRec))) alt.zstring.KeyValRec!(immutable(char)[], > immutable(char)[]).KeyValRec.opEquals > > The error starts with commit: > > commit 751353c8217596726ab219b7d3a690e8950e409e > Author: k-hara > Date: Sat Aug 24 15:07:18 2013 +0900 > Did you rebuild xml2 library after updating/rebuilding dmd code? Because the dmd commit changes the object file places where some instantiated template code are emitted. Kenji Hara
Re: Building 2.063.2 from source produces non-working toolchain??
On Wed, 28 Aug 2013 15:18:47 -0700 "H. S. Teoh" wrote: > > (Also, I don't have > 32-bit development libraries installed -- could that be a problem?) > Possibly, although I don't know what the expected symptoms of that would be. Could you post the exact steps you're using to checkout, build and test the toolchain? Also, are you sure your dmd.conf is right and that the right dmd.conf is being picked up?
Re: Building 2.063.2 from source produces non-working toolchain??
On Thu, 29 Aug 2013 01:27:08 -0400 Nick Sabalausky wrote: > On Wed, 28 Aug 2013 15:18:47 -0700 > "H. S. Teoh" wrote: > > > > (Also, I don't have > > 32-bit development libraries installed -- could that be a problem?) > > > > Possibly, although I don't know what the expected symptoms of that > would be. > > Could you post the exact steps you're using to checkout, build and > test the toolchain? Also, are you sure your dmd.conf is right and > that the right dmd.conf is being picked up? > The following works for me, although my Linux box is a 32-bit VM (stupid consumer-level Intel CPU with no hardware virtualization...). But doing s/32/64/ *should* make it work on a 64-bit: http://pastebin.com/QegPhs8U
Re: obsolete D libraries/modules
On Thursday, 29 August 2013 at 01:13:15 UTC, Ramon wrote: Apologies if this is the wrong forum or even the wrong place but it seems to me there is a kind of tight connection between dlang and dsource.org (to which the following relates). I can perfectly well understand that any group around a not yet globally known language with a not yet richly endowed assortment of libraries isn't eager to push the kill button on 3rd party/user created modules. And yes, it sure gives a new user a warm nice feeling to discover lots of available modules (which after all translates to a quick start and efficiency for many taskS). Let me, however, also share my experience and feelings as a (exited and pleased) newbie to D when one finds out that what seems to be easily 2/3rd of seemingly available modules are "dead, exitus, this bird is passed away, gone, dead, and only sitting there because someone drove a nail through the poor animal" or, at best optimistically pre-early-alpha (speaking with a friendly grin). Feels like a 16 ton weight coming down (if I may borrow again from Python, here). And there is another unpleasant side effect: It doesn't feel profoundly attractive to write something and put it in between all those dead parrots. I'd like to suggest therefore that we begin to mildly weed out dead or stuck-in-dream stage modules or at least discreetly mark them as RIP. In case someone is interested in what disappointed me most, it's hto2 and bcd-gen, bot of which address an important need and both of which don't look healthy and useful. This is particularly troublesome as "make C libs work in D" type tools are essential in any effort to bring D forward in the world out there. In case someone feels like hitting me: Hold it. This thread was written with good intention and the honest worry that a lack of libs and a lack of some support for bringing in C stuff might turn out to be regrettable bumps in the road. A+ -R I agree we do need to deal with older projects. However I don't think we can. Instead maybe we should work towards keeping the wiki up to date with notable projects? With regards to c libraries maybe it would be a good idea to implement a shared library function loader for phobos itself. That would mean both shared libraries and static libraries are very easy to implement. There is e.g. DerelictUtil[0] which provides it if you want it however. With regards to making a converter for between C/D bindings. There is SWIG but I have yet to get that to work well either. Maybe someone else can elaborate more on this side of things. I will say this, one thing about D that has annoyed me from the beginning is the state of the gui libs. Hence why in last month I've been having a real good play around with OpengGL and creating my own library [1]. There is also a few tools missing here and there. For example the conversion of binary assets to D arrays [2]. Works, but not the best. I know I'm advertising some of my own projects here but I think it's relevant to point out my own experience. Another area that does need some work is database connectivity. I did make some bindings to OpenDBX[3]. Which I need to redo as of Derelict3 being split up. I might get that into DUB if somebody wants it. OpenDBX[4] has multiple database interfaces using a common api. We do have sqlite bindings in Phobos however and sqlite itself bundled with dmd (not zip on Windows I believe however). On that note DUB[5] is becoming quite "community official" build manager. These packages _should_ all be up to date however we may need to focus on that? Somebody else should suggest regarding this as I haven't got experience on it yet. This may solve the issue you mentioned with dsource. [0] https://github.com/DerelictOrg/DerelictUtil [1] https://github.com/rikkimax/DOOGLE [2] https://bitbucket.org/alphaglosined/misc-work/src/cf15ec6b1e3cf85128b8ea5c5ce4a07f446f/Tools/Bin2D.d?at=default [3] https://github.com/rikkimax/Derelict3-Extras/tree/master/import/derelict/opendbx [4] http://www.linuxnetworks.de/doc/index.php/OpenDBX/Support [5] http://code.dlang.org/
Re: obsolete D libraries/modules
On 29/08/13 16:11, Rikki Cattermole wrote: I will say this, one thing about D that has annoyed me from the beginning is the state of the gui libs. Hence why in last month I've been having a real good play around with OpengGL and creating my own library [1]. On this topic, I started looking at porting one of my PyGTK applications to GtkD and found that the knowledge of PyGTK API wasn't a great deal of help in this endeavor. I think the problem is Python's "duck typing" and dynamic typing allow for a very flexible API that is much simpler than GTK+'s and GtkD's is much like GTK+'s. The problem is complicated by the fact that the amount of documentation is huge and it's often difficult to find where something is defined. Anyway, long story short, I've decided to investigate the feasibility of rewriting the parts of GTK+ that I like directly in D. It's early days yet and the code is in a private repository on github. I'll keep it private until I have some useful subset working at which time I'll make it public. Of course, if I find that it's all too hard I'll just delete it. Early indications are that the code will be much simpler than the original as GTK+ implements its own OOP and GC where I'll just delegate that to D. :-) Peter
Re: param2 = param1
On 2013-08-28 23:51, Walter Bright wrote: Is this really a problem that needs solving? It's not that important. You asked for use cases, I showed a couple. Is it really consistent if you have to add a new section in the documentation explaining it? That sounds like the documentation is not very well structured. Either this is missing from the documentation, and should be added, or it should already be documented somewhere. If it is already documented, and documented for templates, it should be moved to a section covering arguments both for templates and regular functions. So yes, possibly depending on how the documentation currently look like. BTW, if I recall correctly "consistency" is usually one of your arguments for doing, or not doing, something. -- /Jacob Carlborg
Re: [dox] enum specs vs reality
On 2013-08-28 17:34, captaindet wrote: b) what typeof expects/tolerates seems to be a bit of a minefield by itself. enum test = true; writeln( typeof(test).stringof );//prints: bool enum wtf; writeln( typeof(wtf).stringof );//Error: argument wtf to typeof is not an expression Actually, I previously misread this. This is working as it should. The first declares a manifest constant: enum test = true Is short for: enum bool test = ture; "bool" is the type, "test" is the name. The second declares a new type, where "wtf" is the name of the type. -- /Jacob Carlborg
Re: DIP45: fixing the dllimport/dllexport issue
On 27.08.2013 15:40, Benjamin Thaut wrote: Am 27.08.2013 15:33, schrieb Andrej Mitrovic: On 8/27/13, Benjamin Thaut wrote: Well, a link would have been great: http://wiki.dlang.org/DIP45 Using export(identifier) is not going to be reliable, since chances of clashes are high. E.g. if libFoo uses export(Foo) and libBar also uses export(Foo), you won't be able to distinguish between the two. Instead I think 'identifier' should be a module name. However, I have a better idea. Why not only introduce compiler switches that are based on module names rather than having to annotate what export does in code? For example: dmd -m64 -export libB.* -import libA.* -of"libB.dll" dllmain.d libB.d -L/DLL -L/IMPLIB:"libB.lib" -LlibA.lib "-export libB.*" means all modules and subpackages of the libB package should be exported, whereas "-import libA.*" means the opposite for libA. This way you don't have to edit any existing code. I thought about something along those lines aswell. But wouldn't that create a very long command line if you do it for druntime? I think export (at module granularity) can be handled by building the modules with symbols to export using a command line switch "-exportall", and all other modules without. I'd prefer if the compilation against the imported library would be agnostic whether it is later linked against a static or dynamic library. How is this done on linux right now? It does not need "export"/"import" to build against a shared phobos library. Is "import" assumed for any data access and later removed by some magic in the linker?
Re: [dox] enum specs vs reality
On 2013-08-28 17:26, captaindet wrote: enum keyword covers both, enumeration constants and manifest constants. the specs cover both in one. moreover, they explain that manifest constants are only syntactic sugar for anonymous enums: enum { A = 2, B = 4 } is the same as enum A = 2; enum B = 4; The above is short for: enum int A = 2; enum int B = 4; They declare manifest constants, not types. It's the same as: immutable int A = 2; But you can't take the address of "A", which you can if it's declared as immutable. -- /Jacob Carlborg
Re: obsolete D libraries/modules
On Thursday, 29 August 2013 at 06:34:23 UTC, Peter Williams wrote: On 29/08/13 16:11, Rikki Cattermole wrote: I will say this, one thing about D that has annoyed me from the beginning is the state of the gui libs. Hence why in last month I've been having a real good play around with OpengGL and creating my own library [1]. On this topic, I started looking at porting one of my PyGTK applications to GtkD and found that the knowledge of PyGTK API wasn't a great deal of help in this endeavor. I think the problem is Python's "duck typing" and dynamic typing allow for a very flexible API that is much simpler than GTK+'s and GtkD's is much like GTK+'s. The problem is complicated by the fact that the amount of documentation is huge and it's often difficult to find where something is defined. Anyway, long story short, I've decided to investigate the feasibility of rewriting the parts of GTK+ that I like directly in D. It's early days yet and the code is in a private repository on github. I'll keep it private until I have some useful subset working at which time I'll make it public. Of course, if I find that it's all too hard I'll just delete it. Early indications are that the code will be much simpler than the original as GTK+ implements its own OOP and GC where I'll just delegate that to D. :-) Peter Nice :) Although be careful it was designed for more Posix environment. I'm keeping DOOGLE as far limited in terms of platform dependence. So porting is literally implement the OpenGL context creation and Window creation classes. Also for anyone interested I'm keeping the controls that require text out of DOOGLE because of the font rasterizer dependency.
Re: bug in typeof or wrong enum specs?
On 2013-08-29 01:28, captaindet wrote: a recent discussion ( http://forum.dlang.org/thread/kvje4r$1tff$1...@digitalmars.com ) about the official enum dox ( http://dlang.org/enum.html ) was not conclusive whether enum IDENTIFIER; is officially allowed/supported. jacob pointed out that it has an important use case in that it can serve as UDA. as UDAs are fairly new, this cannot be the reason why this syntax was allowed in the first place though, *if* it is allowed. No, but now it's a useful use case. also, it might be used in meta stuff similar to "#define IDENTIFIER" in C - playing with this idea i run into this issue... while much code behaves with such an empty enum declaration, writeln( __traits(compiles, IDENTIFIER) );// true writeln( is( IDENTIFIER == enum ) );// true typeof() is not happy at all (DMD 2.063.2): writeln( typeof(IDENTIFIER).stringof ); // Error: argument IDENTIFIER to typeof is not an expression typeof() expects an expression and a bare identifier is a "PrimaryExpression" ( http://dlang.org/expression.html#PrimaryExpression ) and hence a valid argument. either the empty enum declaration is not allowed (and should be removed from the dox and throw a compilation error) or there is a bug in typeof(). No, I previously misread your post. enum foo; The above declares a type, with the name "foo". enum bar = 1; Declares a manifest constant, short for: enum int bar = 1; The type is "int", the name of the constant is "bar". typeof(bar); // ok, "bar" is not a type typeof(int); // error, "int" is a type typeof(foo); // error, "foo" is a type Although I do think that typeof(type) should work and just return "type". -- /Jacob Carlborg
Re: New linker error with xml2
On Thu, 29 Aug 2013 13:11:14 +0900, Kenji Hara wrote: > 2013/8/29 ollie > >> I have been seeing a new linker error while building xml2. > Did you rebuild xml2 library after updating/rebuilding dmd code? > Because the dmd commit changes the object file places where some > instantiated template code are emitted. > > Kenji Hara Thanks for the reply Kenji. Yes, because it is so fast to recompile with dmd, I always recompile both xml2 and GtkD after dmd/druntime/phobos/tools to stay ahead of changes. Using the dmpobj.exe from OpenWatcom, I searched for the missing function in the test program sxmltest.obj and xmlp.lib for compilations just before commit 751353c8217596726ab219b7d3a690e8950e409e and for git-head. The function is only emitted into sxmltest.obj as a EXTDEF record type. EXTDEF(8c) recnum:1545, offset:00010cc8h, len:009ah, chksum:00h(aa) 821 - '_D3std9exception7bailOutFNaNfAyakxAaZv' Type:0 822 - '_D3alt7zstring22__T9KeyValRecTAyaTAyaZ9KeyValRec8opEqualsMxFKxS3alt7zstring22__T9KeyValRecTAyaTAyaZ9KeyValRecZb' Type:0 Thanks, ollie
Re: New Lagged Fib. PRNG gen and random2.d
On Thursday, 29 August 2013 at 00:04:08 UTC, Joseph Rushton Wakeling wrote: On Wednesday, 28 August 2013 at 18:43:53 UTC, monarch_dodra wrote: With that said, even with classes, we'd need an easy way to create the classes from the payloads. Don't understand. With classes you don't need payloads. Just converting existing RNG structs to final classes is sufficient. Yes, that'd be the idea, but I mean that if you do that, you close the door to giving straight access to a struct-implementation. Also, placing a value-type payload in a class is pretty trivial.
Re: Building 2.063.2 from source produces non-working toolchain??
On 2013-08-29 00:18, H. S. Teoh wrote: While trying to track down a 2.063.2 problem someone posted to the D.learn forum, I tried to build dmd/druntime/phobos 2.063.2 from source, and to my chagrin, discovered that the resulting toolchain is non-functional. Even the simplest program: void main() {} doesn't compile: Using a clone from git or the zip release? -- /Jacob Carlborg
Re: DIP45: fixing the dllimport/dllexport issue
On 2013-08-29 08:43, Rainer Schuetze wrote: How is this done on linux right now? It does not need "export"/"import" to build against a shared phobos library. Is "import" assumed for any data access and later removed by some magic in the linker? "export" is noop on Posix. Every symbol is accessible. -- /Jacob Carlborg
Re: bug in typeof or wrong enum specs?
On 29.08.2013 01:28, captaindet wrote: a recent discussion ( http://forum.dlang.org/thread/kvje4r$1tff$1...@digitalmars.com ) about the official enum dox ( http://dlang.org/enum.html ) was not conclusive whether enum IDENTIFIER; is officially allowed/supported. jacob pointed out that it has an important use case in that it can serve as UDA. as UDAs are fairly new, this cannot be the reason why this syntax was allowed in the first place though, *if* it is allowed. also, it might be used in meta stuff similar to "#define IDENTIFIER" in C - playing with this idea i run into this issue... enum IDENTIFIER; was used to help resolving forward references to type IDENTIFIER when the resolving of forward references was a lot less capable than it is now. I don't think it is still needed for that. The same syntax exists for struct or class. Please also note that using it as in C/C++ to declare a type that is actually defined in another module does not work. The type is bound to the current module and the definition has to be in that module.
Decrease DMD memory usage
How can I decrease DMD memory usage? My program does now use about 3.5GB during compilation, which is horrible, as even machines with 4GB RAM sometimes fail to compile successfully :( -- Marek Janukowicz