Re: File IO: C# streams VS iterators?
On 11/8/13, 8:57, DDD wrote: I was watching a dconf talk about porting C# code to D. One thing that came up was there isn't anything like C# streams for D. Walter said he thinks iterators (unless I remember wrong) is superior. The speaker agreed but said it isn't a drop in replacement so that is an issue if you want to port. I haven't access file in D and i'm completely confused. What are iterators in regards to file IO? There are several ranges that can be used for file IO, for example http://dlang.org/phobos/std_stdio.html#.File.byChunk and http://dlang.org/phobos/std_stdio.html#.File.byLine . C# Stream has no such capability, which is why you have TextReader and TextWriter on top of streams, etc.. However, sometimes it's useful to have polymorphism for accessing streams, especially when porting C#/java code to D. In that case it would be pretty trivial to port the base classes to D and implement them using the D ranges. L.
Re: Static arrays passed by value..?
On 2010-08-07 9:26, simendsjo wrote: The spec for array says: Static arrays are value types. Unlike in C and D version 1, static arrays are passed to functions by value. Static arrays can also be returned by functions. I don't get the "static arrays are passed to functions by value" part. Here I am passing in a static and dynamic array. Both are passed by value, and the function can modify the array of both { void func(int[] arr, void* ptr) { arr[0] = 9; assert(&arr != ptr); } int[3] a = [1,2,3]; func(a, &a); assert(a == [9,2,3]); // changed.. int[] b = [1,2,3]; func(b, &b); assert(b == [9,2,3]); } When you use "int[]" as the parameter type, the array is passed by reference as a slice of the original array. If you write the function like this: fund(int[3] arr, void* ptr) {...} Now the array is passed by value and a copy is made.
Human stupidity or is this a regression?
Perhaps should have written "and/or" in the subject line since the two are not mutually exclusive. I was showing off D to friends the other day: import std.stdio; void main() { foreach (d; "你好") writeln(d); } IIRC, this used to work fine, with the variable "d" getting deduced as "dchar" and correctly reassembling the UTF-8 bytes into Unicode codepoints. But when I run this code in OSX, dmd v2.064, I get this: $ dmd -run uni.d � � � � � � It's clearly printing the bytes. When I print the typeof(d) I get "immutable(char)", so that confirms the type is not deduced as "dchar". I could have sworn this used to work. Is my memory failing me, or was this a deliberate change at some point? Perhaps a regression? L.
Re: get address of object if opCast is overridden
On 12/2/12, 21:25, js.mdnq wrote: I'm not just comparing them but using them as a unique ID for the objects in an algorithm to prevent computing over the same object more than once. o.toHash() ?? (Which incidentally just casts the reference to a hash_t, exactly what you want to do.)
Re: Human stupidity or is this a regression?
On 12/26/13, 11:58, bearophile wrote: Lionello Lunesu: I could have sworn this used to work. Is my memory failing me, or was this a deliberate change at some point? Perhaps a regression? It's not a regression, it's a locked-in design mistake. Write it like this and try again: foreach (dchar d; "你好") Bye, bearophile Yeah, that's what I ended up doing. But D being D, the default should be safe and correct. I feel we could take this breaking change since it would not silently change the code to do something else. You'll get prompted and we could special case the error message to give a meaningful hint. L
Re: dmd simple loop disassembly - redundant instruction?
On 12/25/13, 20:03, Ivan Kazmenko wrote: - L2C:mov-03D0900h[EDX*4][EBP],EDX movECX,EDX incEDX cmpEDX,0F4240h jbL2C - You should have said that all instructions are redundant :) Looks like the array got optimized out, but then the optimizer stopped. The ECX likely refers to the 'i' loop variable. When the array write code got optimized out, the compile could have figured out that 'i' was in turn unused as well and remove it too. And then, the foreach, etc... You can file backend bugs on the same site.
Re: enum to string
Nick Sabalausky wrote: Is there any way to do this (preferably in D1) with reflection? (ie, without having to manually create a conversion func/lookup for every value of every enum.) -- enum Shape { Square, Circle } char[] foo(Shape s) { // ? } // Either one of these, I don't really care which assert(foo(Shape.Square) == "Shape.Square"); assert(foo(Shape.Square) == "Square"); -- You got to give it to Walter: the code is pretty clean (for C++ code anyway) Add the attached code to src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif). This now works: import std.stdio; enum ABC { A, B, C }; void main(string[] args) { foreach(a; ABC.tupleof) { writefln(a); } } prints: A B C Of course, I'm way over my head here. I've just copied the code from struct.tupleof to make enum.tupleof and creating a tuple of StringExps insteadof DotVarExps, whatever they are L.
Re: enum to string
Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a patch to the DMD source was not really what you expected. I just got so anxious! L.
Re: enum to string
Your attachment is zero-byte. Oops... Try this one.. /* Create a TupleExp out of the fields of the struct e: * (e.field0, e.field1, e.field2, ...) */ e = e->semantic(sc);// do this before turning on noaccesscheck Expressions *exps = new Expressions; exps->reserve(sym->members->dim); for (size_t i = 0; i < sym->members->dim; i++) { EnumMember *em = ((Dsymbol *)sym->members->data[i])->isEnumMember(); char* s = em->ident->toChars(); Expression *fe = new StringExp(e->loc, s, strlen(s), 'c'); exps->push(fe); } e = new TupleExp(e->loc, exps); Scope sss; e = e->semantic(&sss);
Re: enum to string
Nick Sabalausky wrote: "Lionello Lunesu" wrote in message news:gpc4j3$30a...@digitalmars.com... Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a patch to the DMD source was not really what you expected. I just got so anxious! L. Hey, solutions are solutions :) In fact I may very well try that out. I'm not particularly keen on using an ugly mixin to declare all my enums just so that I can use a simple reflection feature like that (which I'd mostly just be using for debugging info anyway). I'm really glad it's so easy to hack stuff into the compiler. Although I'm still strugling to get these new "string expression" to evaluate at compile time. The enum.tupleof is done at compile time, the foreach as well, but I cannot pragma(msg) the values, nor can they be mixin-ed.. Must be some constness flag somewhere? L.
Re: enum to string
cr*p, I've pasted too little. Try this one instead.. I'll use a proper diff tool next time.. /* If e.tupleof */ if (ident == Id::tupleof) { /* Create a TupleExp out of the fields of the struct e: * (e.field0, e.field1, e.field2, ...) */ e = e->semantic(sc);// do this before turning on noaccesscheck Expressions *exps = new Expressions; exps->reserve(sym->members->dim); for (size_t i = 0; i < sym->members->dim; i++) { EnumMember *em = ((Dsymbol *)sym->members->data[i])->isEnumMember(); char* s = em->ident->toChars(); Expression *fe = new StringExp(e->loc, s, strlen(s), 'c'); exps->push(fe); } e = new TupleExp(e->loc, exps); Scope sss; e = e->semantic(&sss); return e; }
Re: enum to string
//src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif): /* If e.tupleof */ if (ident == Id::tupleof) { /* Create a TupleExp out of the fields of the struct e: * (e.field0, e.field1, e.field2, ...) */ e = e->semantic(sc); // do this before turning on noaccesscheck Expressions *exps = new Expressions; exps->reserve(sym->members->dim); for (size_t i = 0; i < sym->members->dim; i++) { EnumMember *em = ((Dsymbol *)sym->members->data[i])->isEnumMember(); char* s = em->ident->toChars(); Expression *fe = new StringExp(e->loc, s, strlen(s), 'c'); exps->push(fe); } e = new TupleExp(e->loc, exps); Scope sss; e = e->semantic(&sss); return e; }
Re: enum to string
"Brad Roberts" wrote in message news:alpine.deb.2.00.0903121755240.4...@bellevue.puremagic.com... That said, I don't think this really helps the desired usecase much. It's useful, don't get me wrong, but still requires code to build up the bi-directional translations. Or am I missing something? Seems to be happening to me a lot lately, so I'm very prepared to be wrong here too. :) You're not wrong :) The problem is that the foreach variable is not evaluatable to a compile-time string. I don't know why, but I'll figure it out tonight. I've also managed to convert an enum to an AssocArrayLiteralExp* (with the name/string as the key and the value/int as the value) but it seems that it cannot be foreached at compile time, even if it's a literal expression. But hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty sure it's possible with a little more research. I want to get either one to work at compile-time. In the case of TupleExp, one could then use a string mixin to convert the string to a value. L. * I don't have the AA patch handy (I'm at work) but it's a good exercise: start with my original tupleof patch but create an AssocArrayLiteralExp instead of the TupleExp. You'll need two Expressions arrays, one for keys and one for values. EnumMember::ident is the name, EnumMember::value is the value expression. Pretty straightforward.
[static] [shared] [const|immutable]
I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post. Surely, some combinations should/can be disallowed? * What's the point of "shared immutable"? * What about a locally declared "shared" variable? (The stack is implicit TLS anyway.) * Come to think of it, what's the difference between a "const int" and a "immutable int"? (Is "const" only meant to be used in a function's argument list?) L. (From the results it's apparent that "static" on the global level does not actually do anything (probably kept for C/C++ compatibility where it's used to mean "private") and that "static" used locally declares the variable as if it were global. This makes sense.) //The code: int f = 0xDEAD0001; //0678 const int cf = 0xDEAD0002;//068d immutable int _if = 0xDEAD0003;//068d shared int sf = 0xDEAD0011;//068d shared const int scf = 0xDEAD0012; //068d shared immutable int sif = 0xDEAD0013; //068d static int Sf = 0xDEAD0101;//0678 static const int Scf = 0xDEAD0102; //068d static immutable int Sif = 0xDEAD0103; //068d static shared int Ssf = 0xDEAD0111; //068d static shared const int Sscf = 0xDEAD0112; //068d static shared immutable int Ssif = 0xDEAD0113; //068d int main() { int f_ = 0xDEAD1001; //073c** const int cf_ = 0xDEAD1002;//073c* immutable int if_ = 0xDEAD1003; //073c* shared int sf_ = 0xDEAD1011;//073c** shared const int scf_ = 0xDEAD1012; //073c* shared immutable int sif_ = 0xDEAD1013; //073c* static int Sf_ = 0xDEAD1101;//0678 static const int Scf_ = 0xDEAD1102; //068d static immutable int Sif_ = 0xDEAD1103; //068d static shared int Ssf_ = 0xDEAD; //068d static shared const int Sscf_ = 0xDEAD1112; //068d static shared immutable int Ssif_ = 0xDEAD1113; //068d // prevent optimization return f+cf+_if+sf+scf+sif+Sf+Scf+Sif+Ssf+Sscf+Ssif+ f_+cf_+if_+sf_+scf_+sif_+Sf_+Scf_+Sif_+Ssf_+Sscf_+Ssif_; } // The numbers in comments represent the sections as printed by dumpbin: //0678 LED386 (TLS?) //068d LED386 (global) //073c CMD386 (code) //* only appears in obj when compiled with -g //** does not appear in obj when compiled with -O
Re: [static] [shared] [const|immutable]
"Christopher Wright" wrote in message news:gugs7b$70...@digitalmars.com... Lionello Lunesu wrote: I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post. The decision to make a variable a static class or module member is independent of whether to make it shared or not. You're right, of course. I realize now that "static" is a storage class (when used locally) not a type modifier. Shared and const-level have to do with controlling access to the variable. An immutable variable does not need to be declared shared. So, immutable implies shared. Shared const is for publish-subscribe sort of deals. You mean one thread can change the value, but for another thread it's constant? I can see how it would be useful using reference types, but I don't understand how it would work with value types.. Shared mutable is for cooperative writing to the variable. This one I understood :) The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble. As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please? Thanks, L.
Re: [static] [shared] [const|immutable]
Christopher Wright wrote: Lionello Lunesu wrote: "Christopher Wright" wrote in message news:gugs7b$70...@digitalmars.com... Lionello Lunesu wrote: I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post. The decision to make a variable a static class or module member is independent of whether to make it shared or not. You're right, of course. I realize now that "static" is a storage class (when used locally) not a type modifier. Shared and const-level have to do with controlling access to the variable. An immutable variable does not need to be declared shared. So, immutable implies shared. Immutable is threadsafe. Shared implies automatic locking, I believe; immutable variables do not need any locking. So one has to wonder what code will be generated for "shared immutable".. an immutable with (useless) locking? Shared const is for publish-subscribe sort of deals. You mean one thread can change the value, but for another thread it's constant? I can see how it would be useful using reference types, but I don't understand how it would work with value types.. Shared const doesn't really work for value types; it ends up being the same as immutable. Unless you have a mutable pointer to the value, in which case you can write to the value through that pointer. That is not safe -- the compiler is free to see that this variable is const and a value type, which means you can't ever write to it, and then put it in read-only memory. Const that doesn't boil down to immutable works a fair bit better with object-oriented code. You wrap your value in a class, create a mutable instance, and send it to a bunch of other functions or objects or threads expecting a const object. They can't use the mutators, but they can use the accessors. Got it. Thanks.. L.
Re: [static] [shared] [const|immutable]
BCS wrote: Hello Lionello, "Christopher Wright" wrote in message The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble. As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please? // without lookin up the details of threading void main() { int i; with(new Thread({i++;})) { Start(); Wait(); } } :O Indeed, that works! Which is scary, since the compiler did not detect the access to 'i' from another thread. In this case the code is safe, but only because of the Wait/join at the end.. This looks like a hole in the shared/tls system and there's nothing the compiler can do about it. :( L.