Re: Frontend and backend communication
On Wed, 10 Aug 2011 10:35:46 +0200, Dainius (GreatEmerald) past...@gmail.com wrote: I seem to have run into a problem with the function pointer method here. I have this code: arco.d: struct FrontendFunctions { void function(SoundTypes) Sound_Play; void function() RedrawScreenFull; void function(const char*, int) PrecacheCard; void function(CardInfo, int) PlayCardAnimation; } cards.d: void InitLuaFunctions() { lua[Damage] = (int Who, int Amount) { FrontendFunctions.Sound_Play(SoundTypes.Damage); }; } Essentially I am trying to get Lua (via LuaD) to call a function in D that calls a frontend function. But when I compile the code, I get this: cards.d(5): Error: 'this' is only defined in non-static member functions, not __dgliteral14. Why is this and what can I do about it? FrontendFunctions frontendFunctions; use frontendFunctions everywhere. OR (this makes them global): struct FrontendFunctions { static: ... }
Re: More than one invariant per struct/class
On Sat, 06 Aug 2011 22:53:31 +0200, Jonathan M Davis jmdavisp...@gmx.com wrote: Feel free to create a feature request on it. It may even get the language changed. However, having more than one invariant complicates things a bit, since right now, it's easy for the runtime to just call the one invariant. If you had multiple invariants, they would have to be merged somehow by the compiler. It's completely doable, but it definitely complicates things, which is probably why it doesn't work that way now. unittests are already merged this way, so it should be easy.
Re: Multi-file byte comparison tool. What would you have done differently?
On Fri, 05 Aug 2011 18:43:27 +0200, Kai Meyer k...@unixlords.com wrote: On 08/05/2011 03:02 AM, Pelle wrote: Don't declare variables until you need them, just leave bytes_read and bytes_max here. Is there a performance consideration? Or is it purely a style or D-Factor suggestion? Just style and D-factor :-) Also, resulting code is shorter, and you can replace a lot of type names with auto. I don't understand why you use ByteUnion instead of just a plain array of bytes. I thought that comparing one byte at a time would be slower than comparing 8 bytes at a time (size_t on 64bit) and failing over to the byte-by-byte comparison only when the size_t value was different. Maybe, but that's something that should be benchmarked. If a byte array is just as fast, and the code is simpler, that's a better solution :)
Re: Multi-file byte comparison tool. What would you have done differently?
On Fri, 05 Aug 2011 00:25:38 +0200, Kai Meyer k...@unixlords.com wrote: I have a need for detecting incorrect byte sequences in multiple files (2) at a time (as a part of our porting effort to new platforms.) Ideally the files should be identical for all but a handful of byte sequences (in a header section) that I can just skip over. I thought this would be a fun exercise for my D muscles. I found success creating a dynamic array of structs to keep information about each file passed in via command-line parameters. I'll append the code at the end (and I'm sure it'll get mangled in the process...) (I'm not one for coming up with creative names, so it's SOMETHING) Then I loop around a read for each file, then manually run a for loop from 0 to BLOCK_SIZE, copy the size_t value into a new dynamic array (one for each of the files opened), and run a function to ensure all values in the size_t array are the same. If not, I compare each ubyte value (via the byte_union) to determine which bytes are not correct by adding each byte to a separate array, and comparing each value in that array, printing the address and values of each bad byte as I encounter them. This appears to work great. Some justifications: I used size_t because I'm under the impression it's a platform specific size that best fits into a single register, thus making comparisons faster than byte-by-byte. I used a union to extract the bytes from the size_t I wanted to create a SOMETHING for each file at run-time, instead of only allowing a certain number of SOMETHINGS (either hard coded, or a limit). Originally I wrote my own comparison function, but in my search for something more functional, I tried out std.algorithm's count. Can't say I can tell if it's better or worse. Features I'll probably add if I have to keep using the tool: 1) Better support for starting points and bytes to read. 2) Threshold for errors encountered, perferrably managed by a command-line argument. 3) Coalescing error messages in sequential byte sequences. When I run the program, it's certainly I/O bound at 30Mb/s to an external USB drive :). So the question is, how would you make it more D-ish? (Do we have a term analogous to pythonic for D? :)) Code: import std.stdio; import std.file; import std.conv; import std.getopt; import std.algorithm; enum BLOCK_SIZE = 1024; union byte_union { size_t val; ubyte[val.sizeof] bytes; } struct SOMETHING { string file_name; size_t size_bytes; File fd; byte_union[BLOCK_SIZE] bytes; } I would use TypeNames and nonTypeNames, so, blockSize, ByteUnion, Something, sizeBytes, etc. void main(string[] args) { size_t bytes_read; size_t bytes_max; size_t size_smallest; size_t[] comp_arr; SOMETHING[] somethings; Don't declare variables until you need them, just leave bytes_read and bytes_max here. getopt(args, seek, bytes_read, bytes, bytes_max ); if(bytes_max == 0) bytes_max = size_t.max; // Limit on the smallest file size else bytes_max += bytes_read; //bytes_read = bytes_read - (bytes_read % (BLOCK_SIZE * SOMETHING.size_bytes.sizeof)); size_smallest = bytes_max; somethings.length = args.length - 1; comp_arr.length = args.length - 1; for(size_t i = 0; i somethings.length; i++) { somethings[i].file_name = args[i + 1]; somethings[i].size_bytes = getSize(somethings[i].file_name); stderr.writef(Opening file: %s(%d)\n, somethings[i].file_name, somethings[i].size_bytes); somethings[i].fd = File(somethings[i].file_name, r); somethings[i].fd.seek(bytes_read); if(somethings[i].fd.tell() != bytes_read) { stderr.writef(Failed to seek to position %d in %s\n, bytes_read, args[i + 1]); } // Pick the smallest file, or the limit size_smallest = min(size_smallest, somethings[i].size_bytes); } Use foreach (ref something; somethings) and something instead of somethings[i]. // Check file sizes for(size_t i = 0; i somethings.length; i++) comp_arr[i] = somethings[i].size_bytes; writef(count: %s\n, count(comp_arr, comp_arr[0])); if(count(comp_arr, comp_arr[0]) != comp_arr.length) { stderr.writef(Files are not the same size!); foreach(s; somethings) stderr.writef([%s:%d], s.file_name, s.size_bytes); stderr.writef(\n); } You can use writefln() istead of writef(\n) everywhere. // While bytes_read size of smallest file size_t block_counter; while(bytes_read size_smallest) { // Read bytes //stderr.writef(tell: ); for(size_t i = 0; i somethings.length; i++) { //stderr.writef(Reading file %s\n, file_names[i]); //stderr.writef(%d , somethings[i].fd.tell());
Re: NaCl stable ABI
On Thu, 04 Aug 2011 21:56:16 +0200, Nick Sabalausky a@a.a wrote: OT: Who the hell uses MSN? Almost everyone below 60 in Sweden, at least a few years ago.
Re: More than one invariant per struct/class
On Thu, 04 Aug 2011 11:32:03 +0200, simendsjo simend...@gmail.com wrote: I would like to use a template mixin to add some fields to a struct, but I'd also like the template to add additional invariant checks without having to remember to add this for all struct/classes that mixes in this code. class C { int a; } mixin template EmbedC() { C _c; // oops.. more than one invariant invariant() { assert(_c); } void close() { _c = null; } } struct S { int i = 10; invariant() { assert(i = 10); } mixin EmbedC!(); } void main() { S s; s.close(); s._c.a = 10; // access violation, but I want assertion from invariant } What happens if you replace assert(_c) with assert(_c !is null)?
Re: More than one invariant per struct/class
On Thu, 04 Aug 2011 12:40:48 +0200, simendsjo simend...@gmail.com wrote: On 04.08.2011 12:30, Pelle wrote: What happens if you replace assert(_c) with assert(_c !is null)? The problem is that you cannot include more than one invariant() in a struct or class. IIRC assert(obj) gets rewritten to obj.__invariant() or something like that, which segfaults if obj is null. I thought that maybe that was why the code didn't work. :--)
Re: Convert string to wchar.
On Wed, 03 Aug 2011 08:29:09 +0200, Jacob Carlborg d...@me.com wrote: Yes, convert the first code point to a wchar and then throw if there's more the one character in the string. Not tested, and I might be wrong, but 'to!' should work between dchar and wchar, no? wchar to_wchar(string s) { auto c = s.front; s.popFront(); assert (s.empty); return to!wchar(c); }
Re: Generate array of random values
On Mon, 01 Aug 2011 21:43:13 +0200, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: Actually I don't really need *uniform* distribution, it's just that when porting C code to D I didn't find any obvious random()/rnd() functions, and uniform seemed to be the closest thing without having to mess around with a bunch of randomization parameters which I don't care about. I don't see how we can claim D to be an elegant language with this mess: array(map!a % 1024(take(rndGen(), 1024))) That's just damn *horrible*. If we ever get UFCS that'd be rndGen().take(1024).map!a % 1024().array() Which is a lot better :--) Without UFCS, well, how would you want it to look? How does it look in other languages?
Re: Empy program running time
On Fri, 29 Jul 2011 15:37:36 +0200, bearophile bearophileh...@lycos.com wrote: On an oldish Windows PC an empty C program generated by GCC takes about 0.03 seconds to run. An empty D2 program runs in about 0.11 seconds. Is this expected/good/acceptable/fixable? Bye, bearophile That's a lot better than I expected! I don't think anyone would notice such a small difference.
Re: Frontend and backend communication
On Wed, 27 Jul 2011 19:41:37 +0200, Dainius (GreatEmerald) past...@gmail.com wrote: I have one program design problem and I wonder if anyone here could give any suggestions about it. The situation is like this: I am splitting a game into a frontend (a library) and a backend (an executable). The backend is going to handle all the game mechanics, while the frontend is going to handle I/O. But there are certain problems. For example, now I have a function Shuffle() that calls PlaySound(SHUFFLE). Shuffle() is a backend function, while PlaySound() is a frontend one, so obviously it won't work that way after the split. It would be ideal if there was a way to create hooks - say an empty PlaySound() function that the frontend could receive calls to. But I can't see a way to do that. Another way to do that that was suggested to me was to use an event loop - set a global variable, then have the frontend monitor it for changes and then respond as necessary, but that just isn't a very clean way to do it. And then there is the fact that the backend is going to be written in D (right now it's a mix of C and D), while the frontend will be in C (one of the frontends, anyway - the second one will also be in D). Any suggestions about this? You could use a struct of function pointers to define the interface, if you need it to work both in C and D. extern (C) struct FrontEndFunctions { void function(sound) playSound; ... } backend does myFrontEndFunctions.playSound(SHUFFLE); The front end: void myPlaySound(...) { ... } void main() { FrontEndFunctions functions; functions.playSound = myPlaySound; ... etc for other functions ...; backend.initialize(functions); backend.run(); }
Re: Importing D libraries
On Tue, 26 Jul 2011 13:06:56 +0200, Dainius (GreatEmerald) past...@gmail.com wrote: I updated the DMD and tried RDMD, but still no luck. Linker errors galore. You can see all of them here: http://pastebin.com/C6cRVGKt You need to link the library as well, try adding -L-llua (I think) to the command.
Re: Calling anonymous delegate recursively ?
On 01/08/2011 04:45 PM, tsukikage wrote: eg. to return a fibonacci delegate: return (ulong m) { if(m 2) return m ; return _self_ref(m-1)+_self_ref(m-2) ; } ; Is it possible? Thank you! http://en.wikipedia.org/wiki/Fixed_point_combinator#Y_combinator I don't think there's a built in way to self-recurse.
Re: How the GC distinguishes code from data
On 01/06/2011 07:31 AM, %u wrote: If you have allocated a large uint[], most likely =C3=ACt will be flagged NO_SCAN, meaning it has no pointers in it, and the GC will ignore it. Ah, but the trouble is, no one said that this array has to be in the GC heap! I could easily have a void[] and a uint[] that both point to non-GC managed memory. Or I might even have a uint[] allocated on the stack! How does the GC distinguish these, when there's no attribute it can mark? (Or does it?!) It assumes everything on the stack is pointers, at the moment, I believe. If it's not on the garbage collected heap, it won't scan it unless you tell it to.
Re: terminology: l-value r-value
On 01/04/2011 02:55 PM, spir wrote: Hello, I'm bluffed by the 2 terms l-value r-value used in C-line language common terminologies. I think I guess what they mean, but I don't understand the need for such absconse idioms. Why not: l-value- variable r-value- value (or expression) ? I guess (*p) is considered an l-value. Indeed, it's a special way of denoting a variable, matching the special case of a pointer. If correct, this requires slightly extending the notion of variable (and/or of identifier). On the r-value side, I cannot find anything that makes it a distinct concept from the one of value, or of expression. Explanations welcome, thank you, Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com rvalue is easier than value-not-bound-to-a-memory-address. lvalue is easier than value-with-memory-address. Both lvalues and rvalues are values, both can be expressions, and lvalues doesn't have to be variables. Perhaps a better terminology could have been chosen, but changing them doesn't provide real benefits, as far as I can tell.
Re: Odd to!string call
On 12/21/2010 07:38 PM, Andrej Mitrovic wrote: I found this by accident: import std.stdio; import std.conv; void main() { writeln(to!string(2, 2)); // writes 10 writeln(to!string(1, 0)); // std.conv.ConvException: Radix error } I'm not sure why std.conv.to would even take multiple arguments. Bugzilla? to! does some fancy stuff, like here: auto myarr = [1,2,3]; writeln(to!string(myarr, myarr:\n, \n, \n-\n); will write (untested, but should work :-) myarr: 1 2 3 - I find this most useful a lot of the time.
Re: List of derived types?
On 12/16/2010 02:16 PM, d coder wrote: Greetings I need a way to know (using traits or other compile time constructs) all the types derived from a given type. Is it possible in D? Is it possible to get a list of all the user-defined classes? I could use that to filter out the classes that I need. Regards Cherry I'm curious, why do you need that?
Re: Concurrency and transfering ownership of data between threads?
On 12/13/2010 09:45 PM, Heywood Floyd wrote: Good Evening from Berlin! Have been reading the chapter about concurrency by Andrei. Nice. I have some questions, of varying quality, I'm sure. Let's say that we have some sort of structure of rather complex data. To give us something concrete to talk about, let's say this data is a tree of nodes representing 3-dimensional objects. It could look something like this: (Not complete example, just to give an idea.) // ... class Cube : Node{ float x, y, z, size, mass, elasticity; // ... } // ... tree.add(new Cube(cube1)); tree[cube1].add(new Cube(cube2)); Let's further say that this structure of data will be subjected to two different activities: 1) We will change properties of some nodes according to some complex lengthy calculations, which may even entail changing the position of nodes in the tree, and 2) we will traverse the tree in a recursive manner and read the properties in order to render a representation of these nodes to screen. These two activities will then be repeated many times, so, let's say we wish to do these two activities in parallel as much as possible! How do we do that? From what I can tell, one way of doing this would be to actually have two data structures, one which is the original and is used for the calculations, and one which is just a copy of the data after each calculation. We could then insert a third activity, which me can call copy, inbetween the two threads. Something like this: |== Calculate ===| Copy | |v |= Render | Seems to me this would then allow us to interlock these two activites: ..|== Calculate ===| Copy |== Calculate |.. ..|=== Render ===|v |=== Render |.. (Sorry if the ASCII graphics looks skewed.) So let me just try and set up some kind of rudamentary code for this in layman's D: // import ... void main() { auto tree = new Node(); tree.add(new Cube(cube1)); auto child = spawn(renderLoop, thisTid); while(true) { calc(tree); auto treeCopy = tree.deepDup(); receiveOnly!bool(); send(child, treeCopy); } } void renderLoop(Tid parent){ { send(parent, true); while(true) { Node tree = receiveOnly!Node(); render(tree); send(parent, true); } } So a couple of thoughts here. - Is this looking ok? What is the proper way of going about this? - How do we send over a large chunk of complex data to another thread and sort of let them assume ownership of this data? So that the thread receiving the data does not need any locks etc. when working with the data? I suppose we could send over the entire treeCopy as immutable (?) but let's for the sake of argument assume that renderLoop() needs to be able to _write_ in the copy of the tree structure too! (- Sidenote: How do we efficiently copy a tree-structure of data several times per second? Sounds insane to me?) Let's further, for the sake of argument, NOT consider that the GPU will do most of the rendering and that in effect parallelising in this particular case may be marginally beneficial. Let's simply assume we have only one processor here: your normal household dual-core CPU, and a VGA-graphics card from the 80s. For me, in my head, parallelising is very much about designing a flow of data through different processes, and this flow chart will have certain hot spots where data must be guarded. You have one process doing something and then transfering over some data to the next process that continues the calculations. (With process I simply mean data processing activity, not a unix process.) |---calc A---Ocalc C etc. |---calc B-^ O = transfer point I find it difficult to see how this is done in D. (Of course, I'm not sure this transfer-idea makes any practical sense.) I understand immutable makes data read-only, contagiously, and shared makes data heavily guarded. But yes, is there any way we can transfer ownership (not sure if that is the right term) of data from one thread to another? So that we can have two threads working on two pieces data, then let them copy it (or not!), and then transfer ownership and have a third thread work on the copied data, without barriers or guards or stuff like that during the time of actual work? Kind regards and sorry for a lengthy sporadic post /Heywood Floyd I think you should probably use shared. With the guards and all. And then not copying it, just sending the reference. If the write barriers make this too slow, try selectively casting away shared at heavy working spots, when you know that's the only place using the object at that time. I think that should be safe. (?) :)
Re: import inside a class overrides symbols imported in module scope?
On 12/09/2010 10:53 PM, Trass3r wrote: It was quite hard to track that one down. In the following example the import statement was mixed into the class among other code so it wasn't as obvious as here. import std.traits; class Foo { import std.string; static assert(isNumeric!int); } foo.d(6): Error: template instance isNumeric is not a template declaration, it is a function foo.d(6): Error: static assert (isNumeric!(int)) is not evaluatable at compile time (There's an isNumeric function in std.string) Local variables override global ones, but is this correct as well? You probably want to use static import when mixing stuff in, to avoid this accidental invasion of namespace.
Re: C++ istream / ostream equivalent ?
On 12/02/2010 09:05 AM, vincent picaud wrote: Matthias Pleh Wrote: Thank you for your reply and yes that works :) Now i m facing with the following problem, what is the trick for input stream ? ( something like std::istream operator(std::istream in,A a) { // A.someData in; return in; } in C++ ) I m thinking of the situation when we want to load some data from a file. The toString() trick is okay for saving the object... but how to load it back (something like fromString(char[]) would do the job but it does not exist in Object) ? Anyway thank you, you solved half of my problem :) Ther are many posibilities, depending on your further needs! Just have a look at the online dokumentation: http://www.digitalmars.com/d/2.0/phobos/phobos.html But my first try would be such .. (note: I've leaved out error-handling ...) module test; import std.stdio; import std.file; class A { void writeToFile() { std.file.write(sample.txt,someData); } void readFromFile() { someData=cast(string)read(sample.txt); } void clear(){ someData=n/A\n; } string toString() { return someData; } private: string someData=Just some data. With anohter line of date. Even more data.!; } int main(string[] args) { A a=new A; a.writeToFile(); a.clear(); writeln(a); a.readFromFile(); writeln(a); return 0; } thank you for all your answers. I understand the approach, but in the same time, I have the feeling that the C++ way is more convenient. Look in C++ , to define I/O for A, you do not have to modify your class A and simply have to overload two functions: std::ostream operator(std::ostream out,const A a) std::istream operator(std::istream in,A a) moreover this smoothly extend the I/O C++ framework without other side effect. I was expecting to find a similar mecanism in D/Phobos Perhaps by overloading some read(), write() functions of the Phobos library, but I do not know if it is moral to do that and which phobos functions are concerned... IMHO there is a documentation hole here What you want is the new writeTo system for output. For input, a readFrom would be symmetrical and make sense :-) To actually use it, you would just do myFile.write(your, stuff, etc); For now, you can stringify using toString(). No way to read yet, except to!int, etc.
Re: 'in' for plain arrays?
On 12/02/2010 01:07 PM, spir wrote: Hello, Is there an equivalent of 'in' for (non-associative) arrays? Cannot find any 'contains' function. (Wouldn't it be nice to have in work for all arrays? What is the reason why it only works with AAs?) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com It doesn't exist for performance reasons, I think. Use std.algorithm.canFind, which doesn't have the best name, but works as expected.
Re: Const foreach
On 11/22/2010 04:12 PM, Simen kjaeraas wrote: spir denis.s...@gmail.com wrote: On Sun, 21 Nov 2010 20:21:14 -0500 bearophile bearophileh...@lycos.com wrote: If in a D2 program I have an array of mutable items I may want to iterate on them but not modify them, so I'd like the iteration variable to be const. This is possible, but it seems I lose type inference: void main() { int[3] array; // not const // foreach (const x; array) {} // Error // foreach (const auto x; array) {} // Error // foreach (const(int) x; array) {} // OK foreach (const(typeof(array[0])) x; array) {} // OK } Is something wrong in that code? Is this a known limitation, an inevitable one? Is this an enhancement request worth adding to Bugzilla? Bye and thank you, bearophile Maybe you'll find it weird, but I would expect foreach (const(auto) x; array) {}; to be the logical idiom for this. auto beeing a kind of placeholder for a type name. 'auto' is not a placeholder for a type, but the default storage class. IOW, 'int n;' == 'auto int n;'. This does however not compile, complaining that it has no effect. Specifying just the storage class signals the compiler to use type inference. Try it: const x = 4; immutable y = 4; I'm not sure you are correct: const static auto x = 4;
Re: defining in a module symbols for export
On 11/22/2010 08:18 PM, spir wrote: Hello, Let us say I have a parsing library. Now, I want to define parsers in stand-alone modules -- for code structuration and reusability. Then, import them from apps that need them. Is there another way than defining the parser (== list of patterns) at the module's top-level. I have nothing against this, since the module is dedicated to this anyway -- but dmd refuses. More generally, I find myself unable to define structured objects at a modules's top level. for instancz: === mod.d == import std.stdio; struct S { int i; void speak() {writeln(i: ,this.i);} } === __trials__.d === import mod; auto s = S(); s.speak(); s.i = 1; writeln(s.i); void main () { } === compilation === __trials__.d(19): no identifier for declarator s.speak __trials__.d(20): no identifier for declarator s.i __trials__.d(21): found '.' when expecting ')' __trials__.d(21): semicolon expected, not 'i' __trials__.d(21): no identifier for declarator i __trials__.d(21): semicolon expected, not ')' __trials__.d(21): Declaration expected, not ')' Why does dmd refuse? If I put the code in a function, I can compile, link, and run it. But this does not match my use case: I need to export symbols (patterns) defined there; so, i guess, they must be defined at the top of the module. Is there another solution? I take the opportunity to ask whether it is possible to define which symbols are to be _ex_ported. Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com To initialize at runtime: S s; static this() { s.i = 1; } to initialize at compile time: S getS() { S s; s.i = 1; return s; } S s = getS(); Use public/private to control which symbols are availible. Unfortunately, this doesn't really work at the moment :-)
Re: segfault
On 11/12/2010 02:03 PM, Steven Schveighoffer wrote: Pelle, I spent all this time helping him, and you swoop in with the answer :) I was in a rush when answering, causing the swoopiness of my post. :-) I only knew the answer because I had almost exactly the same bug a week ago, or so. Coincidentally, for a parser generator.
Re: Combining variadic functions with class templates
On 09/30/2010 08:25 PM, Sebastian Schuberth wrote: On 30.09.2010 20:20, wrzosk wrote: void main() { Vec3f v(1,1,1); } I still get Building Release\ConsoleApp1.exe... main.d(14): found 'v' when expecting ';' following statement Building Release\ConsoleApp1.exe failed! Change Vec3f v(1,1,1); into Vec3f v = Vec3f(1,1,1); Thanks, that works, but that syntax seems a little verbose to me. Is the first syntax generally not supported in D? It is not. You can use auto v = Vec3f(1,1,1);
Re: Immutable woes
On 09/21/2010 09:29 AM, Bob Cowdery wrote: Hi I'm stuggling with immutable. I have a fixed size buffer which is used as a circular buffer of floats and is effectively double buffering data I wish to transfer to another thread. At an appropriate point I take the top half or bottom half of the buffer and send it to another thread. To do this I need to copy the data to an immutable transfer buffer to use in the send. I'm sure this is simple but I can't figure it. if I say something like: float[] xfer = new float[512]; xfer = buffer[0 .. $/2]; tid.send(xfer); it rightly tells me 'thread local data not allowed'. If I make it: immutable (float)[] xfer; xfer = buffer[0 .. $/2]; tid.send(xfer); it tells me 'can't implicitly convert float[] to immutable (float)[]' If I try a float by float copy into xfer it can't because I've said the buffer is immutable. In the first example I can't figure out how to convert the slice into an immutable copy which I think is what I should be doing. Can someone point me in the right direction. Thanks Bob immutable(float)[] xfer = buffer[0 .. $/2].idup; tid.send(xfer); Don't use assumeUnique for non-unique references.
Re: ubyte[] - immutable(ubyte)[]
On 09/10/2010 04:40 AM, Andrej Mitrovic wrote: I'm trying to use algorithm.copy, but I get back nothing in the copy buffer. How do I to copy an array of ubyte's? iimport std.algorithm, std.concurrency, std.stdio; void main() { enum bufferSize = 4; auto tid = spawn(fileWriter); // Read loop foreach (ubyte[] buffer; stdin.byChunk(bufferSize)) { immutable(ubyte)[] copy_buffer; copy(buffer, copy_buffer); writeln(copy_buffer); // writes nothing send(tid, copy_buffer); } } void fileWriter() { while (true) { auto buffer = receiveOnly!(immutable(ubyte)[])(); // writeln(buffer); } } Andrej Mitrovic Wrote: This is from TDPL page 407: import std.algorithm, std.concurrency, std.stdio; void main() { enum bufferSize = 1024 * 100; auto tid = spawn(fileWriter); // Read loop foreach (immutable(ubyte)[] buffer; stdin.byChunk(bufferSize)) { send(tid, buffer); } } void fileWriter() { // write loop while (true) { auto buffer = receiveOnly!(immutable(ubyte)[])(); tgt.write(buffer); } } Error: C:\DMD\dmd2\windows\bin\..\..\src\phobos\std\stdio.d(1943): Error: cannot implicitly convert expression (buffer) of type ubyte[] to immutable(ubyte)[] Yet interestingly I can't use type inference: foreach (buffer; stdin.byChunk(bufferSize)) { send(tid, buffer); } Error: stdin_stdout_copy.d(11): Error: cannot infer type for buffer But in the original code I get back a mutable ubyte[] which I can't implicitly convert to immutable (I'd need a copy first). There's no .dup or .idup property for stdin.byChunk. So what am I supossed to do here? std.algorithm.copy will copy an input range into an output range. An array is a valid output range, but does not append as you seem to expect. Instead, it fills the array. int[] a = new int[](3); copy([1,2,3],a); assert (a == [1,2,3]); To get an output range which appends to an array, use appender. In this case, however, you simply want buffer.idup; :-)
Re: slow runtime
On 09/10/2010 10:17 AM, Jonathan M Davis wrote: On Friday 10 September 2010 00:50:32 bearophile wrote: Jonathan M Davis: Aren't they _always_ on the heap? void main() { int[10] a; int[] b = a[]; } Bye, bearophile Ah, good point. When you have a slice of a static array as opposed to a dynamic arra allocated with new, then it's on the stack. Since I pretty much never use static arrays, I forgot about that. - Jonathan M Davis int i; int[] heh = (i)[0..1];
Re: Question about typeof(this)
On 09/10/2010 03:20 PM, Jacob Carlborg wrote: On 2010-09-07 22:32, Don wrote: Jacob Carlborg wrote: On 2010-09-07 17:29, Don wrote: Jacob Carlborg wrote: I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof where it says: typeof(this) will generate the type of what this would be in a non-static member function, even if not in a member function. From that I got the impression that the code below would print the same result, but it doesn't. It prints: main.Bar main.Foo instead of: main.Foo main.Foo Is this a bug or have I misunderstood the docs? typeof(this) gives the *compile-time* type of this. Inside Bar, it has to return 'Bar'. typeid(this) gives the *runtime* type of this. So it can work that it's Bar is actually a Foo. I know that typeof(this) is a compile time expression but in this case I think the compiler has all the necessary information at compile time. Note that I'm not calling method on a base class reference, I'm calling it on the static type Foo. In this case I think typeof(this) would resolve to the type of the receiver, i.e. the type offoo. Even though in this instance it could work out which derived class is being used, it's not allowed to use that information while compiling method(). There is only ONE function method(), and it has to work for Bar, and all classes derived from Bar. I think Scala can handle this problem, the following text is a snippet from a paper called Scalable Component Abstractions (link at the bottom), page 4 Type selection and singleton types: class C { protected var x = 0; def incr: this.type = { x = x + 1; this } } class D extends C { def decr: this.type = { x = x - 1; this } } Then we can chain calls to the incr and decr method, as in val d = new D; d.incr.decr; Without the singleton type this.type, this would not have been possible, since d.incr would be of type C, which does not have a decr member. In that sense, this.type is similar to (covariant uses of ) Kim Bruce's mytype construct [5]. I'm not very familiar with Scala but the above code example seems to work as I want typeof(this) to work. http://www.scala-lang.org/sites/default/files/odersky/ScalableComponent.pdf You can do this in D, but the syntax is clumsy. And it uses templates. class C { int x; T incr(this T)() { x += 1; return cast(T)this; // clumsy, but always works (?) } } class D : C { T decr(this T)() { x -= 1; return cast(T)this; } } void main() { D d = new D; d.decr.incr.decr.incr.incr; writeln(d.x); }
Re: Generic collection/element function signatures in D2 versus D1
On 09/08/2010 02:24 PM, Steven Schveighoffer wrote: On Tue, 07 Sep 2010 14:06:58 -0400, Steven Schveighoffer schvei...@yahoo.com wrote: On Tue, 07 Sep 2010 11:37:20 -0400, Pelle pelle.mans...@gmail.com wrote: On 09/07/2010 04:33 PM, Steven Schveighoffer wrote: Yes, a valid return. Your function should be: void foo(void delegate(const(C) f) const It helps to understand that inout/const/immutable has NOTHING to do with code generation, it only has to do with limiting what compiles. For this reason, an inout function is compiled once, and works on all three constancies (4 if you have a nested inout function). For the entire function any inout variable is treated as a non-changeable value, just like const. Then when you return, it's converted at the call site back to the constancy with which it was called. If the return value is void, then there's nothing to convert, and no reason to use inout over const. I'll repeat -- there is no benefit to inout if you are not returning anything. -Steve That's not an equivalent function signature. Or maybe it is, but look at this (sorry it's so long): class C { int x; this(int y) { x = y; } inout(int*) foo() inout { return x; } void bar(void delegate(int*) f) { f(x); } void bar(void delegate(const(int*)) f) const { f(x); } void bar(void delegate(immutable(int*)) f) immutable { f(x); } } void main() { immutable(int)* wah; void wahwah(immutable(int*) x) { wah = x; } auto c = new immutable(C)(10); wahwah(c.foo); // why is this privilegied with inout c.bar(wahwah); // and this not? writeln(*wah); } Can't use void delegate(const(int*)) there. Thanks for clarifying, I didn't quite understand the usage before. This is a limitation of inout's design. Technically inout requires a single inout output, and can have multiple inout inputs. Your example matches that description, so in theory it's possible. I realized last night that this won't work. Simple reason -- during an inout function, the function promises to treat the arguments as if they were const. If your class instance was mutable, this would not be true, e.g.: class C { int x; void bar(void delegate(inout(int)* f) inout { f(x); } } void main() { auto c = new C; void dg(int *f) {*f = 10;} c.bar(dg); // modifies c, even though the function is marked as inout } -Steve Well, inout was conceived as a counter to where you need to write the exact same function for every type of constness, was it not? :-)
Re: Generic collection/element function signatures in D2 versus D1
On 09/07/2010 03:15 PM, Steven Schveighoffer wrote: On Tue, 07 Sep 2010 08:56:15 -0400, Jacob Carlborg d...@me.com wrote: On 2010-09-07 14:49, Steven Schveighoffer wrote: On Sun, 05 Sep 2010 09:40:59 -0400, BLS windev...@hotmail.de wrote: On 05/09/2010 02:16, Jonathan M Davis wrote: void foo(T)(T[] collection, T elem) { // Blah, whatever } I am curious, how this will look and feel once inout is working ? inout void foo(T)(inout(T)[] collection, inout T elem) { // Blah, whatever} } inout void doesn't make any sense. You can't have a const void or immutable void. Now, if foo is a member function, then inout applies to the this pointer, but even then, you need a return type other than void for inout to be used. -Steve inout is only used when you want to return the same constness (mutable, const, immutable) as you passed in to the function. If you don't want that, or don't want to return anything then const(T)[] is what you want. It will accept mutable, const and immutable. Yes, exactly. This is why inout functions cannot return void. -Steve Hmm. class C { void foo(void delegate(inout(C)) f) inout { f(this); } } Am I missing something?
Re: Generic collection/element function signatures in D2 versus D1
On 09/07/2010 04:33 PM, Steven Schveighoffer wrote: Yes, a valid return. Your function should be: void foo(void delegate(const(C) f) const It helps to understand that inout/const/immutable has NOTHING to do with code generation, it only has to do with limiting what compiles. For this reason, an inout function is compiled once, and works on all three constancies (4 if you have a nested inout function). For the entire function any inout variable is treated as a non-changeable value, just like const. Then when you return, it's converted at the call site back to the constancy with which it was called. If the return value is void, then there's nothing to convert, and no reason to use inout over const. I'll repeat -- there is no benefit to inout if you are not returning anything. -Steve That's not an equivalent function signature. Or maybe it is, but look at this (sorry it's so long): class C { int x; this(int y) { x = y; } inout(int*) foo() inout { return x; } void bar(void delegate(int*) f) { f(x); } void bar(void delegate(const(int*)) f) const { f(x); } void bar(void delegate(immutable(int*)) f) immutable { f(x); } } void main() { immutable(int)* wah; void wahwah(immutable(int*) x) { wah = x; } auto c = new immutable(C)(10); wahwah(c.foo); // why is this privilegied with inout c.bar(wahwah); // and this not? writeln(*wah); } Can't use void delegate(const(int*)) there.
Re: Understanding isInfinite(Range)
On 09/04/2010 02:11 PM, Simen kjaeraas wrote: Peter Alexander peter.alexander...@gmail.com wrote: == Quote from Steven Schveighoffer (schvei...@yahoo.com)'s article On Fri, 03 Sep 2010 11:12:29 -0400, Andrej Mitrovic andrej.mitrov...@test.com wrote: What does char[1 + Range.empty] do? It looks rather cryptic.. char[1+Range.empty] is a type. If Range.empty is a compile-time constant, then this type is valid, otherwise it's not valid (the is expression results to true if the argument is a valid type). If it's valid, then Range.empty never changes. If it never changes and it's always false, then it's infinite. -Steve That's really ugly code :-( Is there a way you could write an isStatic(expr) template? Using something like that would make the code a hell of a lot more readable. At the moment, the code itself does a very poor job of conveying what it's trying to accomplish. These SFINAE-like tricks should be black-boxed as much as possible, or (at the very least) commented so that people know what's going on. template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); } enum s = Hello; assert (isStatic!s); Gonna need more work than that.
Re: Understanding isInfinite(Range)
On 09/06/2010 08:53 PM, Philippe Sigaud wrote: On Mon, Sep 6, 2010 at 18:47, Pelle pelle.mans...@gmail.com mailto:pelle.mans...@gmail.com wrote: On 09/04/2010 02:11 PM, Simen kjaeraas wrote: Is there a way you could write an isStatic(expr) template? Using template isStatic( alias T ) { enum isStatic = is( char[1+T] ); } unittest { int n = 3; assert( !isStatic!n ); assert( isStatic!1 ); enum r = 5; assert( isStatic!r ); } enum s = Hello; assert (isStatic!s); Gonna need more work than that. Why? That's exactly the behavior we want, or so it seems to me. Sorry if I was unclear, that assert fails. Due to that you cannot add an integer and a string, not not that the string isn't static. It's an enum, so it definitely is static.
Re: SO rotate question
On 09/02/2010 10:24 PM, bearophile wrote: simendsjo: Suggestions for D-ifying the code is welcome. Your unit tests are not good enough, they miss some important corner cases. This my first version in D2: import std.string: indexOf; /// return True if s1 is a rotated version of s2 bool isRotated(T)(T[] s1, T[] s2) { return (s1.length + s2.length == 0) || (s1.length == s2.length indexOf(s1 ~ s1, s2) != -1); } unittest { // of isRotated assert(isRotated(, )); assert(!isRotated(, x)); assert(!isRotated(x, )); assert(isRotated(x, x)); string s = rotato; assert(isRotated(s, rotato)); assert(isRotated(s, otator)); assert(isRotated(s, tatoro)); assert(isRotated(s, atorot)); assert(isRotated(s, torota)); assert(isRotated(s, orotat)); assert(!isRotated(s, rotator)); assert(!isRotated(s, rotat)); assert(!isRotated(s, rotata)); } void main() {} Bye, bearophile This is what I wrote: bool isRotated(T)(T[] a, T[] b) { return a.length == b.length (a.length == 0 || canFind(chain(a,a), b)); } Use chain to avoid allocation. canFind isn't really the best possible name, is it?
Re: SO rotate question
On 09/03/2010 01:35 PM, bearophile wrote: Pelle: bool isRotated(T)(T[] a, T[] b) { return a.length == b.length (a.length == 0 || canFind(chain(a,a), b)); } Nice clean solution. I suggest to add pure and two const in the signature. canFind isn't really the best possible name, is it? Some name/APIs of Phobos are not the best possible, they were often invented by a single person. I don't know if contains() or isIn() are better. Bye, bearophile Heh, I actually tried that before posting, but chain doesn't seem to support const. :-) Should probably be two forward ranges, not two arrays, as well.
Re: built-in string hash ?
On 08/28/2010 10:25 PM, bearophile wrote: torhu: string a = abc; auto hash = typeid(a).getHash(a); If higher performance is necessary, you may pre-compute part of that: void main() { string a = abc; auto hash1 = typeid(a).getHash(a); auto stringHash =(typeid(a).getHash); auto hash2 = stringHash(a); assert(hash1 == hash2); } Bye, bearophile I doubt that gives any performance gains. typeid(a).getHash should be a constant expression anyway, and I don't see any gains in my tiny benchmark test. Perhaps it works better if a was an Object, since typeid for objects does more.
Re: associative array of associative arrays.
On 08/13/2010 01:17 AM, dcoder wrote: Hello. How do you declare and initialize a map that looks like the following: Name = [ Personal Info] Where personal info is type string[string]. I can't get this to compile. I'm wondering what I am doing wrong: import std.stdio; void main() { int[string] helloworld = [ Hello:0, World:1 ]; foreach( k,v;helloworld) { writefln( %s - %s, k, v); } writefln( helloworld type: %s, typeid(helloworld)); string[string] table = [ City:Boston, Title:Vice President ]; foreach( k, v; table) { writefln( %s: %s, k, v); } // Here's the problem: string[string[string]] leaders = [ Obama:[City:DC, Title:ThePrez], Cameron:[City:London, Title:DaPrimeMinista]]; foreach( k, v; leaders) { writefln( first foreach type: %s, typeid(v)); writefln( Person: %s, k); foreach( kk, vv; v) { writefln( \t%s\t%s, kk, vv); } } return; } Here's the output: $ dmd AssocArray.d AssocArray.d(25): Error: Integer constant expression expected instead of City AssocArray.d(25): Error: Integer constant expression expected instead of Title AssocArray.d(25): Error: Integer constant expression expected instead of City AssocArray.d(25): Error: Integer constant expression expected instead of Title AssocArray.d(24): Error: not an associative array initializer $ dmd --help Digital Mars D Compiler v2.047 Copyright (c) 1999-2010 by Digital Mars written by Walter Bright Documentation: http://www.digitalmars.com/d/2.0/index.html thanks dcoder This is probably a bug, I think I have run into it. Try this: string[string[string]] leaders; leaders[Obama] = [City:DC, Title:ThePrez]; leaders[Cameron] = [City:London, Title:DaPrimeMinista]; And if that doesn't work, try unfolding more :-) Probably should report this as a bug, as well.
Re: Problem with std.array(std.regex.splitter())
On 08/09/2010 12:50 AM, bearophile wrote: This D2 code: import std.regex: splitter, regex; import std.array: array; void main() { array(splitter(, abc, de, regex(, *))); } Gives the errors: test.d(4): Error: template std.array.array(Range) if (isForwardRange!(Range)) does not match any function template declaration test.d(4): Error: template std.array.array(Range) if (isForwardRange!(Range)) cannot deduce template function from argument types !()(Splitter!(string)) Do you know what's wrong in it? Bye and thank you, bearophile std.array.array() erroneously requires a forward range, where it should require an input range. Splitter also does not define save(), so it's not a forward range.
Re: std.file.read
On 08/02/2010 10:23 AM, Dmitry Olshansky wrote: On 02.08.2010 5:23, bearophile wrote: Can you tell me why std.file.read() returns a void[] instead of something like a ubyte[]? Well, it magically converts to whatever array type you have. So this works: ubyte[] data = read(trash.txt); This code does not work for me. It's interesting fact deserving further investigation. It seems that void[] arrays are converted implicitly, this also works: void[] tr = malloc(20)[0..20]; data = tr; Neither does this. I am running 2.047, am I doing something wrong?
Re: null dereference exception vs. segfault?
On 08/02/2010 11:27 PM, bearophile wrote: Ryan W Sims: The problem isn't how to check it on a case-by-case basis, there are plenty of ways to check that a given pointer is non-null. The problem is debugging _unexpected_ null dereferences, for which a NPE or its equivalent is very helpful, a segfault is _not_. I don't know what NPE is, but if you program with DbC your nulls are very often found out by asserts, so you have assert errors (that show line number file name) instead of segfaults. Null Pointer Exception! However, I agree with getting segfaults from them. Otherwise, you will be tempted to use the exception handling mechanisms to catch null pointer exceptions, which is a bad thing. I also agree with the notion of using DbC to find nulls. What I really wish for is non-nullable types, though. Maybe in D3... :P
Re: null dereference exception vs. segfault?
On 08/03/2010 12:02 AM, bearophile wrote: Pelle: What I really wish for is non-nullable types, though. Maybe in D3... :P I think there is no enhancement request in Bugzilla about this, I will add one. I think there has been, at least this has been discussed on the newsgroup. To implement this you have to think about the partially uninitialized objects too, this is a paper about it, given a class type T it defines four types (I think the four types are managed by the compiler only, the programmer uses only two of them, nullable class references and nonnullable ones): http://research.microsoft.com/pubs/67461/non-null.pdf If a language defaults to nonnullable references, then you can use this syntax: class T {} T nonnullable_instance = new T; T? nullable_instance; But now it's probably nearly impossible to make D references nonnullable on default, so that syntax can't be used. And I don't what syntax to use yet. Suggestions welcome. Bye, bearophile That is a good syntax indeed. What is also needed is a way of conditionally getting the reference out of the nullable. I think delight uses something like this: T? nullable; if actual = nullable: actual.dostuff; I think a good thing would be NonNull!T, but I haven't managed to create one. If this structure exists and becomes good practice to use, maybe we can get the good syntax in D3. In 20 years or so :P
Re: null dereference exception vs. segfault?
On 08/03/2010 12:32 AM, bearophile wrote: Pelle: I think a good thing would be NonNull!T, but I haven't managed to create one. If this structure exists and becomes good practice to use, maybe we can get the good syntax in D3. In 20 years or so :P Maybe we are talking about two different things, I was talking about nonnull class references/pointers, you seem to talk about nullable values :-) Both can be useful in D, but they are different things. Nullable values are simpler to design, they are just wrapper structs that contain a value plus a boolean, plus if you want some syntax sugar to manage them with a shorter syntax. Bye, bearophile I am talking about non-nullable references indeed. I don't think I mentioned nullable types, really. I also created this, as the simplest NotNull-type concievable: struct NotNull(T) if(is(typeof(T.init !is null))) { private T _instance; this(T t) { enforce(t !is null, Cannot create NotNull from null); _instance = t; } T get() { assert (_instance !is null, text(Supposed NotNull!(, T.stringof, ) is null)); return _instance; } alias get this; } This has the obvious bug in that you can declare a nonnull without an initializer and get a null from it. If we ever get @disable this(){} for structs, this struct can become better. I'll probably try it out in some code.
Re: null dereference exception vs. segfault?
On 08/03/2010 01:08 AM, bearophile wrote: Pelle: struct NotNull(T) if(is(typeof(T.init !is null))) { Is this enough? struct NotNull(T) if (is(T.init is null)) { this(T t) { enforce(t !is null, Cannot create NotNull from null); enforce() is bad, use Design by Contract instead (a precondition with an assert inside). Bye, bearophile If NotNull will be in a library, it should probably use enforce, if I have understood things correctly. External input, and all that. I think most of phobos does it like this currently.
Re: D2 map trouble
On 07/28/2010 12:57 AM, Nick Sabalausky wrote: Trying to convert some D1 code to D2: On 2.047, I'm trying to do this: import std.string; void foo(string str) { str = std.algorithm.map!( (char a) { return inPattern(a, [digits, letters])? a : '_'; } )(str); } And I'm getting: delegate std.algorithm.__dgliteral1 cannot access frame of function __dgliteral1 What's going on? How do I do it right? I figure I probably have some sort of problem with strings being immutable(char)[] instead of char[], but it doesn't look like that's the issue it's complaining about. Also, in this particular case, I'm not concerned about multi-unit UTF-8 characters. This is a compiler bug. Easy workaround: auto fn = (char a) { ... }; str = map!fn(str);
Re: Cannot initialize associative array.
On 06/23/2010 09:41 AM, Ali Çehreli wrote: Ali Çehreli wrote: dcoder wrote: So, I moved the initialization to inside the main function, and now it works. Great. I think we need to put this question in the FAQ. For future reference, if it really needs to be global: uint[string] mywords; static this() { mywords = [ Hello : 1, World : 1, Cat : 1, Dog : 1 ]; } Could someone please verify whether the above is really necessary? Is it actually a dmd bug that we need to use 'static this()' to initialize an associative array? Ali I say it's a bug, a literal like that should be a constant expression. Someone report it!
Re: opAddAssign still works
On 05/11/2010 01:38 AM, Trass3r wrote: Yeah it still works for compatibility reasons but is deprecated. Not yet, it's not. To compile something that's deprecated, you will need the -d switch. Right now, both are allowed, but the old one is scheduled for deprecation and presumably later removal. :)
Re: Fixed-size arrays on the heap
On 05/06/2010 01:10 PM, bearophile wrote: Lars T. Kyllingstad: In particular, note Kasumi Hanazuki's post and Andrei's response to it. Thank you, it seems Andrei agrees with me. But I think here thinks have to be kept tidy, otherwise it's easy to make a mess. The syntax offers various interesting possibilities for a future International Obfuscated D Code Contest: import std.stdio: writeln; struct Arr(int N) { int[N] data; alias data this; } void main() { auto p = new Arr!(10); *p = 10; writeln(p.data); // Output: 10 10 10 10 10 10 10 10 10 10 } This is not good :-( Bye, bearophile Which is why they decided that the [] will always be needed for array operations. Right?
Re: Operators overloading in D2 again
On 05/03/2010 04:28 PM, Dan wrote: Hi, it certainly helps. However I can't help myself, I still thinking that this is the most complicated, hard read and to understand way to overload operators. Maybe there is something I'm missing but I can't really see the reason of all that. Other languages adopts a much easier approach, for example python but also C++ that D is trying to surpass (and it does in most cases) when it comes to operator overloading is much more clear than D. I still thinking that the D1's approach was much better than this. The D way is superior, because you don't need to come up with arbitrary names, like the D1/Python way, and it's much easier to parse than the C++-way, at least I think it is. Anyway, now I have another problem: I can't get how to overload operators like these=,,=,. I read the documentation but I can't really understand it. http://digitalmars.com/d/2.0/operatoroverloading.html#compare You should define an opCmp. Thanks for the precious help guys. DAniele
Re: How to implement a copy
On 03/18/2010 05:43 PM, Paul D. Anderson wrote: If I'm implementing a struct and want to provide for duplication, is there a standard way to implement this? Here's an example: //--- struct S { // members of the struct -- three integer values int a; int b; int c; // here's a copy constructor this(S s) { this.a = s.a; this.b = s.b; this.c = s.c; } // here's the dup property S dup() { S s; result.a = this.a; result.b = this.b; result.c = this.c; return s; } // here's opAssign for S void opAssign(S s) { this.a = s.a; this.b = s.b; this.c = s.c; } } // end struct S // and here's a copy function S copy(S s) { S t; t.a = s.a; t.b = s.b; t.c = s.c; return t; } //--- Which of these three calls is better (more efficient, more intuitive, more consistent...)? S s;// the original struct S t = s.dup; // copied via dup S u = S(s); // copied via copy constructor S v = s; // copied via opAssign S w = copy(s); // copied via copy function Or is this a distinction without a difference? Paul this(this) is the copy constructor, I think. Try using that :)
Re: Tidy attributes
On 03/11/2010 10:20 PM, bearophile wrote: While looking for possible attribute problems to add to Bugzilla, I have seen the following D2 program compiles and runs with no errors or warnings: static foo1() {} static does not apply to free functions, I would guess this means the same as auto. final foo2() {} ref foo3() {} enum void foo5() {} Wow. nothrow foo4() {} pure foo6() {} Would guess for auto here. Not tidy, as you say :) static int x1 = 10; static x2 = 10; static here means 'known at compile time', I think. - What is a static global function in D? It means nothing, but I can't seem to find the documentation. It's just ignored. - A final global function? - Is that ref of void correct? (I think it is not) - A enum of void function? These are mysteries. - What are global static variables in D? variables evaluated at compile time, for example int cfte_able_function() { return 14423 + 12341; } int other_function() { writeln(Not cfte); return 7; } static x1 = 123; //works static x2 = cfte_able_function; //works; static x3 = other_function; //cannot evaluate other_function() at compile time As you say, these are odd issues indeed. :)
Re: Tidy attributes
On 03/11/2010 10:44 PM, bearophile wrote: As far as I know, it's enum that has that purpose. Oh, but they are not the same. enum declares a constant, whereas static declares a variable. A static global is still mutable. Thank you for your answers, bearophile Why thank you!
Re: Static attributes aren' immutable
On 03/05/2010 07:50 PM, bearophile wrote: div0: putting it in Foo simply puts it in a namespace. So my (wrong) idea of immutable applied to a struct was that every thing in such namespace becomes immutable (I think this is a bit more intuitive). What do you think of modifying D2 so in a situation like the one I've shown even static arguments become const/immutable? Can this cause troubles to other things? Thank you to you and Lars T. Kyllingstad for the answers. Bye, bearophile Immutability (somewhat) guarantees the value will never ever change. The static attribute could be changed by a non-immutable instance, and can therefore not be immutable. It could be const for the immutable instance, but I don't see the gains from it. I do, however, see the gains from not being able to access the static members through an instance.
Re: raii
On 02/28/2010 09:16 PM, Ellery Newcomer wrote: Hello The impetus: I agree, except I more and more think that scope classes were a mistake. Structs with destructors are a much better solution, and wrapping a class inside a struct would give it RAII semantics. The problem: In designing a library (or rather touching up someone else's library), I have a class (interface?) Foo, and it has a method close (actually several methods). Almost invariably (although conceivably not always), usage involves manipulating Foo, and then remembering to call close. That last part is obnoxious. One obtains a Foo from function foo. What I'd like is for the result of foo to have RAII semantics by default, with the possibility of nixing it if the user actually cares. I want to take the burden of remembering that stupid close off the user. For example: void bar(){ auto a = foo(); a.doStuff(); } has an implicit call to close after doStuff. The impetus suggests I can do this by wrapping Foo inside a struct, but I'm not so sure how well this would work out. Also note that close can fail in a number of ways relating to file io. So I wrote up a simple prototype. Thoughts? import std.stdio; class Foo{ int k; this(int i){ writefln(bin %d,k); k = i; } void doStuff(){ writefln(do stuff %d,k); } void close(){ writefln(close %d,k); } } struct RAII(T){ T b; bool extracted = false; alias b this; this (T i){ assert(i !is null); writeln(in); b = i; } ~this(){ writeln(~this); if(!extracted) b.close(); } T extract(){ assert(!extracted); T t = b; b = null; extracted = true; return t; } } RAII!(Foo) foo(int i){ return RAII!(Foo)(new Foo(i)); } void main(){ auto a = foo(1); auto b = foo(2).extract(); a.doStuff(); b.doStuff(); } Maybe something along the lines of this struct RAII(T : Object){ T b; alias b this; void delegate(T) destroyer; this (T i, void delegate(T) called_at_exit){ b = i; destroyer = called_at_exit; } ~this(){ if (b) destroyer(b); } T extract(){ T t = b; b = null; return t; } } class Foo { this() { } void close() { writeln(closed.); } } RAII!Foo foo() { return RAII!Foo(new Foo, (Foo f) {f.close;}); } for a slightly more generalized RAII struct, which works on classes only.
Re: running an external .exe
On 02/16/2010 08:09 PM, Funog wrote: Is it possible to run an external .exe and have access to its standard input/output? Apparently std.process does not allow this. You'll want to choose either the input or the output stream, otherwise you might get eaten by a deadlock.
Re: Why isn't == used to compare structs
On 02/08/2010 01:48 PM, Trass3r wrote: Why isn't == used to compare the struct members in the code above? I mean, if I compare the structs with == it could also use == to compare the members. If I use is to compare the structs it could use is to compare them members. Structs are compared *bitwise*! When you dup your pointer is different and thus the structs are different. I believe the question was *why* things are this way. I think it's weird.
Re: default opAssign(string) behaviour
On 01/28/2010 02:32 AM, strtr wrote: Personally, I use (D1)std2.conv a lot to get values from strings and thus would love the following default behaviour for all types: int i = 0; // i = 0 i = cast( int ) 0; // i = 48 ( If I read the utf8 table correctly ) What keeps this from being the case? Strong typing, mostly. It's messy. to!int(0) is seriously pretty, though. :)
Re: boolean over multiple variables
On 01/26/2010 01:02 AM, Nick Sabalausky wrote: strtrst...@spam.com wrote in message news:hjd6t1$be...@digitalmars.com... This may be is a very basic question, but is there a way to let me omit a repeating variable when doing multiple boolean operations? if ( var == a || var == b || var == c || var == d) if ( var == (a || b || c || d) ) I do this: - import tango.core.Array; void main() { if( [3, 5, 6, 12].contains(7) ) { } } - There's probably a phobos equivilent, too. Alhough, I would much prefer what other people mentioned about having in refer to the values of a collection rather than the keys. But I've been using the above as a substitute. I think in should work for keys in an associative array and for values in a regular array. This is how it works in python.
Re: boolean over multiple variables
On 01/23/2010 12:29 AM, strtr wrote: Simen kjaeraas Wrote: Not tested, but they should work: if ( anySame( var, a, b, c, d ) ) { } if ( allSame( var, a, b, c, d ) ) { } A lot prettier. I thought there would be a generic (basic) solution to this which I just didn't know about but maybe I actually do know the basics by now :) -- Simen If we get opIn_r for arrays, you can do if (var in [a, b, c, d]) { } Which I find a lot prettier.
Timer library?
I'm in need for a timer library that measures the acutal time. I have tried std.c.time's clock(), but it only measures time spent inside the program, not actual time elapsed. I need at least millisecond resolution, so std.c.time.time() is not an option. I wonder, is there a good library for this?
Re: Timer library?
On 01/25/2010 04:02 PM, strtr wrote: Stanislav Blinov Wrote: Pelle M�nsson wrote: I'm in need for a timer library that measures the acutal time. I have tried std.c.time's clock(), but it only measures time spent inside the program, not actual time elapsed. I need at least millisecond resolution, so std.c.time.time() is not an option. I wonder, is there a good library for this? Have you tried std.date? :-) and there is of course the undocumented std.perf. It seems std.perf is indeed suitable. Thank you!