Re: OT: What's your favorite codeline?
downs wrote: downs foo.betweens(src=\, \) /select/ (string s) { return s.find(criteria) != -1; } Heh, I love that infix expression syntax. Too abd it ends up with a completely useless wrapper struct 2 function calls, but hopefully LDC can inline that out. downs auto videocon = ctx.getStreams().first(WHERE!(?.codec.codec_type == CodecType.Video)).codec; Heh, going LINQ on us, now?
Re: D should disallow forward references
Stewart Gordon wrote: Have you written a compiler for a superset of C in which arbitrary forward references are allowed? How did you do with overcoming the difficulty that is C's context-sensitive grammar? C (minus preprocessor, of course) is only context-sensitive with regards to casts AFAIK. Since casts are always expressions, you can rewrite parenthesized expressions to casts (or vice versa) in a second pass but still allow forward references. Java and C# are also context-sensitive as far as casts go.
Re: escaping pointer to scope local array: bug or not?
Steven Schveighoffer wrote: It also says that Java 6, a language compiled as I proposed D could be, has escape analysis. Java's escape analysis is done at runtime (during JIT compilation) AFAIK. LDC can compile to bitcode and link-time codegen could be used to deal with escape analysis... this doesn't help (much) in generating errors, but it allows better codegen.
Re: escaping pointer to scope local array: bug or not?
Robert Jacques wrote: ship/sell D libraries in binary format. Does anyone sell static libraries anymore? There are too many problems with static linking for that to be very viable. Most libraries I've seen are sold as DLLs.
Re: std2.xml and std2.encoding for D 1.0 available at D source
On Tue, Aug 11, 2009 at 11:03 PM, Michael Rynnmichaelr...@optushome.com.au wrote: I took away all the safety features of const, immutable and any other things that dmd 1.0 complains about, as recommended for the std2. Well, different people feel differently about these things. IMO, the complication of const/immutable and loss of productivity doesn't justify the small gains in safety. Whether it justifies the muiltithreading advantages is yet to be seen, though there's some promising stuff coming from the minds of AW. Bill Baxter wrote: Very cool. You should probably know, though, that std.xml is not very popular. I'm don't have much to do with XML -- by choice, horrid stuff if you ask me -- but folks who have played with std.xml have found it buggy and very slow. And the original author has disappeared. There has been talk that it needs to be rewritten from scratch. Or perhaps replaced with a port of tango's very speedy xml library. Yup... among other things, it does not correctly handle elements that are closed with / (i.e. `x/` instead of `x/x`). This is basically a show-stopper bug, IMO. As far as Tango's XML goes, yeah, it's awesome; check out: http://dotnot.org/blog/archives/2008/03/10/xml-benchmarks-updated-graphs-with-rapidxml/ http://dotnot.org/blog/archives/2008/03/10/xml-benchmarks-parsequerymutateserialize/ http://dotnot.org/blog/archives/2008/03/09/xml-benchmarks-pros-and-cons-of-each-library/ http://dotnot.org/blog/archives/2008/03/12/why-is-dtango-so-fast-at-parsing-xml/ That second link in particular is a holy ; look at those bars type of experience.
Re: Memory allocation problem
bearophile wrote: grauzone: Then what is there to complain? I have paid for 2 GB RAM, so I am allowed to desire a 1800 MB array :-) I agree it's a bug, and probably a rather major one. However in a real use case, any program that needs 1800+ MB arrays should be 64-bit only.
Re: SSE, AVX, and beyond
Eljay wrote: As cent/ucent, should a keyword be reserved for 256? 512? 1024? - - - - - - - - - - - - - - - Most programming languages are loathe to add new keywords, because that has the chance to impact existing code. So the time to add keywords for D 2.0(alpha) is now, since the language is in alpha. For 128-bit signed/unsigned int, D has reserved cent and ucent. Perfect for working with UUIDs. But not implemented yet. Is there ANY use case where you'd need a 256-bit integer instead of a BigInteger? Even 128 is a bit dodgy. UUIDs and what not are identifiers, not numbers, so have no problem being stored in a struct wrapping a ubyte[]. I agree compilers should support 256+ bit _data_... But doing so with an entirely new numeric data-type is probably a bad idea. Special treatment for certain constructs and library support is a much better idea.
Re: Memory allocation problem
bearophile wrote: I don't think so, I am running a 32 bit GCC on a 32 bit XP operating system. I think the bug is elsewhere (in DMD). Have you tried with DMC?
Re: proposed syntax change
Paul D. Anderson wrote: I was browsing the Python spec yesterday and came across this interesting and useful syntax: / (one slash) means floating point division, e.g. 5/2 = 2.5 even though 5 and 2 are integers // (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0 even though 5.0 and 2.0 are floats. I've always been a little troubled by the standard division operator being dependent on the types of the operands. (I understand the need for it, I just didn't like it much.) Now here is an elegant (IMHO) solution. I like the idea of adding a floating point division, but I think it should be a *new* feature while the current / and // are left as they are. How about ./? 5 / 2 = 2 // Current behavior 5.0 / 2.0 = 2.5 // Current behavior 5 ./ 2 = 2.5 // New behavior 5.0 ./ 2.0 = 2.5 // It always floating-point divides IOW, ./ is short for cast operands to double and divide. If ./ proves too hard to parse (I think it might require some lookahead), then /^ might work.
Re: Contextualizing keywords
Daniel Keep wrote: function-declaration puretrue/pure returnTypeSomeType/returnType namefoo/name parameters/ body comment ... /comment /body /function-declaration Ah, you saw the announcement for Microsoft's new .NET language?
Re: Naming things in Phobos - std.algorithm and writefln
Michel Fortin wrote: As you know, I tried to write some guidelines[1] for naming things in D. Those guidelines looks well at first glance, but then you look at Phobos and you see that half of it use some arbitrary naming rules. Take writefln for instance: following my guidelines (as they are currently written) it should be renamed to something like writeFormattedLine. [1]: http://prowiki.org/wiki4d/wiki.cgi?DProgrammingGuidelines I think naming guidelines aren't a bad thing, but they can be taken too far. We use an automated tool at work to check code and today I was forced to change the name of some classes because they ended in Queue or Dictionary and fix the spelling of Http because it thought it was Hungarian notation.
Re: reddit.com: first Chapter of TDPL available for free
Nick Sabalausky wrote: One little niggle though: At the end of the paragraph that explains the hello world's import statement, it says Repeated imports of the same file are of no import. Sounds like a typo snuck in there. Or a pun ;-P.
Re: property syntax strawman
Walter Bright wrote: Having optional parentheses does lead to unresolvable ambiguities. How much of a problem that really is is debatable, but let's assume it should be resolved. To resolve it, a property must be distinguishable from a regular function. One way is to simply add a property attribute keyword: property bool empty() { ... } property void empty(bool b) { ... } The problem is that: 1. there are a lot of keywords already 2. keywords are global things The alternative is to have a unique syntax for properties. Ideally, the syntax should be intuitive and mimic its use. After much fiddling, and based on n.g. suggestions, Andrei and I penciled in: bool empty { ... } void empty=(bool b) { ... } The only problem is when a declaration but not definition is desired: bool empty; but oops! That defines a field. So we came up with essentially a hack: bool empty{} i.e. the {} means the getter is declared, but defined elsewhere. What do you think? I promised myself I'd never use this emoticon, but it's time to break that rule: 3 3 3 3 Excellent solution.
Contextualizing keywords
Hi, hope you're all enjoying the properties debate. I've been seeing the too many keywords argument a lot lately, and I think it's definitely a valid argument. shared and body in particular are rather annoying keywords since I frequently use them in code. And if users are deciding not to use D because of the number of keywords, that's even worse. The idea of kewyord as a parser construct is antiquated thinking. Look at C#: get, set, value, event, var, etc. are only keywords in a particular context. C++/CLI takes it a step further (from http://blogs.msdn.com/hsutter/archive/2003/11/23/53519.aspx ). There are three new reserved words (gcnew, generic, nullptr) and a few multi-word keywords (for each, enum/interface/ref/value class/struct) as well as some contextual keywords that can only appear in certain positions. In D, without a significant change to the lexer/parser, any keywords that cannot appear in the same place as an identifier could be made legal identifiers easily. Off the top of my head, in, out, body, module, unittest, import, throw and probably a few others could be freed up. With some parser lookahead, you could add modifiers and storage classes to the list and probably dozens of others. If braces were required in try/catch statements, try, catch, and finally could be added. Further, this might be pretty easy to implement (i.e. Walter, if you're interested, I'm willing to make a patch). It's all backwards-compatible and would even work in D1. Thoughts?
Re: Contextualizing keywords
Walter Bright wrote: Chad J wrote: This makes things more difficult for syntax highlighters. A number of them will just not work correctly because they don't actually parse the code. That's true. Another thing keywords provide are anchors that enable better error recovery. Read Herb's article; he mentions error recovery. I agree that the ; at the end of the line is a useful anchor, but in the position in out and body can appear, the ONLY valid words are in, out, body, const, immutable, shared, pure, nothrow, etc. So the error messages for these ones won't get much worse. For category 3 (keywords that can appear where identifiers can), I agree it could get confusing. But at least category 1 (keywords that cannot appear in the same place as identifiers) would be little loss.
Re: Contextualizing keywords
Oliver Hoog wrote: And requiring try/catch to have braces introduces inconsistency. That was probably a bad idea. However note that D is actually the inconsistency here -- C++, Java, and C# all require the braces.
Re: Contextualizing keywords
Chad J wrote: This makes things more difficult for syntax highlighters. A number of them will just not work correctly because they don't actually parse the code. That's all I've got. Ehhh How often will you actually use the identifiers? The point isn't to make them free for use, it's more to reduce the number of people bitching about how many keywords there are.
Re: Reading bool as the string true or false
Ali Cehreli wrote: If the default behavior for dout.writefln is to print bool values as the true and false strings, then the opposite should be available and arguably be the default: // true and false should be acceptable inputs: bool b; din.readf(b); Am I wrong? Thanks, Ali P.S. There hasn't been any responses to the same question that I asked at the .learn forum: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learnarticle_id=17291 Open a bug; the newgroups aren't the right place for this. Thanks!
Re: DIP6: Attributes
Tim Matthews wrote: On Sat, 01 Aug 2009 16:29:28 -0300 Ary Borenszweig a...@esperanto.org.ar wrote: http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP6 Are pragmas not already here for this? Nope, they're for compiler-specific extensions
Re: YAPP - yet another properties poll
aarti_pl wrote: Please add another syntax proposals (max. 2 best proposals - with example code) and correct mistakes in questions (if any): I like the C# style: int size { get { return _size; } set { _size = value; } } get, set and value are only keywords within a property block, if you use them elsewhere, they're just regular identifiers.
Re: Descent, now with Open Type Hierarchy
BCS wrote: will it find it if I ask out of order? Say, QDL? No... what's the use case there? JDT does have auto-corrections for misspellings of variables, though (I think based on Levishien distance, so it's dictionary-independent)... this might be intersting to add to autocomplete. So if you try to autocomplete f*ei*ldN it will suggest f*ie*ldName. Also in an ideal world it would be capitalization-independent.
Re: Some things to fix
Ary Borenszweig wrote: 2. modifiers that don't make sense should be disallowed. There's been wars about this one. IMO, this is a good thing for writing templated/generic code -- if a modifier only makes sense in one instance of a template, all the others should not be marked as errors. I think _conflicting_ modifiers should be made an error, i.e. public private int x;.
Re: A simple rule
Walter Bright wrote: Compare your car with a Model T. The T is simple, easily repaired, easily understood. But who wants to drive a T these days compared with driving a modern car? It would be the _ultimate_ pimpmobile.
Re: A simple rule
downs wrote: 1) If it's a word, put it in the standard library. 2) Otherwise, put it in the compiler. for - compiler. foreach - library. But for is a word, while foreach isn't! ;-P
Re: Yet a new properties proposal
Dimitar Kolev wrote: Steven Schveighoffer Wrote: I don't see what advantages this has over other proposals. What is wrong with a.a such that we have to resort to a#a? -Steve People are crying over compilers not know which is a property and which is not. Actually, one of the major features of properties is that any field can be changed into a property without any changes to existing code. If you're looking for an unused symbol, @ is likely a better choice than #.
Re: poll for properties
Steven Schveighoffer wrote: ... The number of people taking this seriously worries me.
Re: The empty statement ; - when is it useful?
BCS wrote: for({} false; 42) {} Eww...
Re: Can enum and immutable be unified?
Don wrote: Robert Fraser wrote: Don wrote: Ary Borenszweig wrote: Michiel Helvensteijn escribió: Walter Bright wrote: immutable - data that cannot change or be changed (imagine it is stored in ROM) const - read only view of data, you cannot change it but others can enum - compile time constant, has no storage The only place these overlap is in the declaration of symbolic constants. C++ has all three, but in a way that is context dependent that very few people are aware of. Aren't immutable and enum the same thing? At least to the programmer? Yesterday I was thiking the same thing. I think the only difference to the programmer between those is that you can take the address of something immutable, but can't take the address of a compile time constant. Now I wonder why would you like to take the address of something that's immutable. The times I remember passing something's address is to change it, something like: int x = 10; foo(x); // now x might have changed But immutable variables cannot change, so no need to pass it by reference. The other usage is performance. If it's an immutable big struct you might want to pass it by reference instead of copying the whole thing. If you can't pass a reference to something immutable you couldn't do with this optimization. But in this case, the compiler could choose to rewrite mentions to big immutable variables as references to those in a transparent way to the programmer. Of course this is harder for the compiler writer, but it's much easier for the user. (as a starting point the compiler could do without this optimization and see if the users are having problems without it) I can't come up with other cases where you'd want to pass a reference to something immutable. So let's suppose we don't need to take an immutable varaible's address. We get rid of enum then and unify immutable and enum into the single immutable keyword. The compiler still has to determine what to put in ROM and what not. But I think this one is easy: primitive types can go in ROM, also maybe small immutable structs, maybe primitive arrays, but not classes or references to classes. Is there something fundamentally wrong with this reasoning? AFAIK, the only reason 'enum' manifest constants exist in D2 is because of linking limitations. OPTLINK isn't smart enough to be able to discard immutable references. There's no need to use them, unless you have something like the Windows headers, where they're an enormous bloat if they aren't discarded. Most people should forget they exist. Since objconv works with OMF now, how hard would it be to get a workflow going to use a different linker on Windows? Every other post these days seems to be oh, it's an optlink issue objconv can disassemble OMF now, but it can't yet convert COMDAT sections, so it can't convert them to ELF or COFF. Might not be so difficult, if someone wanted to do it. D's use of COMDATs is not so complicated. I would _love_ to see being able to use another (MS?) linker on WIndows
Re: Can enum and immutable be unified?
Don wrote: Ary Borenszweig wrote: Michiel Helvensteijn escribió: Walter Bright wrote: immutable - data that cannot change or be changed (imagine it is stored in ROM) const - read only view of data, you cannot change it but others can enum - compile time constant, has no storage The only place these overlap is in the declaration of symbolic constants. C++ has all three, but in a way that is context dependent that very few people are aware of. Aren't immutable and enum the same thing? At least to the programmer? Yesterday I was thiking the same thing. I think the only difference to the programmer between those is that you can take the address of something immutable, but can't take the address of a compile time constant. Now I wonder why would you like to take the address of something that's immutable. The times I remember passing something's address is to change it, something like: int x = 10; foo(x); // now x might have changed But immutable variables cannot change, so no need to pass it by reference. The other usage is performance. If it's an immutable big struct you might want to pass it by reference instead of copying the whole thing. If you can't pass a reference to something immutable you couldn't do with this optimization. But in this case, the compiler could choose to rewrite mentions to big immutable variables as references to those in a transparent way to the programmer. Of course this is harder for the compiler writer, but it's much easier for the user. (as a starting point the compiler could do without this optimization and see if the users are having problems without it) I can't come up with other cases where you'd want to pass a reference to something immutable. So let's suppose we don't need to take an immutable varaible's address. We get rid of enum then and unify immutable and enum into the single immutable keyword. The compiler still has to determine what to put in ROM and what not. But I think this one is easy: primitive types can go in ROM, also maybe small immutable structs, maybe primitive arrays, but not classes or references to classes. Is there something fundamentally wrong with this reasoning? AFAIK, the only reason 'enum' manifest constants exist in D2 is because of linking limitations. OPTLINK isn't smart enough to be able to discard immutable references. There's no need to use them, unless you have something like the Windows headers, where they're an enormous bloat if they aren't discarded. Most people should forget they exist. Since objconv works with OMF now, how hard would it be to get a workflow going to use a different linker on Windows? Every other post these days seems to be oh, it's an optlink issue
Re: (Non) Nesting block comments
Michel Fortin wrote: On 2009-07-21 05:31:13 -0400, Michiel Helvensteijn m.helvensteijn.rem...@gmail.com said: Robert Jacques wrote: Well /* */ are excellent for toggling code sections. I tend to use constructs such as // */ or //* or /*/ which allows me to turn on of off blocks with often a single key stroke. Using /+ +/ means I have to Add /++/ and remove /++/ each time I want to activate or deactivate a code block. Why? I believe that /++/ works exactly like /**/ in that regard. Doesn't it? //+ code that can be turned off by removing the first / //+/ I'm pretty sure he meant comment out a signle line at the top, not both, like this: /* A /*/ B /**/ With this, you compile B while A is in a comment. Add / at the start of the first line and you compile code A while B is now in commented out. Wow, you just blew my mind. I wish they taught this sort of stuff in programming 101.
Re: stack trace hack for recent Phobos?
Trass3r wrote: Robert Fraser schrieb: Windows or Unix? Currently I only need Windoze, but knowing the linux situation wouldn't be bad either. There's no Windows stack trace that works with the newest Phobos AFAIK, however if you're using D2, you could probably copy Tango's stacktrace pretty easily since it has no dependencies on Tango other than the runtime, and druntime is used in Phobos2.
Re: need help convert c code
D. Reeds wrote: can anybody help me translate this c code into d, im using D1+tango combo. i'm new to D and got stucked on multi-dimension array part. int levenshtein_distance(char *s,char*t) //Compute levenshtein distance between s and t { //Step 1 int k,i,j,n,m,cost,*d,distance; n=strlen(s); m=strlen(t); if(n!=0m!=0) { d=malloc((sizeof(int))*(m+1)*(n+1)); m++; n++; //Step 2 for(k=0;kn;k++) d[k]=k; for(k=0;km;k++) d[k*n]=k; //Step 3 and 4 for(i=1;in;i++) for(j=1;jm;j++) { //Step 5 if(s[i-1]==t[j-1]) cost=0; else cost=1; //Step 6 d[j*n+i]=minimum(d[(j-1)*n+i]+1,d[j*n+i-1]+1,d[(j-1)*n+i-1]+cost); } distance=d[n*m-1]; free(d); return distance; } else return -1; //a negative return value means that one or both strings are empty. } int minimum(int a,int b,int c) //Gets the minimum of three values { int min=a; if(bmin) min=b; if(cmin) min=c; return min; } it is a levenshtein distance algorithm. Ummm... import tango.stdc.stdlib then copy paste; that code should work the same in D as in C. The only changes you should need are: int k,i,j,n,m,cost,*d,distance; Which should be changed to: int k,i,j,n,m,cost,distance; int* d; And sizeof(int) - int.sizeof
Re: All this talk about finalising D2 makes me worried
Stewart Gordon wrote: With apologies to Bruno Medeiros All this talk about getting D2 finished (and other things like what comes next) makes me worried. People talk as if D2 is nearing completion: there are even threads about the coming or even requesting the release of the finished product that D2 will be. For a start, finishing D1 off has to come first. I refer you all back to this discussion: http://www.digitalmars.com/d/archives/digitalmars/D/When_will_D1_be_finished_89749.html http://www.digitalmars.com/d/archives/digitalmars/D/Re_When_will_D1_be_finished_89913.html http://www.digitalmars.com/d/archives/digitalmars/D/Re_When_will_D1_be_finished_89874.html (I don't know why the thread has become split in three.) I've a further feeling that some have suggested declaring D1 obsolete. Except that obsolete would be the wrong word - it would be more a case of D1 becoming a project that was started and then abandoned. Which might sound like a good plan to some. However, I can't at the moment think of any D1 spec issue or major bug that doesn't also affect the D2 line. As such, abandoning D1 will do nothing to bring closer the time when we can freeze the D 2.0 spec. It is thus in the community's best interests to get D1 finished sooner rather than later, as we will then have a D that we can all use and third parties can implement. (Yes, I know I should contribute to the effort. Trouble is that, now I have a job, my time for stuff like this is limited. But hopefully some time I'll find the time to do some work on it.) Once D1 is done and dusted, _then_ we can shift our efforts to polishing D2 ready for finalisation and eventual stable release. But in any case, we need to take things one step at a time. Stewart. This topic has come up over and over, and the results are always the same: D1 will continue to be supported by Walter co., but no new features will be in it. There _are_ some longstanding D1 issues (contract inheritance, in particular), but all (or nearly all) of these are issues with D2 as well, so hopefully they'll get fixed for both. In 1.045 and 1.046, a few older bugs started to get fixed, so there is definitely a show of some commitment by Walter towards getting stability in _both_ branches of D. Further, the continued development of Tango other D1-specific tools and libraries shows a strong community commitment to the language. The LDC community also has been hard at work getting D1 bugs fixed, and LDC has already fixed a few that DMD hasn't (and posted patches Walter hasn't looked at...).
Re: C compatibility
BCS wrote: One thing Walter is adement about is that copy-n-paste C code must run correctly (i.e the same) in D or not compile. As for the C style type syntax, I'd be willing to see that go en-total. It's useful if you have a .h that you both include in a C/C++ file and run through a preprocessor to output a .d file.
Re: dmd crashes with out of memory error
File is probably too big. Remember that for every byte in your binary, DMD is likely allocating several hundred for the literal xpression object + codegen for the expression, etc., and frees very little dynamically allocated memory. Trass3r wrote: Here are the files, if you want to try out: http://ul.to/2f5zzq Why have people not learned about SkyDrive? I'm surprised crap like this, Megaupload, etc is still in business. SkyDrive has no stupid wait time, is ing fast (MS has a lot of data centers, all over the world) and 50MB per-file/25GB total limits [and yes it's free].
Re: C++0x Concepts - Dead?
Andrei Alexandrescu wrote: Jarrett Billingsley wrote: On Mon, Jul 13, 2009 at 5:59 PM, Andrei Alexandrescuseewebsiteforem...@erdani.org wrote: Jarrett Billingsley wrote: On Mon, Jul 13, 2009 at 5:46 PM, Jarrett Billingsleyjarrett.billings...@gmail.com wrote: On Mon, Jul 13, 2009 at 5:33 PM, Walter Brightnewshou...@digitalmars.com wrote: There are unconfirmed reports that this morning, the C++0x standards group in Frankfurt voted to kill Concepts. Oh, wow. I mean, really, I'm kind of speechless. I thought they were supposed to be one of the killer features. You were at the wrong tense: -ing, not -er. :o) Ahaha, good one :) Yeah, what's the solution to a complex, incomprehensible language? More complexity! Speaking of which, I think D has reached the perfect shade with restricted templates. That is, after Walter fixes the related bugs... Andrei ... And gets rid of SFNAE... Seriously, with restricted templates, template specializations, static if, etc., SFNAE is about as bug-prone a feature as we have in the language.
Re: Descent generated documentation
Daniel Keep wrote: But this is quite cool; always nice to have another alternative. :) What are the other alternatives? The interlinks are all but necessary for larger/OO projects.
Re: Descent generated documentation
Ary Borenszweig wrote: phobos: http://downloads.dsource.org/projects/descent/ddoc/phobos/ Tango: http://downloads.dsource.org/projects/descent/ddoc/tango/ *drool* I agree about the source code -- it's probably the main reason the Tango docs are so slow and it's useless 95% of the time. Doxygen can optionally generate source code in separate files and have links to it, which might be a good optional feature someday.
Re: Regex
BLS wrote: Vladimir Voinkov wrote: std.regex can't be used in compile time function call. It's quite frustrating... see dsource.org .. afaik there is a compile time regex project. hth http://www.dsource.org/projects/scregexp But the generated functions aren't CTFE-compatible AFAIK. A CTFE regex engine would be um... tricky to say the least. About 50GB of memory tricky (on DMD, LDC has a GC... though, it's still just as slow with CTFE). Really, if you need that level of code manipulation, a preprocessor is probably a better choice.
Re: The proper case for D.
Walter Bright wrote: Optlink does not discard unreference symbols, it just doesn't pull them in from the library. If it did always pull in everything from the library, then the minimum D executable size will be the size of Phobos. Since that isn't happening, something else is happening with your code. I bet that those unreferenced symbols *are* being referenced. You can determine this by using the librarian to remove those 'unreferenced' symbols from Phobos, and then link, and see if there are any unresolved symbol error messages. Hmmm... well, I built a 3rd-party library (Platinum UPnP + Neptune) into two static libraries (with VS). I then wrote a C wrapper function around one, just to test out the functionality I needed (a fraction of what was available). Originally, I wanted to statically link it with my D project so I ran objconv on the libs (COFF - OMF). I created a test D app that was basically just: extern(C) int cMain(); int main(char[][] args) { return cMain(); } ... And linked it to the OMF version of the library. Worked fine, but the result was ~12MB, which is about 200k larger than the two libraries. I'm now using VC++ to build it into a DLL that exposes the function. 802kb for a debug DLL, 280k for a release. The same thing is happening with my other library (ffmpeg -- libavcodec, libavformat, libavutil and swscale), which I built as static libraries with MinGW gcc and converted again with objconv. In this case, I'm too lazy to create a DLL to wrap only the functions I want, though I may end up doing just that once my project gets closer to usable.
Re: The proper case for D.
Walter Bright wrote: Robert Fraser wrote: Hmmm... well, I built a 3rd-party library (Platinum UPnP + Neptune) into two static libraries (with VS). I then wrote a C wrapper function around one, just to test out the functionality I needed (a fraction of what was available). Originally, I wanted to statically link it with my D project so I ran objconv on the libs (COFF - OMF). I created a test D app that was basically just: extern(C) int cMain(); int main(char[][] args) { return cMain(); } ... And linked it to the OMF version of the library. Worked fine, but the result was ~12MB, which is about 200k larger than the two libraries. I'm now using VC++ to build it into a DLL that exposes the function. 802kb for a debug DLL, 280k for a release. The same thing is happening with my other library (ffmpeg -- libavcodec, libavformat, libavutil and swscale), which I built as static libraries with MinGW gcc and converted again with objconv. In this case, I'm too lazy to create a DLL to wrap only the functions I want, though I may end up doing just that once my project gets closer to usable. It may be a problem with objconv where it puts everything into one obj file. Update on this -- I built it as a DLL in VS, exposing only the functions I need. The DLL is just under 5MB in release mode, and it took my main program down to 823k. Your explanation sounds likely, however it seems VS is discriminating on the per-symbol level...? I'm going to need to make sure runtime CPU detection was still built in, though; VS may have been too smart for its own good.
Re: The proper case for D.
Walter Bright Wrote: Robert Fraser wrote: Your explanation sounds likely, however it seems VS is discriminating on the per-symbol level...? Let's say the C++ source file looks like: int foo() { ... } int bar() { ... } it is compiled and put into a library. Your program references foo(). Pulling in the object module from the library that contains foo() also pulls in bar(), because bar() is in the same object module. If bar() references a bunch of other stuff, that gets pulled in, too. VS may contain some scheme to split a source file into multiple object modules which prevents this. Note that dmd will split a single source file into multiple object modules when you compile with -lib. Ah, thanks for the explanation. I didn't understand it pulled in whole object files at once, though given that libraries are just archives of object files, I should have assumed.
Re: Ranges
bearophile wrote: (P.S.: Is Walter around still? He's pretty silent lately. Talking when he's not around looks quite academic). He gave a D talk on Wednesday night. I get the feeling the next release is going to be something big.
Re: Ranges
Steve Teale wrote: template isInputRange(R) { enum bool isInputRange = is(typeof( { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }())); } I can not possibly be the only D enthusiast who finds this completely incomprehensible. Yeah, that one is a bit tricky, and what makes it worse is that it seems officially sanctioned by Walter/Andrei as the right way to check if a type supports some operations. Basically, if you have: is(typeof({ @@@ }())); this means if I made a function containing @@@, would that function compile?. It's a hack which stems from the way the is expression works. What is a range? As others have mentioned, it's just a struct (or other type) that happens to support certain operations.
Re: Ranges
grauzone Wrote: Your example doesn't compile right now. The @@@ was meant as an example to be replaced with any code. Yeah, you probably knew that. But if you use a string mixin, the code doesn't even have to be syntactically/lexically valid: is(typeof({ mixin(@@@); })) True -- both these features (string mixins and is-expressions) are rife with pitfalls. But they're both very useful features (if you get rid of string mixins, 25% of my code will stop compiling...). Silent compilation is dangerous indeed, but also very powerful. I was just suggesting we need a better syntax, but I realized we have one: __traits(compiles). Why Andrei isn't using this is the real mystery.
Re: Ranges
bearophile wrote: template isInputRange(R) { enum bool isInputRange = __traits(compiles, { R r; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke next auto h = r.front; // can get the front of the range }); } I don't know if this is correct, but if it's correct, is it better looking? It looks almost the same to me. Eh, it has the word compiles in it... You're right, though, it's not great. I guess a single linked list can be seen as an OutputRange then. You can add an item where you are and scan it forward (unfortunately linked listes today are dead, they are never an efficient solution on modern CPUs) LinkedList!(T) is basically useless. But how many times have you used a structure with a next and/or previous pointer? How about separate chaining in hash tables? parent pointers (forms a linked list up to the root for trees, also applies to GUI widgets, French fries, directory hierarchies, etc.)? Linked lists are *everywhere*, they're just generally implicit in some structure and not very long. In what othr situations you may use/need an OutputRange? In a file, as in a stack, you can only add in a very specific point (the end, in files, or replace the current item). I think an OutputRange doesn't have to be an InputRange. It just needs put().
Re: MiniD 2 - Might as well be done
Jarrett Billingsley wrote: I'm bad at meeting deadlines. Partly because I mismanage my time, but a large part of it is also because being a perfectionist, I never know when to _stop working on something_. After nearly two years in development, I think I'm ready to call MiniD 2 gold. http://www.dsource.org/projects/minid I write lots of docs. Please read them. = Oh wow, an interpreted version of D! = NO! That was the aim _three years ago_ but by now it's a completely different language. Please read the docs before you form your opinions on what it is :) = What's changed since MiniD 1? = Lots. It's enough to say that it's practically a different language. To be honest, I don't even consider MiniD 1 - either the language or the implementation thereof - anything more than a crude, unfinished work. MiniD 2 is what I consider to be the first _actual_ language/implementation. The MiniD 2 reference implementation is far more mature, complete, and efficient than its predecessor. It has been reimplemented pretty much from scratch and now features its own heap and GC separate from D's. While this does incur a bit of a hit on the terseness of the native API, it also manifests itself in a frankly _incredible_ increase in performance, as well as features that would have been difficult or impossible to implement using the native GC (like weak references and class finalizers). What kind of performance, you ask? Well, almost every test I've run kicks the crap out of Python, and is more in the ballpark of Lua. The only tests that don't quite measure up are those which are GC-heavy. The current implementation uses a simple mark-and-sweep GC, but that is one of my main development priorities after this release. If I can reach Lua's performance - awesome! The API is much more like Lua's now, though with some nice perks due to overloading that aren't possible in a C API. Writing code for what is essentially a stack language is kind of nice, in some ways. Being such a departure from what most people are used to, though, it can take some getting used to. The API is also much more there is one way to do it. The old MiniD 1 - and early MiniD 2 - APIs sometimes had several, inconsistent methods of acquiring information. This has been entirely done away with. That being said, D's current protection mechanisms (and DMD's forward reference issues) are woefully inadequate for dividing up the API the way I want to, forcing almost all of the public API functions into a single module. Sorry for that. = I'm bearophile, and I don't think it performs as well as X, and isn't similar enough to Python. = OK. Give me some benchmarks, and I'll see what's taking so long. As for the language style? Tough luck ;) I admit the standard library probably doesn't have as many lazy-evaluation functions and datatypes as it could, but that can certainly change. I am open to suggestions! = Why do I need it? = I don't know! Maybe you're just interested in learning new languages. Maybe you've got a legitimate need for a scripting language in one of the D apps you're writing. Whatever. I can't tell you why you need it. Only you know that. For a high-level, pseudo-philosophical introduction to the language, see http://www.dsource.org/projects/minid/wiki/Introduction2 I recommend you read the spec and the language tutorial if you're wondering what the language is all about. _Then_ can you tell me what you do and don't like. = What prerequisites do I need, and how do I install it? = D1 with Tango 0.99.8, currently. That's about it, as far as the core language and its standard libraries are concerned. Installation instructions are available here: http://www.dsource.org/projects/minid/wiki/Installation I plan on putting some more detailed docs up especially w.r.t. feti's sandbox script, since I haven't been able to get some configurations to work. If you're having trouble installing a D compiler or build tool or Tango, I'm sorry, but I just don't have the time or patience to help you install the prerequisites. I have spent far too much time helping others install those and it's just.. well, it's not my fault that the D toolchain is currently so fractured and hard-to-use, and I've kind of lost the will to help anyone else. Sorry :\ MiniD works fine with DMD and LDC. GDC is too old to compile it. Bug David Friedman or Arthur about that. :| = How do I x? = Please ask me. Here on the newsgroups is OK, but for more long-term conversations, *please* sign up for a dsource account and post your questions to the MiniD dsource forum (http://www.dsource.org/forums/viewforum.php?f=94). If you don't have a dsource account already, why not? ;) If you're one of those people who refuses to post on one of those dirty, slow, inefficient web forums, well, I guess you're not getting any help! Or you could just email me, but by doing that, you'll be depriving anyone else from seeing your question and the resulting answer.
Re: Andrei writes The Case for D
Tim Matthews wrote: Anders F Björklund wrote: Last but definitely not least, two windowing libraries complete the language's offering quite spectacularly. The mature library DWT is a direct port of Java's SWT. A newer development is that the immensely popular Qt Software windowing library has recently released a D binding (in alpha as of this writing). In other words, so long and thanks for all the fish: GDC and wxD ? --anders About the gui toolkits: Never mind the fact that GTKD has been working stable for a long time unlike the QT port. Best to include both to keep wars at bay in my opinion like kde vs gnome. You might want to toss in DFL, too. It doesn't compile on the latest anything without (a little) work, but it's a stable GUI library with a graphical designer that was designed from the ground up with D in mind.
Re: EnumBaseType conversion
dsimcha wrote: It has bitten me several times when I have a named enum type next to an integer type or something that an integer can be implicitly converted to in a function param list: enum MyEnum { FOO, BAR } Try... typedef int _MyEnum; enum MyEnum : _MyEnum { FOO, BAR }
Linking to MinGW-generated library woes
Has anyone been able to successfully link (statically) to a library generated by MinGW? I compiled the libraries in question (FFMpeg avutil, avformat, and avcodec) under MinGW, ran objconv on it to convert it to OMF (no errors) and passed it to optlink along with MinGW's libgcc. At this point I got quite a few undefined references: Error 42: Symbol Undefined _snprintf Error 42: Symbol Undefined ___strtod Error 42: Symbol Undefined _gettimeofday Error 42: Symbol Undefined _strncasecmp Error 42: Symbol Undefined _strcasecmp Error 42: Symbol Undefined ___mingw_vfprintf Error 42: Symbol Undefined ___fpclassifyf I've tried with different combinations of adding mingwex and libcoldname to the mix, but not only do they add some previous definition conflicts, neither was able to fix any of the linker errors. I might be able to manually find implement all those functions in the MinGW source, would this be the best way? Thanks, Robert
Re: [Issue 3070] New: Implicitly conversion on function call
d-bugm...@puremagic.com wrote: http://d.puremagic.com/issues/show_bug.cgi?id=3070 Summary: Implicitly conversion on function call Product: D Version: 2.030 Platform: x86 OS/Version: Windows Status: NEW Severity: trivial Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: k0l0b0k.v...@gmail.com I have next pieces of code: struct MyString { public MyString opAssign(string pStr) { throw new Error(); } public MyString opCast(string pStr) { throw new Error(); } public MyString opImplicitCast(string pStr) { throw new Error(); } this(string pStr) { throw new Error(); } } void foo(MyString pStr) { } int main(char[][] args) { MyString str = test1; str = test2; foo(str); foo(test3);// error Error: cannot implicitly convert expression (test3) of type immutable(char)[] to MyString return 0; } This is just sample. So, my trouble is to pass string argument to foo() with implicit conversion to MyString struct (I also tried class, with no results). I'm googled by this topic, but nothing found. Can you help me? This is not a bug (I think), but the question - how I can implicitly convert from one object to another in the as C++ does (C++ will call constructor with parameter type string). How I can make same in D? Thanks in advance! If you want quicker responses to questions, try the newsgroups or IRC. Bugzilla is usually for bugs :-). Anyway, user-defined implicit casting is not implemented in (any version of) D yet. Sorry!
Automatic translation from .h - .d using nothing but CTFE!
SharedLib _lib;; int numFuncs = functions.length / 2; for(int i = 0; i numFuncs; i++) { char[] type = functions[i * 2]; char[] name = functions[i * 2 + 1]; r ~= public static ~ type ~ ~ name ~ ;; } r ~= public void _loadLib() {if(_lib)return; scope(failure){_unloadLib();}; r ~= _lib = SharedLib.load(\ ~ libFile ~ \);; for(int i = 0; i numFuncs; i++) { char[] name = functions[i * 2 + 1]; r ~= name ~ = ~ cast(typeof( ~ name ~ )) _lib.getSymbol(\ ~ name ~ \);; } r ~= }; r ~= public void _unloadLib() { if(_lib){_lib.unload();}; for(int i = 0; i numFuncs; i++) { char[] name = functions[i * 2 + 1]; r ~= name ~ =null;; } r ~= }; return r; } private char[] convertCppTypes(char[] line) { line = line.ctfeReplace(_VOID, void); line = line.ctfeReplace(_LUINT, uint); line = line.ctfeReplace(_LINT, int); line = line.ctfeReplace(_INT, int); line = line.ctfeReplace(_UINT, uint); line = line.ctfeReplace(_LONG, long); line = line.ctfeReplace(_ULONG, ulong); line = line.ctfeReplace(_CHAR, char); line = line.ctfeReplace(_CONST, ); return line; } public char[] sharedFromHeader_mixin(char[] headerFile)(char[] libFile) { char[] h = import(headerFile); int lineStart = 0; bool inCopy = false; bool inFunctions = false; char[] r; char[][] functions; for(int i = 0; i h.length; i++) { if(h[i] == '\n') { char[] line = h[lineStart .. i]; lineStart = i + 1; if(line.ctfeStartsWith(//@)) { if(line.ctfeStartsWith(//@END)) { inCopy = false; inFunctions = false; } else if(line.ctfeStartsWith(//@FUNCTIONS)) inFunctions = true; else if(line.ctfeStartsWith(//@COPY)) inCopy = true; } else if(inCopy) { r ~= convertCppTypes(line); } else if(inFunctions) { if(!line.ctfeStartsWith(FUN()) continue; int s = 4; int j; for(j = 4; j line.length; j++) if(line[j] == ',') break; if (j == line.length) continue; char[] fname = line[s .. j]; s = j + 1; for(j = j + 1; j line.length; j++) if(line[j] == ',') break; if (j == line.length) continue; char[] retTy = line[s .. j]; s = j + 1; for(j = j + 1; j line.length; j++) if(line[j] == ';') break; if(line[j - 1] != ')') continue; char[] params = line[s .. j - 1]; functions ~= convertCppTypes(retTy ~ function ~ params); functions ~= fname; } } } return r ~ shared_mixin(libFile, functions); } /** * Mime on Fire (mime) -- Simple UPnP server for XBOX360 * Copyright (C) 2009 Robert Fraser * * This program is free software; you can redistribute it andor * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ module mime.util.meta; public char[] ctfeItoa(int n) { bool neg = false; char
Re: Automatic translation from .h - .d using nothing but CTFE!
Robert Fraser wrote: [...] BTW, the code is D1+Tango... it shouldn't be overly hard to port, though, since the only part of Tango it uses is tango.sys.SharedLibrary. As for D2, change char[] to string, and all should be good.
Re: runtime vararg can easily be broken
davidl wrote: Also the whole paradigm of coding a runtime vararg func is so troublesome and even much complex compared to the compile time vararg. Maybe we should borrow something from compiletime to aid the runtime vararg programming. Got my vote!
Re: __FUNCTION__ implemented with mixins and mangles
Jarrett Billingsley wrote: It's not foolproof, but I found it useful enough; maybe others will too. // Parsing mangles for fun and profit. char[] _getJustName(char[] mangle) { size_t idx = 1; size_t start = idx; size_t len = 0; while(idx mangle.length mangle[idx] = '0' mangle[idx] = '9') { int size = mangle[idx++] - '0'; while(mangle[idx] = '0' mangle[idx] = '9') size = (size * 10) + (mangle[idx++] - '0'); start = idx; len = size; idx += size; } if(start mangle.length) return mangle[start .. start + len]; else return ; } // Eheheh, I has a __FUNCTION__. const char[] FuncNameMix = static if(!is(typeof(__FUNCTION__))) { struct __FUNCTION {} const char[] __FUNCTION__ = _getJustName(__FUNCTION.mangleof); }; To use, just mix into any function where you want to use __FUNCTION__, and it'll be declared as a const char[]. void forble() { mixin(FuncNameMix); pragma(msg, __FUNCTION__); // shows forble } It doesn't seem to cause any noticeable bloat. The only reference I found to __FUNCTION in an executable compiled with -release was the contents of the FuncNameMix constant itself; I'm sure an enum string in D2 wouldn't be emitted like this. It doesn't work for nested functions, but that's just a little more parsing work. If you want a version that displays the FQN instead of just the function name, I have that too. For those wondering how this works, it's pretty simple: when you declare a type within a function, its mangleof contains the function's name. All the mixin is doing is declaring a type within the function (struct __FUNCTION), then parsing the owning function's name out of the type's mangleof. Awesome, thanks!
Re: D_Version2 problem
David Ferenczi wrote: == Quote from Sergey Gromov (snake.sc...@gmail.com)'s article Sun, 18 Jan 2009 22:28:12 +0100, Hoenir wrote: The D_Version2 version identifier doesn't work properly for me. Tried compiling with dmd 1.039. D_Version2 is set even if I pass -v1 to it. Is this a bug or am I doing something wrong? Works for me. It's hard to tell if you're doing something wrong until you post your test code. 8-- test.d version(D_Version2) { pragma(msg, v2); } else { pragma(msg, v1); } 8-- dmd -c test.d v1 The behaviour is a bit ambigous, since in compile time every version block gets interpreted! So you cannot put D2 only code in the version(D_Version2) {} block, if you want to compile your source with D1. I don't know if it's a bug or a feature. Regards, David This has been discussed many times over. It's a feature according to Walter, and there's some sense to it (since D code is supposed to be parseable without doing semantic analysis, and versions can require arbitrary ammounts of semantic analysis (like CTFE) to determine). If you want to have D2 code you need to use a mixin: version(D_Version2) { mixin(const(char)[] x;); } else { char[] x; } Note that the -v1 switch reverts to the (rather arbitrary) D version 1.00, while new D features were being added through (I think) 1.014.
Re: C#4 Covariance/Contravariance
Lionello Lunesu wrote: bearophile bearophileh...@lycos.com wrote in message news:h0ggl7$60...@digitalmars.com... From the last C#: http://codepad.org/kQgbwAqJ Bye, bearophile Lionello likes this In D if you want to treat a Template!(SomeClass) as a Template!(Object), it's as easy as cast(Template!(Object)) cast(void*) x
Re: C#4 Covariance/Contravariance
bearophile wrote: Robert Fraser: In D if you want to treat a Template!(SomeClass) as a Template!(Object), it's as easy as cast(Template!(Object)) cast(void*) x How is this related to Covariance/Contravariance and in/out keywords, as shown in C#4? Bye, bearophile Errr... isn't that the point of covariance/contravariance?
Re: D Wiki
Jarrett Billingsley wrote: On Tue, Jun 9, 2009 at 10:40 AM, Daniel Keepdaniel.keep.li...@gmail.com wrote: I hate in-browser rich text editors; every single one I've ever used sucked massively. For example, when I was posting on Blogger, I had to write every post manually because their rich text editor was painful and crippled; it wouldn't allow me to do the things I wanted to do. Like use paragraphs. Or insert internal links to footnotes. You know, really bloody basic stuff. Until someone shows me a cross-browser rich text editor that doesn't both blow and suck, I'm sticking to simplified markup; it's the only way I get ANY control whatsoever. QFT Okay, but let's choose a wiki that has an _optional_ rich text editor for those of us who aren't technophobic.
Re: LDC predefined identifiers
Robert Clipsham wrote: Dunno if anyone else thinks this, but the operating system looks very confusing with all the LDC only identifiers mixed in. I think it'd be a good idea to find out which of them are deprecated and remove them, eg only keeping one of either solaris or Solaris etc. Neither side seems to want to budge on this (rather pointless, IMO) matter. LDC chose the identifiers first. Then DMD got support for Solaris, FreeBSD, and OSX, and chose different identifiers. LDC added DMD's but decided not to deprecate their own (probably because they were already in use in Tango). I also wonder why there's a Win32 and a Win64... I don't see a Linux64, so why is Windows so special? I know Win32 has been around in D for a while, but in that case, WIn32 should be defined even on 64-bit Windows targets for compatibility reasons (like %WINDIR%/System32 is kept as System32 even on 64-bit platforms).
Re: Fractal
Frits van Bommel wrote: Fractal wrote: Jarrett Billingsley Wrote: Because those are the three string encodings D supports, and only supporting one is a dumb idea. Why? wchar is full compatible with all languages (if it is not please tell me)... also when I have many strings in different types, I need to convert it from one type to other in each part of the program. Why three when one is suffice? IIRC, Chinese characters can't be represented by a single wchar. However, that's not a problem since all three string types support full Unicode. are all Unicode, just different encodings. However, even if you can throw an exception in Spanish, it might not print out correctly on Windows unless you have your console configured correctly. Oh... I will take a look for that (console configuration)... but the char type dont supports some languages, because it only supports latin... Im wrong? The Exception on the two APIs uses char[]. I want Inernationalized programs. char[] supports any language that wchar[] and dchar[] support. It's just that with char and wchar you need more than one of them for some characters. You may want to read http://prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD and http://en.wikipedia.org/wiki/Unicode (or one of its many translations if your English is not so good). I'd recommend using char[] for everything (unless you're calling Windows API functions, then wchar[] is better). All three can support all characters, so just pick one and roll with it.
Re: Fractal
Fractal wrote: Thanks for the correction... then adding a String struct to simplify it? Fractal Why? char[] _is_ a string. wchar[] and dchar[] are basically there for compatibility with libraries that want them. That being said, tango.text.Text is a string struct of a sort, although it's designed more for representing a large block of text in an editor rather than a single string. There's also mtext ( http://www.dprogramming.com/mtext.php ), though it's unlikely to compile without modification since it's rather old.
Re: Creating a dynamic link library
Fractal wrote: Hello Using Windows, I created a DLL with D, and when I try to create my test executable (also with D), the ImpLib program displays an error saying that there is no any exported function. The DLL source only contains a class with the export attribute like: export class Foo { } And also... the GC can be implemented in the DLL and not in the executable? Thanks DLLs + D basically don't work (they work 100% if either only the host or only the extension is written in D, and then only for free functions with extern(C) linkage). For D-D shared libraries on Windows (which also work on Linux), I'd recommend checking out DDL: Documentation/homepage: http://www.dsource.org/projects/ddl Working code (fork): http://team0xf.com:8080/ext/file/94be291e4d32/ddl/
Re: DMD + nedmalloc?
Brad Roberts wrote: davidl wrote: I will attach a compilable nedmalloc source, corresponding compile batch, and a simple test app. In two post of this thread because of the attachment size limitation of 51k. In the future, please, a website.. or bugzilla, or anything but sending a bunch of big attachments to the newsgroup and mailing list. Later, Brad http://skydrive.live.com/ Free, fast, 2GB, and no wait 60 seconds and watch our advertisement like all the other file storage places.
Re: GIS and D
Sjoerd van Leent wrote: User application - An application with custom windows, dialogs and menus to interact with the GIS database(s) There are like 20 of these for D, most of which work reasonably well. I'd recommend DWT, which is cross-platform, and the newest branch is stable on D1+Tango and experimental on D2+Phobos. D1 still gets bugfixes; it's definitely not a dead language.
Re: Operator overloading, structs
BCS wrote: If you can assume that any FPU will be designed to work with IEEE 754 (would that be valid now days?) Not at all! IIRC, some of the PS2's CPUs don't implement NaN or Infinity (just check out the Advanced page of PCSX2, you can set how accurately the various PS2 CPUs FP operations are emulated on x86). Not sure if the PS2 is now days, but... Also, this is kind of old, but it suggests GPUs have all sorts of different behavior: http://www.cs.unc.edu/~ibr/projects/paranoia/ ... When being used only for graphics, accuracy often isn't as important as speed, however with GPGPU, I wouldn't be surprised if newer GPUs were IEEE-compliant.
Re: Generic Class Alias Syntax
eris wrote: bearophile Wrote: eris: Is there any way to get around including the exclamation point? !(int) tells the template what type is T. Somewhere you have to tell it what type of items you want to put inside it. The alternative is like the old Java, where your collections contain references to Object, used to store wrappers (boxes) like Integer, etc, and you have to cast the items you pull out of them. So I don't understand what you want. (1) Cake (2) Eat it too Sometimes you realize that you don't get to redefine the language syntax. That's a bad, cold, lonely day. :-) bye And then you come across Lisp, and see a glimmer of hope. An hour after that, you decide to hang yourself.
Re: Garbage collection in D
bearophile wrote: Yes, for such tiny benchmarks I have seen several times 10-12 higher allocation performance in Java compared to D1-DMD. But real programs don't use all their time allocating and freeing memory... Bye, bearophile For the compiler I'm working on now (in D), I wanted to check the affects of allocation on performance. Using a placement new, the time for lex/parse/semantic/type-infer/codegen (on a really huge in-memory file) went from ~6 seconds to ~4 seconds (don't have the exact timings, and can't repro right now since I'm redoing inference). So I'd say that even in real-world applications, these things have an effect. Of course, this only applies to programs which allocate and throw away a lot of small objects. This is a style encouraged by Java and C#'s programming models, much less so by, say, C++'s.
Re: [Issue 3050] New: Allow exception in CTFE (patch)
d-bugm...@puremagic.com wrote: http://d.puremagic.com/issues/show_bug.cgi?id=3050 Summary: Allow exception in CTFE (patch) Product: D Version: 2.030 Platform: x86 OS/Version: All Status: NEW Keywords: patch Severity: enhancement Priority: P2 Component: DMD AssignedTo: bugzi...@digitalmars.com ReportedBy: rsi...@gmail.com Created an attachment (id=389) -- (http://d.puremagic.com/issues/attachment.cgi?id=389) Patch (DMD 2.030) The proposed patch implements support for throw/try/catch/finally in CTFE. Throw statement is, however, somewhat limited; new expression is not allowed, except for new Exception(msg). Example and output: int thrower(string s) { // The interpretor emulates throw new Exception(msg) throw new Exception(exception ~ s); return 0; } int catcher() { try { return thrower(abc); } catch (Exception e) { throw e; } return 0; } enum a = catcher(abc); test.d(21): Error: uncaught exception from catcher(): exception abc test.d(21): Error: cannot evaluate catcher() at compile time Since scope() is defined in terms of try/finally, would it be much harder to get scope(success/failure/exit) working in CTFE?
Re: Functions with package protection
grauzone wrote: Sorry to dig up this old post, but I still don't understand why 'package' functions cannot be virtual? Is there a good reason for this? I can't see why we can't use polymorphism on 'package' functions! Is there way to make it virtual without making it public? (e.g. a 'virtual' keyword?) package needs to fixes: - package methods must be allowed to be virtual - package methods must be allowed to be accessed from sub packages (module a.b.x should be able to access package identifiers declared in module a.y) I don't understand why these fixes applied, especially because they are completely backward compatible. package methods must be allowed to be virtual isn't backwards-compatible. This code will work differently if package methods were made virtual: class A { package void foo() { printf(A); } } class B { package void foo() { printf(B); } } void main() { A a = new B(); a.foo(); }
Re: Garbage collection in D
What's the difference between: D 1: 40.20 DMD D 2: 21.83 DMD D 2: 18.80 DMD, struct + scope and: D 1: 8.47 DMD D 2: 7.41 DMD + scope ...?
Re: Garbage collection in D
Sam Hu wrote: bearophile Wrote: I have tried the new JavaVM on Win, that optionally performs escape analysis, and the results are nice: Timings, N=100_000_000, Windows, seconds: D 1: 40.20 DMD D 2: 21.83 DMD D 2: 18.80 DMD, struct + scope C++: 18.06 D 1: 8.47 DMD D 2: 7.41 DMD + scope Java: 1.84 V.1.6.0_14, -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC Java 1.78 -server Java: 1.44 Java: 1.38 V.1.6.0_14 Java: 0.28 V.1.6.0_14, -server -XX:+DoEscapeAnalysis Timings, N=100_000_000, Pubuntu, seconds: D 1: 25.7 LDC C++: 6.87 D 1: 2.67 LDC + scope Java: 1.49 Bye, bearophile Sorry for my stepping in... What does this result mean?Does it mean D is slower than Java and C++ is also slower than Java?Or that's true just under certain circumstance? I am really confused and really appreicate if any further explanation. Regards, Sam It suggests that for dynamic allocation of many small objects via new, Java is an order of magnitude faster than C++, which in turn is slightly faster than D.
Re: Source control for all dmd source (Git propaganda =)
Vladimir Panteleev wrote: On Tue, 02 Jun 2009 22:29:28 +0300, Jérôme M. Berger jeber...@free.fr wrote: Leandro Lucarella wrote: You have a good command-line support. Maybe you do, but that's not the impression the Git fans here were giving: - Robert Fraser on win32 support: git's Win32 support via TortoiseGit is nearly as good as SVN's now - All the discussion between BCS, hasen and Daniel Keep on tortoise git. I don't get it - how can you assume that just because people say that git has a good GUI for Windows (TortoiseGit), it doesn't have a decent command-line version? Making a port of the command-line version is much easier that creating a Win32 GUI. Like someone else mentioned in this thread - git's Win32 command-line support is now on par with Linux, and it doesn't require you to install cygwin or use a separate shell (bash). FWIW, TortoiseGit is leagues better than TortoiseHg (TortoiseHg doesn't even work on 64-bit Windows), and there are fairly complete command-line ports of both.
Re: visualization of language benchmarks
Jérôme M. Berger wrote: Nick Sabalausky wrote: Denis Koroskin 2kor...@gmail.com wrote in message news:op.uuthxivwo7c...@soldat.creatstudio.intranet... On Mon, 01 Jun 2009 03:21:42 +0400, Tim Matthews tim.matthe...@gmail.com wrote: Knud Soerensen wrote: Tim Matthews wrote: It's things like this that make me want to get into visualization. Great article! Where's the D It is on 3,3 called Dlang. OK it is was on the 05 chart but I was expecting it to be on the updated 09 chart though. They seem to believe D is less of a player now. IIRC, there was no stable 64bit D compiler for Linux at the moment they moved to new hardware and thus D support was dropped. So they're benchmarks are only accurate for 64-bit? The shootout have 32-bit and 64-bit versions of the benchmarks, but they wanted to have the same benchmarks on both architectures. I don't know which version was used to generate the charts though. Jerome Well now that LDC supports 64-bit, could we convince them to put it back in?
Re: Source control for all dmd source (Git propaganda =)
Jérôme M. Berger wrote: - Here's the same for Mozilla: http://weblogs.mozillazine.org/preed/2007/04/version_control_system_shootou_1.html From the article: While they've made recent progress, Git was lacking in Win32 support and it was unclear that this would ever change and if it did change, it was unclear that Git-on-Win32 would ever become something more than a second-class citizen. As good, performant Win32 (and Mac and Linux) is a hard-requirement, Git lost in early Kombat rounds. This is unfortunate because (as we would soon find out), lots of issues with the other systems did just work in Git. git's Win32 support via TortoiseGit is nearly as good as SVN's now, so I can't see that being an issue here. So I'd say Git is a great choice for the DMDFE.
Re: legal identifier check
BCS wrote: Hello Saaa, You have to write it yourself. Here's a good starting point: http://www.digitalmars.com/d/1.0/lex.html#identifier Yes, that was my starting point and it seemed quite complex, thus my question :) I think I'll stay with my simple check for now as it isn't really necessary to be as strict as D's identifiers. Just thought that if there was an easy check I'd implement that. Thanks anyways everybody. if you are only working with ASCII: use the regex `_A-Za-z[_A-Za-z0-9]*` Isn't there an isUniAlpha function in both Phoboses and in Tango?
Re: the semi-resident thread pool
zsxxsz wrote: Hi, I written one thread pool in which each thread is semi-resident. The thread-pool is different from the Tango's one. Any thread of the thread-pool will exit when it is idle for the timeout. That is to say, all threads for jobs, and no job no thread. The thread-pool was from my C version. With D, I wrote it more easier with the delegate function. Below is the source code: module adl.thread_pool; import core.sys.posix.pthread; // just for pthread_self() import core.thread; import core.sync.mutex; import core.sync.condition; import std.c.time; private struct Job { Job *next; void function() fn; void delegate() dg; void *arg; int call; } /** * semi-daemon thread of thread pool */ class CThreadPool { public: /** * Constructs a CThreadPool * @param nMaxThread {int} the max number threads in thread pool * @param idleTimeout {int} when 0, the idle thread will * exit after idleTimeout seconds, if == 0, the idle thread * will not exit * @param sz {size_t} when 0, the thread will be created which * stack size is sz. */ this(int nMaxThread, int idleTimeout, size_t sz = 0) { m_nMaxThread = nMaxThread; m_idleTimeout = idleTimeout; m_stackSize = sz; m_mutex = new Mutex; m_cond = new Condition(m_mutex); } /** * Append one task into the thread pool's task queue * @param fn {void function()} */ void append(void function() fn) { Job *job; char buf[256]; if (fn == null) throw new Exception(fn null); job = new Job; job.fn = fn; job.next = null; job.call = Call.FN; m_mutex.lock(); append(job); m_mutex.unlock(); } /** * Append one task into the thread pool's task queue * @param dg {void delegate()} */ void append(void delegate() dg) { Job *job; char buf[256]; if (dg == null) throw new Exception(dg null); job = new Job; job.dg = dg; job.next = null; job.call = Call.DG; m_mutex.lock(); append(job); m_mutex.unlock(); } /** * If dg not null, when one new thread is created, dg will be called. * @param dg {void delegate()} */ void onThreadInit(void delegate() dg) { m_onThreadInit = dg; } /** * If dg not null, before one thread exits, db will be called. * @param dg {void delegate()} */ void onThreadExit(void delegate() dg) { m_onThreadExit = dg; } private: enum Call { NO, FN, DG } Mutex m_mutex; Condition m_cond; size_t m_stackSize = 0; Job* m_jobHead = null, m_jobTail = null; int m_nJob = 0; bool m_isQuit = false; int m_nThread = 0; int m_nMaxThread; int m_nIdleThread = 0; int m_overloadTimeWait = 0; int m_idleTimeout; time_t m_lastWarn; void delegate() m_onThreadInit; void delegate() m_onThreadExit; void append(Job *job) { if (m_jobHead == null) m_jobHead = job; else m_jobTail.next = job; m_jobTail = job; m_nJob++; if (m_nIdleThread 0) { m_cond.notify(); } else if (m_nThread m_nMaxThread) { Thread thread = new Thread(doJob); thread.isDaemon = true; thread.start(); m_nThread++; } else if (m_nJob 10 * m_nMaxThread) { time_t now = time(null); if (now - m_lastWarn = 2) { m_lastWarn = now; } if (m_overloadTimeWait 0) { Thread.sleep(m_overloadTimeWait); } } } void doJob() { Job *job; int status; bool timedout; long period = m_idleTimeout * 10_000_000; if (m_onThreadInit != null) m_onThreadInit(); m_mutex.lock(); for (;;) { timedout = false; while (m_jobHead == null !m_isQuit) { m_nIdleThread++;
Re: Cuda for C++
Trass3r wrote: bearophile schrieb: Thrust is a CUDA library of parallel algorithms with an interface resembling the C++ Standard Template Library (STL). Thrust provides a flexible high-level interface for GPU programming: http://code.google.com/p/thrust/ Something like this (but OpenCL) for D sounds quite interesting. Hopefully OpenCL's runtime will be compatible to D's: Chris R Miller wrote (in Feb): I looked into writing CUDA with D a while back. The problem is that the CUDA C runtime and the D runtime are 100% incompatible. I don't have any new information about the topic though. Maybe it works with druntime. Isn't there a dcuda project at team0xf? Not sure what state it's in, though. I'd say OpenCL/DirectX Compute Shaders are the future... CUDA is only supported on NVIDIA, and as a proud ATI user, I must take exception.
Re: ldc 0.9.1 released
Walter Bright wrote: The D compiler source doesn't use any templates, rtti, or clever macro hacks. Whether it's well designed or not, I'll let others decide. It is written in a D-ish style. I ported part of the DMDFE to Java, and found it quite well-designed (with the exception of the frequent use of globals). The gotos make it more readable IMO (compare the original to the Java version where gotos are replaced with exceptions, replaced with duplicated code, emulated with a bunch of booleans, or refactored into separate functions taking 7+ arguments). However, the DMDFE's organization relies on being able to declare class member functions separately from where they're defined, which is impossible in D (hint, hint, nudge, nudge).
Re: static this sucks, we should deprecate it
BCS wrote: Hello Steven, On Thu, 28 May 2009 11:39:28 -0400, Matti Niemenmaa see_signat...@for.real.address wrote: Steven Schveighoffer wrote: If we were importing compiled files (or even generated files), then the compiled file could have annotated the static this with the dependencies it has... I don't want to start another long thread on this, I understand Walter's I want to use standard linkers position. I don't think that's an argument against this; you can always compile both an intermediate representation for purposes such as these in addition to the standard object file. It's what the Haskell compiler GHC does, for instance. As long as it's part of a system where you can't accidentally use stale files, then I'd agree. The best scenario would be to import the object file directly IMO. How about serialized the AST that goes into a .di file into a special section of he object file and then suck it back in for imports? (BTW this is a solution I can live with. :) vote -= pow(MATH_E, 1.0i * MATH_PI);
Re: [OT] Convention of Communication
Nick Sabalausky wrote: Frits van Bommel fvbom...@remwovexcapss.nl wrote in message news:gvlsjc$188...@digitalmars.com... Denis Koroskin wrote: FWIW, NNTP (which is used in newsgroups like this) falls into Usenet category: Wikipedia quote (http://en.wikipedia.org/wiki/Usenet#Technical_details): On the Internet, Usenet is typically served via NNTP ... Just because NNTP is used for Usenet doesn't mean every NNTP server is a Usenet server. Similarly, not every TCP/IP network is the Internet and not every car is the one I drove to the supermarket last week :P. WiFi available here! [pet peeve]Not every WiFi network is conected to the internet[/pet peeve] One day I would like to walk into a coffee shop my laptop, connect to Wi-Fi and be able to only explore the cafe's intranet.
Re: static this sucks, we should deprecate it
Steven Schveighoffer wrote: On Thu, 28 May 2009 08:14:45 -0400, Frank Benoit keinfarb...@googlemail.com wrote: Unknown W. Brackets schrieb: Probably a silly idea, but what about (or similar): static this: mod.name, mod.name2, mod.name3 { } For a dependency list. I may be wrong, but afaik the main problems stem from either wrong order or co-dependence (which needs to be solved by the programmer.) At least with this, you could ask the compiler for an order, potentially. If the other modules had no static this, it could ignore it, allowing future proofing. But, maybe that's an ugly hack. -[Unknown] In Java the static { /* static ctor code */ } does not have the circular dependency problem. why is that? Probably because Java doesn't use source code as imports. It is one flaw of D that I really wish could be fixed. -Steve That's not strictly true; a .java file is the compilation unit, which can contain any number of classes (only one public, but any # of inner/package-protected ones).
Re: static this sucks, we should deprecate it
Unknown W. Brackets wrote: Because you've never tried to use data initialized circularly. I wonder what would happen in Java if you did? -[Unknown] Frank Benoit wrote: Unknown W. Brackets schrieb: Probably a silly idea, but what about (or similar): static this: mod.name, mod.name2, mod.name3 { } For a dependency list. I may be wrong, but afaik the main problems stem from either wrong order or co-dependence (which needs to be solved by the programmer.) At least with this, you could ask the compiler for an order, potentially. If the other modules had no static this, it could ignore it, allowing future proofing. But, maybe that's an ugly hack. -[Unknown] In Java the static { /* static ctor code */ } does not have the circular dependency problem. why is that? It gives a compile-time error message.
Re: Encoding problems...
grauzone wrote: Robert Fraser wrote: Jarrett Billingsley wrote: On Wed, May 27, 2009 at 8:55 PM, Robert Fraser fraseroftheni...@gmail.com wrote: Hi all, Quick question: I want to use some unicode identifiers, but I get unsupported char 0xe2, both with using and not using a BOM. The characters in question are the superset/subset-equals operators: ⊇ and ⊆... Perhaps these are just unsupported by DMD (in which case, I'll file a bug)? Thanks, Robert If they're not classified as universal alpha I don't think you can use them in identifiers. How the hell did your news client switch from UTF-8 to Japanese-something? (charset=UTF-8 = charset=ISO-2022-JP) Lame. K; thanks. Don't worry, people working with your code will be thankful! Hmm... I'd say x.⊆(y) is preferable x.isSubsetOf(y), but it's not a huge deal.
Re: Encoding problems...
BCS wrote: Reply to Robert, Hmm... I'd say x.⊆(y) is preferable x.isSubsetOf(y), but it's not a huge deal. Only until you have to type it. I think universal alpha includes only the union of things that can be easily typed on standard keyboards. I don't think any keyboard (ok maybe an APL keyboard) has the subset symbol on it. I have 10 configurable keys on my keyboard, none of which are in use. I could also remap my numpad (cause, seriously, who uses this?) Also, many editors can be configured so that a sequence of characters converts to a single one. There appears to be no reason that mathematical symbols aren't allowed in identifiers... Think of how awesome it would be to write assert(x⊇y→∀a∈x∃b∈y(a⊇b)) ... Okay, that would require overloading of those operators (and instantiating variables in a new way), but still!
Re: Encoding problems...
Jarrett Billingsley wrote: On Wed, May 27, 2009 at 8:55 PM, Robert Fraser fraseroftheni...@gmail.com wrote: Hi all, Quick question: I want to use some unicode identifiers, but I get unsupported char 0xe2, both with using and not using a BOM. The characters in question are the superset/subset-equals operators: ⊇ and ⊆... Perhaps these are just unsupported by DMD (in which case, I'll file a bug)? Thanks, Robert If they're not classified as universal alpha I don't think you can use them in identifiers. Lame. K; thanks.
[OT] Language design question
Hey all, Without revealing too much I'm currently working on a programming language for a research project (it's implemented in D, of course!). I'm trying to figure out a good syntax for type annotations. I realized that under my current scheme the fun keyword in my language now serves three purposes: - syntax sugar for declaring a function - a type annotation for a function - introducing a literal function/lambda So a lazy evaluation/application could be written something like: fun fun $a() lazyApply(fun $a($b) f, $b x) = fun $a() = f(x); Where the first fun starts a function declaration, the next two indicate function types, and the last one indicates a lambda expression. This, if you'll forgive the pun, might not be so fun. Of course, since the language supports type inference, it could be written more simply as one of: fun lazyApply(f, x) = fun() = f(x); fun lazyApply(f, x) = f@(x); (All are equavalent to the D2 closure function: T delegate() lazyApply(t, U)(T delegate(U) f, U x) { return T() { return f(x); } } ) What do you think of this? Do I need to find a different syntax? Some other possible syntaxes I thought of (where x, y, and z are types) {y, z - x} {(y, z) - x} 'x(y, z) \x(y, z) (Might be confusing since \ introduces lambda expressions in other languages) Which would make the above monstrosity look like: fun {- $a} lazyApply({$b - $a} f, $b x) = fun {- $a} = f(x); fun {() - $a} lazyApply({($b) - $a} f, $b x) = fun {() - $a} = f(x); fun '$a() lazyApply('$a($b) f, $b x) = fun '$a() = f(x); fun \$a() lazyApply(\$a($b) f, $b x) = fun \$a() = f(x); The short versions would remain the same in all cases: fun lazyApply(f, x) = fun() = f(x); fun lazyApply(f, x) = f@(x); Any thoughts/suggestions? Thanks, Robert
Re: [OT] Language design question
Robert Fraser wrote: fun fun $a() lazyApply(fun $a($b) f, $b x) = fun $a() = f(x); And don't forget to take your fun fun (a banger in the mouth if you get the reference :-)).
Re: Taunting
Nick Sabalausky wrote: Saaa em...@needmail.com wrote in message news:gv6qcj$2ck...@digitalmars.com... If I could get that in a super fast, light programming editor, I'd use that instead. But I can't. Wasn't there an effort somewhere to port eclipse to D ? I have no idea, but that does raise an interesting question (maybe one of our resident Eclipse experts can answer it?): If it were ported to D, would that really improve the speed/resource-usage? From various things I've heard, I fear the answer may be only a little bit and that it would still need a bunch of extra optimizations (Although despite claims of Java being fast, I would think it still has a big limit in that there's a lot of optimizations that just simply can't be done without a systems language like D). A direct port of Eclipse to D I would guess to be much SLOWER. Eclipse relies *heavily* on inheritance (Java can inline virtual calls; D can't) and allocating many small objects (something D tests badly in, and Java is particularly well-suited for). There's also a lot of static initialization that would need to be converted to static this() in D. However, in Java, the static stuff is initialized lazily at the first time it's used, while in D, it's all run at startup, even if only 1/5th of it is going to be used. If the codebase were D-ized, it's possible that native code optimizations make it slightly faster (though the shootout shows Java performing nearly as well as C/C++/D for many tasks).
Re: OT: Flash (Was: Re: Taunting)
Daniel Keep wrote: The only way Flash will die if if at least the following happen: ... 5. Silverlight replaces it (and then we're all doomed).
Re: Descent 0.5.5 released
Saaa wrote: Is the executable name any of bud or bud.exe? I think that's what the process name is for Eclipse, and the links are associated to the process name (not to the name you choose for the external tool). :) May I suggest adjusting the filter to bud*.exe or add a note on dsource as I sometimes append the version to the filename. The method I'm using is a really weird hack where the executable names are hardcoded in the plugin.xml and there's no way to filter based on anything but absolute strings. I may need to implement a different type of external tool that adds links... I'll ask in the eclipse NG.
Re: why allocation of large amount of small objects so slow (x10) in D?
nobody wrote: $ g++ alloc.cpp -o alloc $ time ./alloc real0m1.946s user0m1.688s sys 0m0.256s $ dmd -O -release allocd.d $ time ./allocd real0m22.734s user0m22.353s sys 0m0.360s $ cat alloc.cpp #include vector typedef std::vectorint intvec; typedef intvec* intvecp; int main() { int i, n = 2000; intvecp* iva; iva = new intvecp[n]; for (i = n; i-- 0; ) { iva[i] = new intvec(); } return 0; } $ cat allocd.d int main() { int i, n = 2000; Object[] oa; oa = new Object[n]; for (i = n; i-- 0; ) { oa[i] = new Object(); } return 0; } I use this a structure for arena-based memory allocation (attached). Example of use: import candy.util.MemPool MemStack!() stack; class MyObject { mixin MemPoolNew!(stack); } int main() { stack.push(); int i, n = 2000; MyObject[] oa; oa = new MyObject[n]; for (i = n; i-- 0; ) { oa[i] = new MyObject(); } stack.pop(); return 0; } The push() and pop() allows memory to be allocated and deallocated as large blocks. However, you shouldn't need to deallocate manually -- it's GCed memory, so ideally the GC should free it when it's no longer referenced. That being said, I've run some tests, and the GC will free it *eventually*, but it allocates 4-6x as much memory as it needs before it starts freeing it, even when GC.collect() is called manually. /** * Provides a pool of GCed memory to allocate things from a block. * This maintains cache coherency for related types (i.e. tree nodes). * It doesn't garuntee any ordering, though, the array struct should be * used for that. Also, everything has to be freed at once, freeing one * portion of this has no effect. * * Based on a similar concept posted by bearophile at: * http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=88227 */ public struct MemPool(size_t BLOCK_SIZE = 1 14) { private void* next; // Next available block private void* end; // End of the current block private void*[] blocks; public void* alloc(size_t sz) { sz = ((sz + 7) ~7); // Next multiple of 8 if this isn't a multiple of 8 if (this.next + sz = this.end) { void* blk = GC.calloc(BLOCK_SIZE); this.blocks.length = this.blocks.length + 1; this.blocks[$ - 1] = blk; this.next = blk; this.end = blk + BLOCK_SIZE; } void* ret = this.next; this.next += sz; return ret; } public void free() { foreach(blk; this.blocks) GC.free(blk); this.blocks = null; this.blocks.length = 0; this.next = null; this.end = null; } } /** * Wrapper for MemPool that allocates the given struct */ public struct StructPool(T) { private MemPool!() pool; public T* alloc() { return cast(T*) pool.alloc(T.sizeof); } } public struct MemStack(size_t BLOCK_SIZE = 1 14) { private Stack!(MemPool!(BLOCK_SIZE)*, 16, true, true) stack; public static const size_t MAX_ALLOC = BLOCK_SIZE; public void* alloc(size_t sz) { return stack.peek().alloc(sz); } public void push() { stack.push(new MemPool!(BLOCK_SIZE)); } public void pop(){ stack.pop().free(); } } /** * Placement new mixin for allocating from a memory pool. Benchmarks show this * as faster than the D new in real usage (i.e. the parser runs about 1.2x * faster using this). */ public template MemPoolNew(alias Pool) { version(NoMemPool) { } else { public final new(uint sz){ return Pool.alloc(sz); } public final delete(void *p) {} } }
Re: why allocation of large amount of small objects so slow (x10) in D?
Robert Fraser wrote: nobody wrote: $ g++ alloc.cpp -o alloc $ time ./alloc real0m1.946s user0m1.688s sys 0m0.256s $ dmd -O -release allocd.d $ time ./allocd real0m22.734s user0m22.353s sys 0m0.360s $ cat alloc.cpp #include vector typedef std::vectorint intvec; typedef intvec* intvecp; int main() { int i, n = 2000; intvecp* iva; iva = new intvecp[n]; for (i = n; i-- 0; ) { iva[i] = new intvec(); } return 0; } $ cat allocd.d int main() { int i, n = 2000; Object[] oa; oa = new Object[n]; for (i = n; i-- 0; ) { oa[i] = new Object(); } return 0; } I use this a structure for arena-based memory allocation (attached). Example of use: import candy.util.MemPool MemStack!() stack; class MyObject { mixin MemPoolNew!(stack); } int main() { stack.push(); int i, n = 2000; MyObject[] oa; oa = new MyObject[n]; for (i = n; i-- 0; ) { oa[i] = new MyObject(); } stack.pop(); return 0; } The push() and pop() allows memory to be allocated and deallocated as large blocks. However, you shouldn't need to deallocate manually -- it's GCed memory, so ideally the GC should free it when it's no longer referenced. That being said, I've run some tests, and the GC will free it *eventually*, but it allocates 4-6x as much memory as it needs before it starts freeing it, even when GC.collect() is called manually. /** * Provides a pool of GCed memory to allocate things from a block. * This maintains cache coherency for related types (i.e. tree nodes). * It doesn't garuntee any ordering, though, the array struct should be * used for that. Also, everything has to be freed at once, freeing one * portion of this has no effect. * * Based on a similar concept posted by bearophile at: * http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=88227 */ public struct MemPool(size_t BLOCK_SIZE = 1 14) { private void* next; // Next available block private void* end; // End of the current block private void*[] blocks; public void* alloc(size_t sz) { sz = ((sz + 7) ~7); // Next multiple of 8 if this isn't a multiple of 8 if (this.next + sz = this.end) { void* blk = GC.calloc(BLOCK_SIZE); this.blocks.length = this.blocks.length + 1; this.blocks[$ - 1] = blk; this.next = blk; this.end = blk + BLOCK_SIZE; } void* ret = this.next; this.next += sz; return ret; } public void free() { foreach(blk; this.blocks) GC.free(blk); this.blocks = null; this.blocks.length = 0; this.next = null; this.end = null; } } /** * Wrapper for MemPool that allocates the given struct */ public struct StructPool(T) { private MemPool!() pool; public T* alloc() { return cast(T*) pool.alloc(T.sizeof); } } public struct MemStack(size_t BLOCK_SIZE = 1 14) { private Stack!(MemPool!(BLOCK_SIZE)*, 16, true, true) stack; public static const size_t MAX_ALLOC = BLOCK_SIZE; public void* alloc(size_t sz) { return stack.peek().alloc(sz); } public void push() { stack.push(new MemPool!(BLOCK_SIZE)); } public void pop(){ stack.pop().free(); } } /** * Placement new mixin for allocating from a memory pool. Benchmarks show this * as faster than the D new in real usage (i.e. the parser runs about 1.2x * faster using this). */ public template MemPoolNew(alias Pool) { version(NoMemPool) { } else { public final new(uint sz){ return Pool.alloc(sz); } public final delete(void *p) {} } } Oops, that needs another module. Okay, both are attached in a compile-able form. /*** * Copyright (c) 2008-2009 Robert Fraser * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html ***/ module candy.util.memory; import tango.core.Memory : GC; import candy.util.array; /** * Provides a pool of GCed memory to allocate things from a block. * This maintains cache coherency for related types (i.e. tree nodes). * It doesn't garuntee any ordering, though, the array struct should be * used for that. Also, everything has to be freed at once, freeing one * portion of this has no effect. * * Based on a similar concept posted by bearophile at: * http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=88227 */ public struct MemPool(size_t BLOCK_SIZE = 1 14) { private void
Re: Class allocation from tuple
bearophile wrote: I have a tuple of classes (D1 language), I'd like to instantiate one of them directly with new, but it seems I can't: template Tuple(T...) { alias T Tuple; } class Foo { static void foo(){} } class Bar {} alias Tuple!(Foo, Bar) ClassTuple; void main() { alias ClassTuple[0] Foo0; new Foo0; // OK ClassTuple[0].foo(); // OK new ClassTuple[0]; // Not OK new (ClassTuple[0]); // Not OK } Can you tell me what the problem is? Thank you and bye, bearophile alias
Re: the last change for ranges
dsimcha wrote: Also, while we're fine tuning input ranges vs. forward ranges, I think the concept of iterables as a catch-all for ranges, opApply, builtins, etc. needs to be introduced and fine tuned, too. We've shown on this NG previously that, while ranges are usually preferable for the flexibility they offer, opApply does have its legitimate use cases. An input/forward range is basically just another name/syntax for an iterable. Perhaps algorithms that work on input ranges should be written using foreach instead of front/popFront?
Re: the last change for ranges
Andrei Alexandrescu wrote: struct R { bool empty(); ref int front(); void popFront(); } ref int popNext(ref R fwdRange) { auto result = fwdRange.front(); fwdRange.popFront; return *result; } void main() { R r; int x = r.popNext; } This should work, I just noticed with surprise it doesn't. It's a bug, specifically bug 3015: http://d.puremagic.com/issues/show_bug.cgi?id=3015 Yes. Oh yes. YES!!!
Re: any html parser with d binding
reimi gibbons wrote: 2) how reliable is bcd to create binding for c libraries? C? Very reliable (unless it uses weird compiler directives). C++ is a bit trickier.
Re: with still sucks + removing features + adding features
Frank Benoit wrote: Alexander Pánek schrieb: Andrei Alexandrescu wrote: bearophile wrote: Andrei Alexandrescu: Thank you for bringing a real example that gives something to work on. Awful! Well, one of your cases was wrong. Using the +1 at the end one of those cases become: case 'A' .. 'Z'+1, 'a' .. 'z'+1: Instead of what you have written: case 'A' .. 'Z'+1: case 'a' .. 'z'+1: I agree that that syntax with +1 isn't very nice looking. But the advantage of +1 is that it introduces (almost) no new syntax, it's not easy to miss, its meaning is easy to understand. AND you don't have to remember that in a case the .. is inclusive while in foreach is exclusive on the right, keeping the standard way in D to denote ranges. You don't understand. My point is not that people will dislike 'Z'+1. They will FORGET TO WRITE THE BLESSED +1. They'll write: case 'A' .. 'Z': You know, Ruby solves this by introducing a “seperate” range syntax for exclusive ranges: “...”. An inclusive range is written the same as an exclusive range in D: “..”. a[1 .. 2].length #= 1 ([a[1]]) a[1 ... 2].length #= 2 ([a[1], a[2]]) I see no reason not to include such a seperate syntax in D. “..” being exclusive and “...” being inclusive, not the other way round as in Ruby — see “Programmer’s Paradox” @ http://www.programmersparadox.com/2009/01/11/ruby-range-mnemonic/ . Kind regards, Alex Yes, this is useful for all use cases of ranges. I like '...'. Indeed it's not a bad idea... But it might be easily mistyped, lead to strange off-by-one errors and be very difficult to find while debugging them. Hmmm...
Re: with still sucks + removing features + adding features
Andrei Alexandrescu wrote: Let me add one more, although more than sure someone will find a remedy for it, too. a...b vs. a.. .b and of course the beauty ab Oh, and this speaks more about the .b syntax than anything else. Does anyone actually use this...? If it was removed, b could still be accessed by its fully-qualified name, so its' removal not a huge loss.
Re: with still sucks + removing features + adding features
Ary Borenszweig wrote: Oh, and this speaks more about the .b syntax than anything else. Does anyone actually use this...? If it was removed, b could still be accessed by its fully-qualified name, so its' removal not a huge loss. But that will make porting C code harder Guess who'll say that. ;-) ??? C allows .x to access a global member? You learn something useless every day...