Re: Going to ACCU next week
On 10/04/2010 18:55, Walter Bright wrote: with Andrei to do a full day D tutorial. I'm not sure how connected I'll be with email and stuff. http://accu.org/index.php/conferences Hum, I read last weekend the ACCU booklet they gave with all the descriptions of the conferences, started to feel a bit more disheartened that I wouldn't stay for the whole conference, they had some pretty interesting talks! No regrets though, and there's always next year. But anyways, it was nice meeting you guys, Walter and Andrei, and maybe next time you are here in Europe we'll meet again, and maybe can garner a few more D enthusiasts from the community. :P -- Bruno Medeiros - Software Engineer
Re: Going to ACCU next week
Bruno Medeiros wrote: On 10/04/2010 18:55, Walter Bright wrote: with Andrei to do a full day D tutorial. I'm not sure how connected I'll be with email and stuff. http://accu.org/index.php/conferences Hum, I read last weekend the ACCU booklet they gave with all the descriptions of the conferences, started to feel a bit more disheartened that I wouldn't stay for the whole conference, they had some pretty interesting talks! No regrets though, and there's always next year. But anyways, it was nice meeting you guys, Walter and Andrei, and maybe next time you are here in Europe we'll meet again, and maybe can garner a few more D enthusiasts from the community. :P Yes, it was great meeting you in 3D land!
Re: JavaScript is the VM to target for D
Nick Sabalausky: Does that answer your question? Yes, thank you, bearophile
Re: D FTP Library
On 4/21/10 03:39, Mengu Kagan wrote: Hi, Is there an FTP library that I can use with D? If not, how can I build one? Since I'm a beginner, please guide my way. Thanks in advance. If nothing has changed Tango has an FTP module. It's quite low level compared to how it used to look.
DMD crash! and JSON files
I just installed VisualD and enabled JSON output on my project and to my delight F12 took me to my own symbols. Yay. Next, I thought it would be grand if I could jump around phobos/druntime code the same way so I went looking for JSON files for these. Sadly, they're not included in the DMD release zip. Not to be foiled so easily I figured I'd try my hand at building druntime and phobos. So.. attempt #1, the naive approach. I cracked open the win32.mak files for each and added -X to DFLAGS. For druntime... I did a make -fwin32.mak clean then make -fwin32.mak only to get: Target 'target' is up to date It seems that 'clean' doesn't clean everything, it gave an error: The system cannot find the file specified. for one of the myriad files included in the del command. I modified win32.mak for druntime to perform a seperate del command for each item, eg. clean: del $(DOCS) del $(IMPORTS) del $(DRUNTIME) del $(OBJS_TO_DELETE) del $(GCSTUB) this isn't perfect as I suspect if any file in any of those lists is missing the delete will stop dead, but this does at least clean enough to get me going again. ** (Walter, might be worth making a similar change to the master copy?) I then repeated the make steps and managed to produce a druntime.lib plus these JSON file.. bitop.json gcstub.json that's less than I was expecting.. is this because the dmd command to build druntime.lib is a -lib and -X is not compatible/meaningful with it? Ignoring that for now I moved on to phobos itself... make -fwin32.mak clean worked, but make -fwin32.mak failed until I added: -...@p%\..\..\src\druntime\src to my sc.ini ** (Walter, should that be there by default? .. perhaps not as you only need it to rebuild phobos and most ppl don't do that). Now make -fwin32.mak gets as far as the big dmd -lib command but this time it crashes ***! I do however have a few JSON files from the make: c_stdio.json Czlib.json Dzlib.json oldsyserror.json It seems I am going to need to get smarter with the makefiles, instead of attempting to piggy-back the lib build process I should build each file seperately to produce a JSON...
Re: D FTP Library
On 4/20/2010 9:48 PM, davidl wrote: ?? Wed, 21 Apr 2010 09:39:05 +0800??Mengu Kagan whalb...@gmail.com : Hi, Is there an FTP library that I can use with D? If not, how can I build one? Since I'm a beginner, please guide my way. Thanks in advance. Don't use FTP for any serious purpose. There's *NONE* stable and robust FTP implementation in any other languages. I don't expect any in D either. And FTP is plain old protocol, it should be abandoned because it's not expressive and not standardized. It's only designed for text client honestly. Regards, DavidL It's worth asking what he's using it for first. Maybe he's writing an ftp client for fun, or working with a server or web service he doesn't control that can only be accessed via ftp?
Re: DMD crash! and JSON files
Regan Heath wrote: I just installed VisualD and enabled JSON output on my project and to my delight F12 took me to my own symbols. Yay. Next, I thought it would be grand if I could jump around phobos/druntime code the same way so I went looking for JSON files for these. Sadly, they're not included in the DMD release zip. Not to be foiled so easily I figured I'd try my hand at building druntime and phobos. [snip] Now make -fwin32.mak gets as far as the big dmd -lib command but this time it crashes ***! bug 4809 ? BTW, I don't need to modify paths in order to build on Windows (except note that you need to touch druntime/minit.obj because of a problem with the download). So you shouldn't need to modify sc.ini.
Re: DMD crash! and JSON files
Don wrote: Regan Heath wrote: [snip] Now make -fwin32.mak gets as far as the big dmd -lib command but this time it crashes ***! bug 4809 ? You need the patches to bugs #4089 and #3415 to create sensible JSON output. I just added another diff to #4089 for an issue that I hit recently. With these patches to DMD, I used JSON output for druntime and phobos successfully. But it would be nice if these would be part of the DMD distribution, so you don't need to build them manually first. The installer for Visual D could then automatically configure them for lookup. Before letting the IDE dive deep into semantic analysis, my current plan is to use the information found in the json files for parameter info tooltips aswell. For this, pre-installed files would be really convenient.
Remove real type
I suggest to remove the real type from D2 because: - It's the only native type that has not specified length. I'm sold on the usefulness of having defined length types. Unspecified length types causes some of the troubles caused by C types that D has tried to avoid defining the size of its integral types. - Its length is variable across operating systems, it can be 10, 12, 16 bytes, or even just 8 if they get implemented with doubles. The 12 and 16 bytes long waste space. - Results that you can find with programs written in other languages are usually computed with just floats or doubles. If I want to test if a D program gives the same results I can't use reals in D. - I don't see reals (long doubles in C) used much in other languages. - If I compile a program with LDC that performs computations on FP values, and I take a look at the asm it produces, I can see onl SSE-related instructions. And SSE registers allow for 32 and 64 bit FP only. I think future AVX extensions too don't support 79/80 bit floats. GPUs are increasingly used to perform computations, and they don't support 80 bit floats. So I think they are going to be obsolete. Five or ten years from now most numerical programs will probably not use 80 bit FP. - Removing a built-in type makes the language and its manual a little simpler. - I have used D1 for some time, but so far I have had hard time to find a purpose for 80 bit FP numbers. The slight increase in precision is not so useful. - D implementations are free to use doubles to implement the real type. So in a D program I can't rely on their little extra precision, making them not so useful. - While I think the 80 bit FP are not so useful, I think Quadrupe precision FP (128 bit, currently usually software-implemented) can be useful for some situations, (http://en.wikipedia.org/wiki/Quadruple_precision ). They might be useful for High dynamic range imaging too. LLVM SPARC V9 will support its quad-precision registers. - The D2 specs say real is the largest hardware implemented floating point size, this means that they can be 128 bit too in future. A numerical simulation that is designed to work with 80 bit FP numbers (or 64 bit FP numbers) can give strange results with 128 bit precision. So I suggest to remove the real type; or eventually replace it with fixed-sized 128 bit floating-point type with the same name (implemented using a software emulation where the hardware doesn't have them, like the __float128 of GCC: http://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html ). In far future, if the hardware of CPUs will support FP numbers larger than 128 bits, a larger type can be added if necessary. Bye, bearophile
Re: Remove real type
I don't find it that useful either. Seems to me the only use is to preserve a few more bits in intermediate computations. But finite precision is finite precision. If you're running up against the limitations of doubles, then chances are it's not just a few more bits you need -- you either need to rethink your algorithm or go to variable precision floats. Maybe just rename 'real' to something less inviting, so that only the people who really need it will be tempted to use it. Like __real or __longdouble, or __tempfloat or something. --bb On Wed, Apr 21, 2010 at 3:38 PM, bearophile bearophileh...@lycos.com wrote: I suggest to remove the real type from D2 because: - It's the only native type that has not specified length. I'm sold on the usefulness of having defined length types. Unspecified length types causes some of the troubles caused by C types that D has tried to avoid defining the size of its integral types. - Its length is variable across operating systems, it can be 10, 12, 16 bytes, or even just 8 if they get implemented with doubles. The 12 and 16 bytes long waste space. - Results that you can find with programs written in other languages are usually computed with just floats or doubles. If I want to test if a D program gives the same results I can't use reals in D. - I don't see reals (long doubles in C) used much in other languages. - If I compile a program with LDC that performs computations on FP values, and I take a look at the asm it produces, I can see onl SSE-related instructions. And SSE registers allow for 32 and 64 bit FP only. I think future AVX extensions too don't support 79/80 bit floats. GPUs are increasingly used to perform computations, and they don't support 80 bit floats. So I think they are going to be obsolete. Five or ten years from now most numerical programs will probably not use 80 bit FP. - Removing a built-in type makes the language and its manual a little simpler. - I have used D1 for some time, but so far I have had hard time to find a purpose for 80 bit FP numbers. The slight increase in precision is not so useful. - D implementations are free to use doubles to implement the real type. So in a D program I can't rely on their little extra precision, making them not so useful. - While I think the 80 bit FP are not so useful, I think Quadrupe precision FP (128 bit, currently usually software-implemented) can be useful for some situations, (http://en.wikipedia.org/wiki/Quadruple_precision ). They might be useful for High dynamic range imaging too. LLVM SPARC V9 will support its quad-precision registers. - The D2 specs say real is the largest hardware implemented floating point size, this means that they can be 128 bit too in future. A numerical simulation that is designed to work with 80 bit FP numbers (or 64 bit FP numbers) can give strange results with 128 bit precision. So I suggest to remove the real type; or eventually replace it with fixed-sized 128 bit floating-point type with the same name (implemented using a software emulation where the hardware doesn't have them, like the __float128 of GCC: http://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html ). In far future, if the hardware of CPUs will support FP numbers larger than 128 bits, a larger type can be added if necessary. Bye, bearophile
Re: Remove real type
bearophile wrote: I suggest to remove the real type from D2 because: D being a systems programming language should give access to the types supported by the CPU. If you don't like real, don't use it! It's not hard to avoid. Furthermore, reals are supported by gcc and dmc, and part of D's mission is to interoperate with C's data types.
typedef in D2
I think a recent discussion about typedef has decided to remove the typedef and keep only the alias (if I am wrong, then only the last part of this can be useful). In that thread people have said they find typedef useless, but I keep finding it useful even in partially OOP code too. In the D.learn group there was a long thread (that's not closed yet, I have one more answer to add) about some C++ code ported to D (the OP programmer is a newbie D programmer): http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learnarticle_id=19449 This is the last D version of his program, that I have cleaned up a little in successive stages (and there are some more things to fix left): version (Tango) { import tango.stdc.stdio: printf; import tango.math.Math: sqrt, pow; } else { import std.stdio: printf; import std.math: sqrt, pow; } struct FastRandom { uint kiss_x = 1; uint kiss_y = 2; uint kiss_z = 4; uint kiss_w = 8; uint kiss_carry = 0; uint kiss_k, kiss_m; void seed(uint seed) { kiss_x = seed | 1; kiss_y = seed | 2; kiss_z = seed | 4; kiss_w = seed | 8; kiss_carry = 0; } uint randUint() { kiss_x = kiss_x * 69069 + 1; kiss_y ^= kiss_y 13; kiss_y ^= kiss_y 17; kiss_y ^= kiss_y 5; kiss_k = (kiss_z 2) + (kiss_w 3) + (kiss_carry 2); kiss_m = kiss_w + kiss_w + kiss_z + kiss_carry; kiss_z = kiss_w; kiss_w = kiss_m; kiss_carry = kiss_k 30; return kiss_x + kiss_y + kiss_w; } double random() { return this.randUint() / (uint.max + 1.0); } double uniform(double a, double b) { double r = cast(double)this.randUint() / (uint.max + 1.0); return a + (b - a) * r; } } struct Rating { uint user, object; double value; } abstract class ReputationAlgorithm { this() {} } typedef Rating[] TyRatings; typedef double[] TyReputationUser; typedef double[] TyReputationObject; final class Yzlm : ReputationAlgorithm { double beta; double convergenceRequirement; double errorMin; //uint[] userLinks; // commented out because for now it // has a constant value for all users double[] weightSum; TyReputationObject oldReputationObject; double objectReputationUpdate(TyRatings ratings, TyReputationUser reputationUser, ref TyReputationObject reputationObject) { double diff = 0; TyReputationObject temp = oldReputationObject; // Original version had: // //oldReputationObject[] = reputationObject[] // // This version is an attempt to save effort // by just switching round the memory the two // arrays are pointing at -- not sure if it // actually does what I'm expecting it to. // Doesn't seem to improve speed. :-( oldReputationObject = reputationObject; reputationObject = temp; reputationObject[] = 0; weightSum[] = 0; foreach (ref const(Rating) r; ratings) { reputationObject[r.object] += reputationUser[r.user] * r.value; weightSum[r.object] += reputationUser[r.user]; } foreach (uint object, ref double r; reputationObject) { r /= (weightSum[object] 0) ? weightSum[object] : 1; auto aux = (r - oldReputationObject[object]); diff += aux * aux; } return sqrt(diff); } void userReputationUpdate(ref TyRatings ratings, TyReputationUser reputationUser, TyReputationObject reputationObject) { reputationUser[] = 0; foreach (ref const(Rating) r; ratings) { auto aux = (r.value - reputationObject[r.object]); reputationUser[r.user] += aux * aux; } foreach (uint user, ref double r; reputationUser) { //if(userLinks[user]0) r = pow( (r/reputationObject.length/*userLinks[user]*/) + errorMin, -beta); } } void opCall(ref TyRatings ratings, ref TyReputationUser reputationUser, ref TyReputationObject reputationObject) { //userLinks.length = reputationUser.length; //userLinks[] = 0; weightSum.length = reputationObject.length; oldReputationObject.length = reputationObject.length; //foreach (Rating r; ratings) //userLinks[r.user]++; double diff; uint iterations = 0; do { userReputationUpdate(ratings, reputationUser, reputationObject); diff = objectReputationUpdate(ratings, reputationUser, reputationObject); ++iterations; } while (diff convergenceRequirement); printf(Exited in %u iterations with diff = %g %g\n, iterations,
Re: Remove real type
On 4/21/2010 7:00 PM, Bill Baxter wrote: I don't find it that useful either. Seems to me the only use is to preserve a few more bits in intermediate computations. But finite precision is finite precision. If you're running up against the limitations of doubles, then chances are it's not just a few more bits you need -- you either need to rethink your algorithm or go to variable precision floats. Maybe just rename 'real' to something less inviting, so that only the people who really need it will be tempted to use it. Like __real or __longdouble, or __tempfloat or something. --bb On Wed, Apr 21, 2010 at 3:38 PM, bearophilebearophileh...@lycos.com wrote: I suggest to remove the real type from D2 because: - It's the only native type that has not specified length. I'm sold on the usefulness of having defined length types. Unspecified length types causes some of the troubles caused by C types that D has tried to avoid defining the size of its integral types. - Its length is variable across operating systems, it can be 10, 12, 16 bytes, or even just 8 if they get implemented with doubles. The 12 and 16 bytes long waste space. - Results that you can find with programs written in other languages are usually computed with just floats or doubles. If I want to test if a D program gives the same results I can't use reals in D. - I don't see reals (long doubles in C) used much in other languages. - If I compile a program with LDC that performs computations on FP values, and I take a look at the asm it produces, I can see onl SSE-related instructions. And SSE registers allow for 32 and 64 bit FP only. I think future AVX extensions too don't support 79/80 bit floats. GPUs are increasingly used to perform computations, and they don't support 80 bit floats. So I think they are going to be obsolete. Five or ten years from now most numerical programs will probably not use 80 bit FP. - Removing a built-in type makes the language and its manual a little simpler. - I have used D1 for some time, but so far I have had hard time to find a purpose for 80 bit FP numbers. The slight increase in precision is not so useful. - D implementations are free to use doubles to implement the real type. So in a D program I can't rely on their little extra precision, making them not so useful. - While I think the 80 bit FP are not so useful, I think Quadrupe precision FP (128 bit, currently usually software-implemented) can be useful for some situations, (http://en.wikipedia.org/wiki/Quadruple_precision ). They might be useful for High dynamic range imaging too. LLVM SPARC V9 will support its quad-precision registers. - The D2 specs say real is the largest hardware implemented floating point size, this means that they can be 128 bit too in future. A numerical simulation that is designed to work with 80 bit FP numbers (or 64 bit FP numbers) can give strange results with 128 bit precision. So I suggest to remove the real type; or eventually replace it with fixed-sized 128 bit floating-point type with the same name (implemented using a software emulation where the hardware doesn't have them, like the __float128 of GCC: http://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html ). In far future, if the hardware of CPUs will support FP numbers larger than 128 bits, a larger type can be added if necessary. Bye, bearophile Just a personal preference, but I always disliked secret features of languages hidden behind underscores. I feel like features should be part of the standard spec or not there at all.
Re: Remove real type
On the other hand, being an engineer, I use the reals all the time and want them to stay. I would use the max precision supported by the cpu then fixed precision like double any day. -sk Walter Bright wrote: bearophile wrote: I suggest to remove the real type from D2 because: D being a systems programming language should give access to the types supported by the CPU. If you don't like real, don't use it! It's not hard to avoid. Furthermore, reals are supported by gcc and dmc, and part of D's mission is to interoperate with C's data types.
Re: Remove real type
abcd Wrote: On the other hand, being an engineer, I use the reals all the time and want them to stay. I would use the max precision supported by the cpu then fixed precision like double any day. -sk For me it's the exact opposite, reproducibility/portability is key. My problem with real is that I am always afraid my floats get upgraded to them internally somewhere/somehow.
Re: Remove real type
strtr wrote: abcd Wrote: On the other hand, being an engineer, I use the reals all the time and want them to stay. I would use the max precision supported by the cpu then fixed precision like double any day. -sk For me it's the exact opposite, reproducibility/portability is key. My problem with real is that I am always afraid my floats get upgraded to them internally somewhere/somehow. With numerical work, I suggest getting the correct answer is preferable g. Having lots of bits makes it more likely you'll get the right answer. Yes, it is possible to get correct answers with low precision, but it requires an expert and the techniques are pretty advanced.
Re: Remove real type
- Its length is variable across operating systems, it can be 10, 12, 16 bytes, or even just 8 if they get implemented with doubles. The 12 and 16 bytes long waste space. across hardware systems - its not an operating system thing 80bit is the native size of x86 fpu - Results that you can find with programs written in other languages are usually computed with just floats or doubles. If I want to test if a D program gives the same results I can't use reals in D. - I don't see reals (long doubles in C) used much in other languages. but you can't port delphi extended type (since delphi2 i think), gcc suports it, llvm supports it, assembler support it, borland and intel compiler supports it - Removing a built-in type makes the language and its manual a little simpler. it doesn't change the codegeneration that much (ok, ok there are some fpu instructions that are not fully equal to double precision behaviour) but also for more than 15 years now - I have used D1 for some time, but so far I have had hard time to find a purpose for 80 bit FP numbers. The slight increase in precision is not so useful. - D implementations are free to use doubles to implement the real type. So in a D program I can't rely on their little extra precision, making them not so useful. but it is an 80bit precision feature in hardware - why should i use an software based solution - if 80bits are enough for me btw: the precision lost while switching between fpu stack and the D data space is better - While I think the 80 bit FP are not so useful, I think Quadrupe precision FP (128 bit, currently usually software-implemented) can be useful for some situations, (http://en.wikipedia.org/wiki/Quadruple_precision ). They might be useful for High dynamic range imaging too. LLVM SPARC V9 will support its quad-precision registers. sounds a little bit like: lets throw away the byte type - because we can do better things with int - The D2 specs say real is the largest hardware implemented floating point size, this means that they can be 128 bit too in future. A numerical simulation that is designed to work with 80 bit FP numbers (or 64 bit FP numbers) can give strange results with 128 bit precision. ok now we got 32bit, 64bit and 80bit in hardware - that will (i hope) become 32bit,64bit,80bit,128bit,etc... but why should we throw away real - maybe we should alias it to float80 or something - and later there will be an float128 etc. So I suggest to remove the real type; or eventually replace it with fixed-sized 128 bit floating-point type with the same name (implemented using a software emulation where the hardware doesn't have them, like the __float128 of GCC: http://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html ). In far future, if the hardware of CPUs will support FP numbers larger than 128 bits, a larger type can be added if necessary. why should we throw away direct hardware support - isn't it enough to add your software/hardware float128? and all the others btw: the 80bit code-generator part is much smaller/simpler in code than your 128bit software based impl
Re: Remove real type
On Wed, 21 Apr 2010 23:48:20 -0300, strtr st...@spam.com wrote: abcd Wrote: On the other hand, being an engineer, I use the reals all the time and want them to stay. I would use the max precision supported by the cpu then fixed precision like double any day. -sk For me it's the exact opposite, reproducibility/portability is key. My problem with real is that I am always afraid my floats get upgraded to them internally somewhere/somehow. You do realize that the x86 floating point unit _always_ promotes floats and doubles to reals internally? The only way around it is for the compiler to use MMX/SSE unit for everything instead.
Re: Comb Sort with ranges
Ellery Newcomer: this is a bit off topic, but have you noticed that comb sort can consistantly beat the pants off phobos' built in sort for data of reasonable sizes? In my dlibs1 there is a tuned Quicksort that I have written that is about 3.5 faster than the built-in sort, so I am not surprised. (The built-in sort is not a template, it used run-time typeinfo to work). Admittedly, I didn't implement it using ranges (It's really cool that you can!) and just used arrays. I have already found three bugs in that cool code, I will try to fix them and I'll post an updated version. Bye, bearophile
tools.ctfe for D1
On 20.04.2010 01:49, Ellery Newcomer wrote: Are there any good libraries for ctfe/code generation? I don't know, things like parsing support for compile time strings, string formatting, type - string My project seems to be growing ctfe, and it's all horribly hacky and ugly code. This might be useful if you're on D1: http://dsource.org/projects/scrapple/browser/trunk/tools/tools/ctfe.d Contents: * ctToString(int) * ctAtoi(string) * ctToLower(string) * ctFind(string, string) * ctFind(string, char) * ctRFind(string, string) * ctStripL(string) * ctStripR(string) * ctStrip(string) * ctSlice(ref string, string where, bool cutOff = true) * ctReplace(string, string, string) * ctBetween(string text, string from, string to, bool adhere_right = false) * ctReplace(string, string, string{, string, string}) * Table parsing code (ctTableHeight, ctTableWidth, ctTableUnrollColMajor, ctTableUnroll, ctTableUnrollColumn, ctTableLookup and related) * ctExpand (turns foo, bar(0, 1)baz into |foo|bar0baz|bar1baz, used for simpler enum generation)
Re: ctfe library
bearophile wrote: Don: I've found that the function below improves things immensely. I might propose it for std.metastrings in the next Phobos release. Can you tell me what this function can be useful for? Thank you, bye, bearophile If you have recursive mixins (such as appears in many of the examples posted by downs), it lets you get rid of the horrible `\` and backslashes which appear everywhere.
Re: Buffered Endian Stream Socket?
Kyle Mallory wrote: I'm trying to write a series of structs to a stream, which then has to be sent over the wire within a single TCP packet, in order for the host, an embedded device, to recognize the message. If there is too little, or too much data for a given command (packet), the device will throw out the entire packet. Ie, one packet must contain one complete message. In all of my messages, the first 23 bytes are a common header. I'm playing with having this header be a separate struct, apart from the subsequent payload struct. This will allow me to do simple things like (in pseudo-d-code): msg.foo = 1234; msg.bar = DMDD; hdr.datalen = Payload.sizeof; packet.write((hdr)[0..1]); packet.write((msg)[0..1]); socket.send(packet); Since this is network data originating from various platforms, I also need to handle endian issues. There are a few problems I'm running into with all of this: I can't find a way to load data into a SocketStream without also issuing a Socket.send(). I considered a BufferedStream, or a MemoryStream but its not clear if/or how I would go about issuing an explicate send. Is there a preferred way to do this that I'm missing? If you had a BufferedStream wrapping a SocketStream, then I think you could call flush(); to trigger the send. It may depend on the size of the BufferedStream.. Is is possible (or reasonable) to pass in arbitrary structs into EndianStream and expect that it will intelligently convert each type in the struct? No.. I think you want to create your own PacketStream class containing an EndianStream, wrapping a BufferedStream, wrapping a SocketStream. Then.. all your structs you want to write derive from a common base struct and you implement a PacketStream.writeStruct(BaseStruct a) method which uses reflection to discover all the members of the struct at runtime. It would then call itself for all members derived from BaseStruct, and EndianStream.write for all basic types. Alternately, an easier/more verbose way to go is to have a seperate writeStruct specifically for each struct you want to write, and manually code them up to write all the members. This way means you have to remember to update them as you add members to structs etc. You'll need a member, or members in PacketStream to start and flush/send the packet. The former would write the packet header to the endian/buffer stream and the latter would call flush to send the data. R
Re: tools.ctfe for D1
FeepingCreature Wrote: On 20.04.2010 01:49, Ellery Newcomer wrote: Are there any good libraries for ctfe/code generation? I don't know, things like parsing support for compile time strings, string formatting, type - string My project seems to be growing ctfe, and it's all horribly hacky and ugly code. This might be useful if you're on D1: http://dsource.org/projects/scrapple/browser/trunk/tools/tools/ctfe.d Contents: * ctToString(int) * ctAtoi(string) * ctToLower(string) * ctFind(string, string) * ctFind(string, char) * ctRFind(string, string) * ctStripL(string) * ctStripR(string) * ctStrip(string) * ctSlice(ref string, string where, bool cutOff = true) * ctReplace(string, string, string) * ctBetween(string text, string from, string to, bool adhere_right = false) * ctReplace(string, string, string{, string, string}) * Table parsing code (ctTableHeight, ctTableWidth, ctTableUnrollColMajor, ctTableUnroll, ctTableUnrollColumn, ctTableLookup and related) * ctExpand (turns foo, bar(0, 1)baz into |foo|bar0baz|bar1baz, used for simpler enum generation) When will Phobos D1 plus be released?
Re: tools.ctfe for D1
On 04/21/2010 05:43 AM, FeepingCreature wrote: On 20.04.2010 01:49, Ellery Newcomer wrote: Are there any good libraries for ctfe/code generation? I don't know, things like parsing support for compile time strings, string formatting, type- string My project seems to be growing ctfe, and it's all horribly hacky and ugly code. This might be useful if you're on D1: http://dsource.org/projects/scrapple/browser/trunk/tools/tools/ctfe.d Looks like itś exactly what I want, thanks! A couple notes: Is there any particular license associated with it? (whatever tangoś is would be fine) When I try to compile, I get forward referencing errors and had to take out the import to tools.compat
Re: tools.ctfe for D1
Also, are there any examples for usage of the table parsing functions? And to whom do I give attribution?
Re: Comb Sort with ranges
This removes two of the three bugs. But this code doesn't work yet with a class that implements a collection, because code like: auto right = data; copies just the reference to the data object. Suggestions welcome. I have also seen that some of the functions of std.range don't work with static arrays, so I've had to roll my own fixed versions, see the isSorted() below. Bye, bearophile import std.algorithm: swap, binaryFun, sort; import std.range: isForwardRange, walkLength, popFrontN, empty, front, popFront, hasSwappableElements, equal; import std.contracts: enforce; void combsort(alias less=a b, Range)(Range r) if (__traits(isStaticArray, Range) || (isForwardRange!Range hasSwappableElements!Range)) { static void combsort_impl(Range2)(Range2 data) { // From: http://en.wikipedia.org/wiki/Comb_sort enum double SHRINK_FACTOR = 1.247330950103979; auto gap = walkLength(data); bool swapped = true; while ((gap 1) || swapped) { if (gap 1) gap /= SHRINK_FACTOR; swapped = false; auto right = data; popFrontN(right, gap); for (auto left = data; !right.empty; left.popFront, right.popFront) { if (binaryFun!(less)(right.front, left.front)) { swap(left.front, right.front); swapped = true; } } } } // postcondition verified in debug mode only. // Workaround: necessary because D postconditions don't // support the old (original input data view) yet. debug { static if (__traits(isStaticArray, Range)) { auto r_copy = array(r[]); sort!(less)(r_copy); combsort_impl(r[]); enforce(equal(r[], r_copy)); } else { auto r_copy = array(r); sort!(less)(r_copy); combsort_impl(r); enforce(equal(r, r_copy)); } } else { static if (__traits(isStaticArray, Range)) combsort_impl(r[]); else combsort_impl(r); } } // end combsort() // no way to give a checked name to the unittest yet unittest { // tests of combsort() // TODO } // end tests of combsort() // // imports local to the main() // function-local imports not supported yet import std.stdio: writeln; import std.range: SListRange, array; import std.algorithm: isSorted_impl = isSorted; import std.string: format; bool isSorted(alias less=a b, Range)(Range data) if (__traits(isStaticArray, Range) || isForwardRange!Range) { static if (__traits(isStaticArray, Range)) return isSorted_impl!(less)(data[]); else return isSorted_impl!(less)(data); } void main() { int[] a = [10, 1, 5, 3, 7, -1, 5, 21, -3]; writeln(isSorted(a), , a); combsort(a); writeln(isSorted(a), , a); writeln(); auto lst = SListRange!int(10, 1, 5, 3, 7, -1, 5, 21, -3); writeln(isSorted(lst), , array(lst)); combsort(lst); writeln(isSorted(lst), , array(lst)); writeln(); int[9] b = [10, 1, 5, 3, 7, -1, 5, 21, -3]; writeln(isSorted(b), , b); combsort(b); writeln(isSorted(b), , b); writeln(); } Bye, bearophile
[Issue 4089] crash when creating JSON output for incomplete struct
http://d.puremagic.com/issues/show_bug.cgi?id=4089 --- Comment #2 from Rainer Schuetze r.sagita...@gmx.de 2010-04-21 11:09:05 PDT --- An almost identical patch is also needed for incomplete EnumDeclarations: Index: json.c === --- json.c(revision 433) +++ json.c(working copy) @@ -386,19 +386,23 @@ if (memtype) JsonProperty(buf, base, memtype-toChars()); -JsonString(buf, Pmembers); -buf-writestring( : [\n); -size_t offset = buf-offset; -for (int i = 0; i members-dim; i++) -{ Dsymbol *s = (Dsymbol *)members-data[i]; -if (offset != buf-offset) -{ buf-writestring(,\n); -offset = buf-offset; +if(members) +{ +JsonString(buf, Pmembers); +buf-writestring( : [\n); +size_t offset = buf-offset; +for (int i = 0; i members-dim; i++) +{ Dsymbol *s = (Dsymbol *)members-data[i]; +if (offset != buf-offset) +{ buf-writestring(,\n); +offset = buf-offset; +} +s-toJsonBuffer(buf); } -s-toJsonBuffer(buf); +JsonRemoveComma(buf); +buf-writestring(]\n); } JsonRemoveComma(buf); -buf-writestring(]\n); buf-writestring(}\n); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 3865] ICE(cgcs.c, D1 only): Assigning to struct literal member
http://d.puremagic.com/issues/show_bug.cgi?id=3865 Don clugd...@yahoo.com.au changed: What|Removed |Added Summary|ICE(cgcs.c): Assigning to |ICE(cgcs.c, D1 only): |struct literal member |Assigning to struct literal ||member --- Comment #1 from Don clugd...@yahoo.com.au 2010-04-21 13:00:19 PDT --- Strange, I can't reproduce this on D2. I must have been mistaken -- this seems to be a D1-only bug. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4108] New: [ICE] __traits(isStaticArray) on empty static array
http://d.puremagic.com/issues/show_bug.cgi?id=4108 Summary: [ICE] __traits(isStaticArray) on empty static array Product: D Version: future Platform: x86 OS/Version: Windows Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 13:45:12 PDT --- This is D2 code: void foo(T)(T) { bool b = __traits(isStaticArray, T); } void main() { int[0] arr; foo(arr); } dmd 2.043 gives at runtime: Internal error: ..\ztc\cod2.c 4333 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4109] New: writeln doesn't work with empty static array
http://d.puremagic.com/issues/show_bug.cgi?id=4109 Summary: writeln doesn't work with empty static array Product: D Version: future Platform: x86 OS/Version: Windows Status: NEW Keywords: rejects-valid Severity: normal Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 13:48:33 PDT --- This D2 code: import std.stdio: writeln; void main() { int[0] a; writeln(a); } dmd 2.043 shows: [...]\dmd\src\phobos\std\format.d(2040): Error: array index 0 is out of bounds obj[0 .. 0] [...]\dmd\src\phobos\std\format.d(2040): Error: array index 0 is out of bounds [0..0] -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4110] New: Function template with two constraints
http://d.puremagic.com/issues/show_bug.cgi?id=4110 Summary: Function template with two constraints Product: D Version: future Platform: x86 OS/Version: Windows Status: NEW Severity: normal Priority: P2 Component: Optlink AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 13:53:21 PDT --- This D2 code is wrong: void foo(T)(T x) if (is(T == int)) { if (!is(T == float)) { } void main() { foo(1); } The dmd 2.043 compiler+linker spit out: OPTLINK (R) for Win32 Release 8.00.2 Copyright (C) Digital Mars 1989-2009 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Warning 23: No Stack OPTLINK : Warning 134: No Start Address -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4111] New: Foreach ranges accept floating-point extrema
http://d.puremagic.com/issues/show_bug.cgi?id=4111 Summary: Foreach ranges accept floating-point extrema Product: D Version: future Platform: All OS/Version: All Status: NEW Keywords: accepts-invalid Severity: normal Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 14:01:40 PDT --- This D2 code works with dmd 2.043, it shows that foreach accepts floating point extrema too. But I think it's safer/tidier to accept only ranges with integral extrema (in Python too the range/xrange expects integers). FP approximations can cause problems here. import std.stdio; import std.math: nextUp; void main() { foreach(i; 2.1 .. 4.10001) { writeln(typeid(typeof(i))); // Output: double break; } foreach(i; 2.1 .. nextUp(4.1)) write(i, ); // Output: 2.1 3.1 4.1 } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4112] New: Stride in foreach ranges
http://d.puremagic.com/issues/show_bug.cgi?id=4112 Summary: Stride in foreach ranges Product: D Version: future Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 14:09:48 PDT --- In D2 the range syntax of foreach is useful because it helps state the iteration variable one time only instead of tree, it's cleaner and less bug-prone than the normal for syntax, and it's useful in many situations because many for loops are just over a numeric range (so the normal for syntax can be left for more complex situations). But beside natural series, for loops over arithmetic ranges too are common. Currently in D2 this requires a normal for syntax: for (int i = 0; i 100; i += 2) {} My experience with Python tells me that an optional stride can be useful here. This is a possible syntax (the colon is useful to visually tell apart the third value): foreach (i; 0 .. 100 : 2) {} (To keep things simpler, it can even be acceptable for the stride value to be a value known at compile-time). See also bug 4111. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4113] New: std.typetuple, std.typecons, TypeTuple, Tuple, tuple names
http://d.puremagic.com/issues/show_bug.cgi?id=4113 Summary: std.typetuple, std.typecons, TypeTuple, Tuple, tuple names Product: D Version: future Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 15:09:19 PDT --- I think the Phobos module std.typetuple is not well named because the tuples can contain values (variables) too. The std.typecons defines a Tuple. In D1 tuples are generally meant the ones used in std.typetuple. So I think this module too can be better named. Such tuples are implemented in D with structs, and in Pascal structs are named records. So I propose the following five name changes: std.typetuple == std.tuples std.typetuple.TypeTuple == std.tuples.Tuple std.typecons = std.records std.typecons.Tuple == std.records.Record std.typecons.tuple == std.records.record -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4114] New: Support static arrays in some algorithms
http://d.puremagic.com/issues/show_bug.cgi?id=4114 Summary: Support static arrays in some algorithms Product: D Version: future Platform: All OS/Version: All Status: NEW Keywords: patch Severity: normal Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 15:53:45 PDT --- Fixed-sized stack-allocated static arrays can't support all features of a dynamic array, so they are not a fully flexible range. So it's not possible to perform some operations/algorithms on static arrays. But there are several basic operations that I might desire to perform on static arrays too, like to test if their items are sorted (isSorted), to sort them (sort()), or to compare the items of a sequence to the items of a static array (equals). Currently std.algorithm.isSorted doesn't work with static arrays, but I see no point in forbidding isSorted() or sort() on a static array. A simple workaround is to use: isSorted(stat_arr[]) sort(stat_arr[]) to give isSorted a dynamic array view of the same contents of the static array. This is not too much bad looking, but it gratuitously breaks some generic code. This shows a possible simple way to fix it: to rename the current isSorted as isSorted_impl, and add this function template that uses isSorted_impl: import std.algorithm: isSorted_impl = isSorted; bool isSorted(alias less=a b, Range)(Range data) if (__traits(isStaticArray, Range) || isForwardRange!Range) { static if (__traits(isStaticArray, Range)) return isSorted_impl!(less)(data[]); else return isSorted_impl!(less)(data); } void main() { int[3] b = [1, 2, 3]; assert(isSorted(b)); } Better, the original isSorted() can become a function statically nested in this wrapper. std.range.array, equal() and sort() can be augmented in similar ways. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4115] New: Reading few CPU flags from D code
http://d.puremagic.com/issues/show_bug.cgi?id=4115 Summary: Reading few CPU flags from D code Product: D Version: future Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: DMD AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2010-04-21 16:52:34 PDT --- Delphi has ranged types of integral values, that increase the safety of programs, restricting a variable in a sub range. In D a struct template can be created to implement a ranged integral value: Ranged!(1, 1001, int) foo; alias Ranged!('a', 'z'+1, char) Lowercase; (The type used by the struct of the can be omitted, so for a range in [1, 1000] it can choose an int.) See a similar idea in C++: http://www.richherrick.com/software/herrick_library.html Multiplications are quite less common on ranged variables, + and - == and assigns are the most common operations done on them. The preconditions of the methods of that struct can test for the out-of-range conditions. In release mode they get removed (or I can use a debug statement). But it's better to keep those tests when possible, so I'd like that Ranged to be efficient. Delphi ranges are fast also because the compiler can remove some unnecessary checks, I can't do this in a simple way (template expressions are overkill here). The struct has to test for out-of-range and true overflows of the int/ubyte/etc they are implemented on. But there are no good solution in D because: - Checking for overflow in D with no inline assembly can be a little slow. - Modern programmers know assembly less than in the past - Asm is more error-prone - asm is less portable than D code - dmd (or LDC with no LDC extensions) don't inline functions and struct methods that contain asm code - And maybe the prologue-epilogue of the asm code can kill any performance improvement given by reading the overflow bit from asm. A solution is to make the backend smarter, so it recognizes patterns in the code and compiles it into good asm, but LLVM doesn't currently perform well here yet: http://llvm.org/bugs/show_bug.cgi?id=4916 http://llvm.org/bugs/show_bug.cgi?id=4917 http://llvm.org/bugs/show_bug.cgi?id=4918 Even if/when LLVM implement those tiny optimizations, that's not a full solution because the bad thing with compiler optimizations is that you can't rely on them. A solution that I think is better, that is portable on many CPU types (CPUs aren't forced have all those flags, but they are common, and the compiler can map the requested semantics using the correct asm instructions for different CPUs too), and gives good performance, is to add ways to read the contents of Overflow, Zero and Carry flags to std.intrinsic. A simple way to implement it is to turn them into boolean functions that the compiler manages in a special way, as the other intrinsics: bool over = overflow_flag(); if (carry_flag()) {...} else {...} Then the compiler has to manage them efficiently (for example here using a single JNO or JO instruction), and inlining functions if they contain such intrinsics. Unlike the other intrinsics I have given them a semantic name, instead of the name of the asm instruction, so the D compiler can use the right instruction from different CPUs, increasing their portability. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---