Re: The Thermopylae excerpt of TDPL available online
Justin Johansson, el 30 de octubre a las 08:42 me escribiste: Actually, I think I like that better than 'traits'. -Lars I'm in agreement with whoever suggested 'meta' or just about anything else except 'traits'. 'meta', whilst perhaps an overloaded keyword, is still much more user-friendly. Whenever I see 'traits' I get the feeling I need a Ph.D. to understand what it's about. For some reason, I don't know why, 'meta' has an aire of karma about it. compiler? That could open the door to other types of access to compiler internals, AST, etc. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Yo soy peperino el que siempre pone el vino, yo soy aquel que come los huevos con tocino. -- Peperino Pómoro
Re: The Thermopylae excerpt of TDPL available online
Lars T. Kyllingstad, el 30 de octubre a las 08:55 me escribiste: Leandro Lucarella wrote: Walter Bright, el 29 de octubre a las 16:06 me escribiste: Lars T. Kyllingstad wrote: What I cannot for the life of me understand is WHY the double underscores? What's wrong with just traits? Because D needed the feature, and it wasn't clear what a good syntax for it would be. So __traits is a put something out there, make it work, if it proves its usefulness and a good syntax for it appears, then that can be adopted. And now, being moderately close to D2 stabilization, isn't a good moment to think about a better syntax or just live with traits() as it is (but without the leading __)? Same for __gshared. I'm not convinced about __gshared. As far as I've understood, __gshared is a don't use this unless you know what you are doing feature. As such, it should probably be a bit ugly. D is a system programming language. I don't see why one should be over patronizing. It's enough to clarify what the keyword does in the documentation. __gshared is not *that* rare, if you are interfacing with C, every C global have to be __gshared, it just makes the code uglier for no reason. Maybe it can be renamed to cglobal? I think we need a good descriptive name so people can know what it's about, not an ugly obfuscated one to confuse and scare them. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- I can't watch TV for four minutes without thinking I have five serious diseases. Like: Do you ever wake up tired in the mornings? Oh my god I have this, write this down. Whatever it is, I have this.
Re: Followup Poll: Why tango trunk instead of 0.99.8?
Nick Sabalausky, el 29 de octubre a las 21:18 me escribiste: If you use (or admin a project that requires) Tango trunk instead of 0.99.8: Why? (Select all that apply) http://www.micropoll.com/akira/mpview/704493-212991 It's missing an answer: Tango doesn't release fast enough and doesn't maintain (do bug-fixes-releases for) released versions. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- PADRES DENUNCIAN QUE SU HIJA SE ESCAPO CON UN PARAGUAYITO -- Crónica TV
Re: Success! (Precisely)
dsimcha, el 30 de octubre a las 05:08 me escribiste: After a few evenings of serious hacking, I've integrated precise heap scanning into the GC. Right now, I still need to test it better and debug it, but it at least basically works. I also still need to write the templates to generate bit masks at compile time, but this is a simple matter of programming. A few things: 1. Who knows how to write some good stress tests to make sure this works? If somebody have this, I'm very interested too. Being D2 it will be much harder to find programs to test. I found Dil to be a good candidate for testing, at least it failed with some bugs other smaller, simpler test didn't. But it's for D1. And congratulations! Great news. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Cada movimiento que no se hace, es un movimiento que se pierde. Y cada movimiento que se pierde, se transforma en una mochila. Y las mochilas nos alejan, de nuestros amigos y nuestras amigas. Y nuestros amigos se transforman, en enemigos y en enemigas. Cada movimiento que se hace, es una mochila que se deja.
Re: associative arrays: iteration is finally here
Andrei Alexandrescu, el 28 de octubre a las 20:29 me escribiste: Your test looks something up and then removes it. Andrei Well, my extended test case looks something up, manipulates the found value, and then possibly removes it. Ok, I understand your points, thanks for explaining. What about and overload of remove() like this: bool remove(in T key, out U value); If the element was present, it's returned in value, so you can manipulate it. I thought about just returning a pointer: U* remove(in T key); But I guess that pointer would point to the element stored in the the AA private data, but that element was just removed, so bad things would happen, that's why the only option is to copy the data, right? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Y no es el centro del Universo! El sol gira alrededor de la tierra! Miles de girasoles no pueden estar equivocados! -- Inodoro Pereyra
Re: The Thermopylae excerpt of TDPL available online
Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste: It's a rough rough draft, but one for the full chapter on arrays, associative arrays, and strings. http://erdani.com/d/thermopylae.pdf Any feedback is welcome. Thanks! It looks very nice. A small error in 4.1.7 first code block: auto a = new double[4]; // must be already allocated auto a1 = [ 0.5, -0.5, 1.5, 2 ]; auto a2 = [ 3.5, 5.5, 4.5, -1 ]; a[] = (a1[] + a2[]) / 2; // take the average of b and c ^^^ take the average of a1 and a2? (I think it would be easier to follow using b and c though ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Cuando intenté arrimarle mi brazo Se puso a hablar de Miller, de Anais Nin y Picasso Y si osaba intentar robarle un beso Se ponía a leer de Neruda unos versos Me hizo mucho mal la cumbiera intelectual
Re: The Thermopylae excerpt of TDPL available online
Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste: Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste: It's a rough rough draft, but one for the full chapter on arrays, associative arrays, and strings. http://erdani.com/d/thermopylae.pdf Any feedback is welcome. Thanks! It looks very nice. A small error in 4.1.7 first code block: auto a = new double[4]; // must be already allocated auto a1 = [ 0.5, -0.5, 1.5, 2 ]; auto a2 = [ 3.5, 5.5, 4.5, -1 ]; a[] = (a1[] + a2[]) / 2; // take the average of b and c ^^^ take the average of a1 and a2? (I think it would be easier to follow using b and c though ;) BTW, it looks like array literals will be dynamic arrays, from the code in your book. Can you or Walter explain why this is better to make array literals statically stored immutable memory like strings (which adds an inconsistency to the language)? Is this just to avoid [1,2,3].dup; when you want to get a dynamic array from an array literal or is there other reasons? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- En la calle me crucé con un señor muy correcto, que habitualmente anda en Falcon; iba corriendo con dos valijas en la mano y dijo: Voy para Miami, tiene algún mensaje o ... y le dije: No, no, no... -- Extra Tato (1983, Triunfo de Alfonsín)
Re: The Thermopylae excerpt of TDPL available online
Andrei Alexandrescu, el 29 de octubre a las 12:23 me escribiste: Leandro Lucarella wrote: Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste: Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste: BTW, it looks like array literals will be dynamic arrays, from the code in your book. Can you or Walter explain why this is better to make array literals statically stored immutable memory like strings (which adds an inconsistency to the language)? Is this just to avoid [1,2,3].dup; when you want to get a dynamic array from an array literal or is there other reasons? I don't have a better explanation than the excerpt: Beware, however: if you replace @int[3]@ above with @auto@, @a@'s type will be deduced as @int[]@, not @int...@. Although it seems logical that the type of \cc{[1, 2, 3]} should be @int[3]@ which in a way is more ``precise'' than @int[]@, it turns out that dynamically-sized arrays are used much more often than fixed-size arrays, so insisting on fixed-size array literals would have been a usability impediment and a source of unpleasant surprises. Effectively, the use of literals would have prevented the gainful use of @a...@. As it is, array literals are @T[]@ by default, and @T[n]@ if you \emph{ask} for that specific type and if @n@ matches the number of values in the literal (as the code above shows). I saw that, but I think introducing an inconsistency (and depart on how literals usually work) is worse than having to explicitly state the type or adding a .dup to the literal. But I guess it's just me. Another question about the book: you explain dynamic arrays are being represented by a start and end pointer, much like the STL, but that's not the real implementation. I know you say in the book that the implementation doesn't necessarily work like that, but I wonder if you decided to explain things like that because it's planned to change the dynamic arrays implementation or just because you found it more didactic. Thanks. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Algún día los libros desterrarán a la radio y el hombre descubrirá el oculto poder del Amargo Serrano. -- Ricardo Vaporeso. El Bolsón, 1909.
Re: associative arrays: iteration is finally here
Andrei Alexandrescu, el 29 de octubre a las 12:33 me escribiste: Bill Baxter wrote: I think bool remove(key) is better than all other designs suggested so far. I agree with the folks who say it's error-prone. I can just see myself now removing a key I know is in the dictionary and being baffled when my program fails somewhere later on because I typed aa.remove(theKey) when it should have been aa.remove(thekey). I knew it was there so I didn't want to clutter up my code with a check for it. I don't find this reasonable. If you know removal must have succeeded, just type enforce(aa.remove(theKey)). I don't think I don't agree, this is like saying you should bound-check every array access. I think it's nice to have safety by default. If you are expecting to have an error, you will be extra careful to spell the key correctly. This should cover the cases where you are distracted and not expecting any errors. I think the check could be done in non-release mode only though, just like bound checking. that's the overwhelmingly common case though, and if it's, say, about 50/50, then it's much more sensible to have a non-throwing primitive than a throwing one. And it looks like defining two primitives just to save a call to enforce is not a good design. This is one case where I think practicality beats purity, because the whole point of throwing an exception is for the cases you don't expect it to fail. Again, think of array bounds, you can force the programmer to add lots of enforce() in the code and remove bound checking from the compiler. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- EXPOSICION INTERNACIONAL DE INODOROS -- Crónica TV
Re: associative arrays: iteration is finally here
KennyTM~, el 30 de octubre a las 02:55 me escribiste: On Oct 30, 09 01:14, bearophile wrote: KennyTM~: Um what? aa[theKey] = 1 doesn't fail, why should aa.remove(theKey) be special? That's a different situation. You probably meant to say: If aa[theKey]++; doesn't fail, why should aa.remove(theKey) be special? void discard(K,V)(ref V[K] aa, in K key) { if (!aa.remove(key)) assert(false); } This is stupid. Part of the point of built-in AAs is to avoid to import things. If I need to import (or worse define) that discard template in all programs where I use an AA, then I will create my own AAs and I'll just import and use them in the first place. Bye, bearophile This does not contradicts with .remove() not throwing an exception when a key is not found. If you like you can put it in object.d. (Moreover, having .remove() to throw means you can't delete any dictionary items in nothrow functions. Sure you can silent it with try/catch but that's expensive.) Not if it's an Error instead of an exception. I think that should be the case, .remove() check should be like bound check, something done at non-release mode, not something to use in the regular flow of a program to avoid using opIn(). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Esta desenchufada la internet de ese televisor? -- Osvaldo Lucarella
Re: associative arrays: iteration is finally here
Andrei Alexandrescu, el 29 de octubre a las 13:26 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 29 de octubre a las 12:33 me escribiste: Bill Baxter wrote: I think bool remove(key) is better than all other designs suggested so far. I agree with the folks who say it's error-prone. I can just see myself now removing a key I know is in the dictionary and being baffled when my program fails somewhere later on because I typed aa.remove(theKey) when it should have been aa.remove(thekey). I knew it was there so I didn't want to clutter up my code with a check for it. I don't find this reasonable. If you know removal must have succeeded, just type enforce(aa.remove(theKey)). I don't think I don't agree, this is like saying you should bound-check every array access. I think it's nice to have safety by default. remove from an associative array is not unsafe. In the sense of memory corruption that's true. But your program will be at least leaking memory if you thought the key was present in the AA (the majority of the use cases for remove(), because come on, if you are removing something is because you think there are very good chances that the key is in the AA :). If your program then iterate the AA and there is a key that it doesn't supposed to be there, it will blow in very original, hard to track ways. What's the point of that? If you want to remove something you're not sure that it really is in the AA, you should use a safer method. Maybe try_remove(), or an extra parameter to remove() or maybe just ask first if key in aa (but this have an extra lookup, and I think that's the whole point that triggered this discussion). If you are expecting to have an error, you will be extra careful to spell the key correctly. This should cover the cases where you are distracted and not expecting any errors. I think the check could be done in non-release mode only though, just like bound checking. Bounds checking is eliminated in release mode solely for efficiency reasons. There is no other good reason to eliminate checks. But in Well, same for removing an inexistent key from an AA then :) the case of remove, the amount of work done is consistent enough to make a check negligible. Ok, but make it an Error, not an exception, so it can be used in nothrow functions. Removing an nonexistent key from an AA should be a programming error, except if you state in some way that you know that maybe the key is not there (which should be rare). that's the overwhelmingly common case though, and if it's, say, about 50/50, then it's much more sensible to have a non-throwing primitive than a throwing one. And it looks like defining two primitives just to save a call to enforce is not a good design. This is one case where I think practicality beats purity, because the whole point of throwing an exception is for the cases you don't expect it to fail. Again, think of array bounds, you can force the programmer to add lots of enforce() in the code and remove bound checking from the compiler. I can't think of array bounds. The situations are completely unrelated. I don't think they are *completely* unrelated. I agree is not exactly the same because array bound error automatically imply memory corruption and nonexistent key removal don't, but they are a bug in the vast majority of the cases. At least this is my experience. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Fitter, happier, more productive, comfortable, not drinking too much, regular exercise at the gym (3 days a week), getting on better with your associate employee contemporaries,
Re: The Thermopylae excerpt of TDPL available online
Andrei Alexandrescu, el 29 de octubre a las 13:30 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 29 de octubre a las 12:23 me escribiste: Leandro Lucarella wrote: Leandro Lucarella, el 29 de octubre a las 13:21 me escribiste: Andrei Alexandrescu, el 28 de octubre a las 23:38 me escribiste: BTW, it looks like array literals will be dynamic arrays, from the code in your book. Can you or Walter explain why this is better to make array literals statically stored immutable memory like strings (which adds an inconsistency to the language)? Is this just to avoid [1,2,3].dup; when you want to get a dynamic array from an array literal or is there other reasons? I don't have a better explanation than the excerpt: Beware, however: if you replace @int[3]@ above with @auto@, @a@'s type will be deduced as @int[]@, not @int...@. Although it seems logical that the type of \cc{[1, 2, 3]} should be @int[3]@ which in a way is more ``precise'' than @int[]@, it turns out that dynamically-sized arrays are used much more often than fixed-size arrays, so insisting on fixed-size array literals would have been a usability impediment and a source of unpleasant surprises. Effectively, the use of literals would have prevented the gainful use of @a...@. As it is, array literals are @T[]@ by default, and @T[n]@ if you \emph{ask} for that specific type and if @n@ matches the number of values in the literal (as the code above shows). I saw that, but I think introducing an inconsistency (and depart on how literals usually work) is worse than having to explicitly state the type or adding a .dup to the literal. But I guess it's just me. It's me as well. The decision didn't go without a fight (I had your viewpoint and Walter didn't). Oh, ok. Thanks for the fight ;) He convinced me with two arguments. One is that 90% of the time you actually want T[], not T[n]. I don't know how did he come up with that number. At least, talking about arrays that comes from a literal, I don't think that is the case. In a program I'm sure more than 90% of the array usage are dynamic arrays, but when talking about array literals I'm not very convinced, I think you usually just want an iterable from them. The second is that string literals already have dynamic (not static) type, although the most informative type would be fixed-size. Damn! Are you saying that this: auto s = hello; Really does something like this in C: char* s = gc_malloc(5, NO_SCAN); memcpy(s, hello, 5); ? I though it was just like C, a pointer to an statcally allocated memory block. What's the point to heap-allocate an immutable chunk of memory? Another question about the book: you explain dynamic arrays are being represented by a start and end pointer, much like the STL, but that's not the real implementation. I know you say in the book that the implementation doesn't necessarily work like that, but I wonder if you decided to explain things like that because it's planned to change the dynamic arrays implementation or just because you found it more didactic. We will change the implementation at some point, but right now I hope I made it clear enough it's about the notion of a bounded chunk of typed memory, than the representation of it. I think the point is taken, I was just curious about what's the plan. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Salvajes, de traje, me quieren enseñar Salvajes, de traje, me quieren educar
Re: TDPL reaches Thermopylae level
Andrei Alexandrescu, el 27 de octubre a las 19:32 me escribiste: Leandro Lucarella wrote: Bill Baxter, el 27 de octubre a las 13:12 me escribiste: They are? ...Then what is the point of wstring, dstring? They are all just different representations of Unicode. string, which is unicode in UTF-8, is good because it's the least wasteful for mostly ASCII text. And has a nice ASCII backwards compatibility story. dstring, which is unicode in UTF-32, is good because you have one element = one character. So it's good for doing substring and other text manipulations. wstring, which is UTF-16, is good because it lets you call Windows Unicode functions. Here's Daniel Keep's nice explanation: http://docs.google.com/View?docid=dtqh79k_1rbxfmb And here is a nice artible about Unicode and encodings: http://www.joelonsoftware.com/articles/Unicode.html Damn guys, with these good explanations, nobody's going to use the one in TDPL! BTW, seeing the explanation about Unicode in your book, one wonders why UTF-8, UTF-16 and UTF-32 character types are not simply called utf8, utf16 and utf32... -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Ya ni el cielo me quiere, ya ni la muerte me visita Ya ni el sol me calienta, ya ni el viento me acaricia
Re: associative arrays: iteration is finally here
Simen Kjaeraas, el 29 de octubre a las 22:06 me escribiste: bearophile bearophileh...@lycos.com wrote: In nothrow functions you can use a different method, like discard (or a similar name less intuitive than remove), that's like remove, but it doesn't throw and just returns false when the key was absent. The idea is to use the safer method by default and the less safe one as a performance optimization (or where you are sure you want that semantics) in the other places. Please elucidate, what is unsafe about deleting something that isn't there? A leak, if the key was wrong (not if the key was right but deleted before). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Soñé que tenia un caballo Que me trataba mejor que vos Tenia tan buena onda con ella Era mi yegua, mucho mas que vos
Re: The Thermopylae excerpt of TDPL available online
Walter Bright, el 29 de octubre a las 16:06 me escribiste: Lars T. Kyllingstad wrote: What I cannot for the life of me understand is WHY the double underscores? What's wrong with just traits? Because D needed the feature, and it wasn't clear what a good syntax for it would be. So __traits is a put something out there, make it work, if it proves its usefulness and a good syntax for it appears, then that can be adopted. And now, being moderately close to D2 stabilization, isn't a good moment to think about a better syntax or just live with traits() as it is (but without the leading __)? Same for __gshared. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Es mucho mas probable que el salchichón sea primavera a que la primavera sea salchichón. -- Peperino Pómoro
Re: GC Sentinel
bearophile, el 28 de octubre a las 03:52 me escribiste: Leandro Lucarella: I think that's used to check for memory corruption, by storing a known patter before and after the actual object. Then, each time you can, you check that the unused memory block is intact (meaning nobody wrote to an invalid memory area). Such things can be quite useful. Do you need to compile Phobos again to do that? Yes, it's added through a version statement. If that's true then handier (compile-time?) solutions can be found. What do you mean? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Se ha dicho tanto que las apariencias engañan Por supuesto que engañarán a quien sea tan vulgar como para creerlo
Ugly identifiers
Denis Koroskin, el 28 de octubre a las 08:05 me escribiste: I've recently updated to DMD2.035 (from DMD2.031 because all the later versions had issues with imports) and for the first time faced problems with shared modifier. I don't need shared and all my globals are __gshared (they are globally unique instances that don't need per-thread copies). BTW, will __gshared and __traits be renamed to something that doesn't hurt my eyes before DMD2 is finalized or we will have to live with that until the end of the ages? I don't remember if I'm missing any other ugly identifier. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- - Mire, don Inodoro! Una paloma con un anillo en la pata! Debe ser mensajera y cayó aquí! - Y... si no es mensajera es coqueta... o casada. -- Mendieta e Inodoro Pereyra
Re: associative arrays: iteration is finally here
Pelle Månsson, el 28 de octubre a las 15:48 me escribiste: Andrei Alexandrescu wrote: Walter has magically converted his work on T[new] into work on making associative arrays true templates defined in druntime and not considered very special by the compiler. This is very exciting because it opens up or simplifies a number of possibilities. One is that of implementing true iteration. I actually managed to implement last night something that allows you to do: int[int] aa = [ 1:1 ]; auto iter = aa.each; writeln(iter.front.key); writeln(iter.front.value); Two other iterations are possible: by key and by value (in those cases iter.front just returns a key or a value). One question is, what names should these bear? I am thinking of makign opSlice() a universal method of getting the all iterator, a default that every container must implement. For AAs, there would be a iterate keys and iterate values properties or functions. How should they be called? Thanks, Andrei aa.each, aa.keys and aa.values seem good names? I might be too pythonic, but aa.items sounds a little better for me ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Can you stand up? I do believe it's working, good. That'll keep you going through the show Come on it's time to go.
Re: GC Sentinel
bearophile, el 28 de octubre a las 13:19 me escribiste: Leandro Lucarella: If that's true then handier (compile-time?) solutions can be found. What do you mean? For example something run-time that doesn't work with a version(), like something that can be added to the GC API. If this is seen as too much slow or hard to do, then just the GC may be compiled, and used as separated dynamic lib. With LDC other intermediate solutions may be possible. Think of this problem from the point of view of someone that wants something handy. Debugging data structures is something I do often. You can compile just the GC as a shared object (.so) in Linux and then preload it to change just the GC implementation at dynamic-link-time. Just run: $ LD_PRELOAD=mygc.so ./myprogram If your GC with extra checks is compiled as a shared object in mygc.so. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Que barbaridad, este país se va cada ves más pa' tras, más pa' tras... -- Sidharta Kiwi
Re: TDPL reaches Thermopylae level
Bill Baxter, el 27 de octubre a las 13:12 me escribiste: They are? ...Then what is the point of wstring, dstring? They are all just different representations of Unicode. string, which is unicode in UTF-8, is good because it's the least wasteful for mostly ASCII text. And has a nice ASCII backwards compatibility story. dstring, which is unicode in UTF-32, is good because you have one element = one character. So it's good for doing substring and other text manipulations. wstring, which is UTF-16, is good because it lets you call Windows Unicode functions. Here's Daniel Keep's nice explanation: http://docs.google.com/View?docid=dtqh79k_1rbxfmb And here is a nice artible about Unicode and encodings: http://www.joelonsoftware.com/articles/Unicode.html -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- He cometido pecados, he hecho el mal, he sido víctima de la envidia, el egoísmo, la ambición, la mentira y la frivolidad, pero siempre he sido un padre argentino que quiere que su hijo triunfe en la vida. -- Ricardo Vaporeso
Re: GC Precision
dsimcha, el 27 de octubre a las 01:34 me escribiste: 2. Some concern has been expressed in the past about the possibility of using 4 bytes per block in overhead to store pointers to bitmasks. IMHO this concern is misplaced because in any program that takes up enough memory for space efficiency to matter, false pointers waste more space. Furthermore, if you're programming for a toaster oven, elevator controller, etc., you probably aren't going to use the standard out-of-the-box GC anyhow. This seems reasonable, but I don't see why we can't use a more efficient way to store this information in the GC. Implementation simplicity (to have a better GC now instead of a perfect GC in some point in a far future) is a good enough reason :) I'm just curious if you found any flaws in the scheme proposed by Frits or is just you want a simpler implementation. Two things: Implementation simplicity is one. As I've been alluding to, worse and works in practice is better than better and only exists on paper. The other Fair enough. is that I don't understand, in Frits's approach, how do you store the size of the object so you know how many bits to interpret as the mask? I guess you don't. You have a bin size, so you use the bin size. I guess you just mark unused words as being non-pointers, so they wont get scanned. ... I guess that doesn't work for arrays though. I remember some discussion about how to handle arrays, but I can't find it now... 3. The bitmask pointer would be stored at the end of every GC-allocated block for which a bitmask pointer is stored. The reason for using the end of the block instead of the beginning is just implementation simplicity: That way, finding the beginning of a block would work the same whether or not we have a bitmask pointer. Did you even consider storing this information outside the memory block (like the flags)? I think storing them in the memory block can be annoying if they are not stored always because now your fixed sized blocks are not fixed. It might be very easy to overcome this, but maybe thinking about the other option is worthy. The flags in the GC are designed to store single bits apparently. Also, as far as weak refs, we could use another high-order bit for that. I don't think anyone cares if (on 32-bit) T.sizeof is limited to about a gigabyte. I think at first sight it sounds reasonable, but I'm a little affraid of it; it can sound like 640K ought to be enough for anybody ;) I know it almost impossible to have a T.sizeof larger than 1GiB, but what if you hit that? I guess since you won't be creating more than one or two objects of that size (3 at most), I guess is pretty reasonable to say manage that memory yourself. The question is, how many high-order bits do we reserve? BTW, I'm not going to actually implement weak references unless I see an easy way to do it, we're only talking about reserving bits here. I wasn't talking about bitmaps, I was talking more generally. Even if you want to store a pointer to the array describing the offsets of the pointers, you could store that pointers in a separated memory block (not in the block reserved for the object itself). Again, I didn't thought about it, it was just something that popped in my mind. I guess is a little irrelevant just now, it's something that should be moderately easy to change in the future if it's proven to be better to store it elsewhere. I guess the bottom line is that IMHO precise heap scanning is really low-hanging fruit where the bang for the buck would be huge. Improving the GC in other ways raises some nasty issues, but in this case I really think the perfect is the enemy of the good. I'm not guaranteeing anything, but I think I might be able to have precise heap scanning up and running in a release or two if I really keep it simple and stupid. Agreed. I would like to know very much how things goes. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Just because you're paranoid, don't mean they're not after you.
Re: TDPL reaches Thermopylae level
Andrei Alexandrescu, el 27 de octubre a las 19:32 me escribiste: Leandro Lucarella wrote: Bill Baxter, el 27 de octubre a las 13:12 me escribiste: They are? ...Then what is the point of wstring, dstring? They are all just different representations of Unicode. string, which is unicode in UTF-8, is good because it's the least wasteful for mostly ASCII text. And has a nice ASCII backwards compatibility story. dstring, which is unicode in UTF-32, is good because you have one element = one character. So it's good for doing substring and other text manipulations. wstring, which is UTF-16, is good because it lets you call Windows Unicode functions. Here's Daniel Keep's nice explanation: http://docs.google.com/View?docid=dtqh79k_1rbxfmb And here is a nice artible about Unicode and encodings: http://www.joelonsoftware.com/articles/Unicode.html Damn guys, with these good explanations, nobody's going to use the one in TDPL! :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Vivimos en una época muy contemporánea, Don Inodoro... -- Mendieta
Re: Disallow catch without parameter (LastCatch)
grauzone, el 26 de octubre a las 08:44 me escribiste: Leandro Lucarella wrote: grauzone, el 25 de octubre a las 12:09 me escribiste: Right now, you can catch every exception with try { something; } catch { somethingelse; }. Can we get rid of this abomination before D2 is finalized? I claim that it's completely useless, and even more so, every single use of this is a bug. Why every use of this is a bug? Because you most likely catch more exception types than you really want. For example, a novice programmer is likely to write something like this: int x; try { x = convert(somestring); } catch { //convert throws some exception if convert() fails return -1; } This is a bug, because catch might catch and *hide* a runtime error like failing assertions. The programmer really wanted to write catch (ConversionException e). Even if he wrote catch (Exception e), he wouldn't catch runtime errors, and the code would be safe. OK, I see. What about rewriting: try { foo(); } catch { something(); } As: try { foo(); } catch (Exception) { something(); } (I mean the compiler)? I think a catch all is a nice feature for quickdirty scripts, it would be nice to keep it and fix the semantics. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Y cuando llegamos a nuestro hogar ella saca de su bolsillo derecho un casete de Ricardo Montaner y nos dice: Ponelo! Ponelo!; nos desilusionamos un poco, pero a esa altura... Todo da igual. -- Sidharta Kiwi
Re: GC Precision
dsimcha, el 26 de octubre a las 13:08 me escribiste: I just realized last night that D's templates are probably powerful enough now to generate bit masks that can be used for precise GC heap scanning. I'm halfway (emphasis on halfway) thinking of using this to try to hack the GC and make heap scanning fully precise except for the corner case of unions. However, this ties into several things that others in the D community are doing, so I want to gauge people's responses and make sure I'm not wasting effort on something that will be useless in 6 months. 1. Sean, Leonardo, whoever else may be working on GC implementations, have you by any chance broken ground on precise heap scanning already? Maybe you're talking about me. I didn't have the chance to play with this yet. My main goal is to make the collect run concurrently with the mutator, but I have been a little busy lately so I didn't make many advances yet. I will like to play with adding preciseness to the GC too if I have the time. 2. Andrei, Walter, how close are we to actually eliminating new from the language? If all allocations were done by either calling GC.malloc() or using templates that call GC.malloc(), then things would get a lot simpler than if I were to have to hack the compiler to make new pass type info to the GC. The runtime is already receiving the type information on the allocated object when new is used AFAIK, but this information is not propagated to gc_malloc(). So it shouldn't be too hard to add type information to the GC. There was some interesting discussion about this some time ago. http://www.digitalmars.com/d/archives/digitalmars/D/Std_Phobos_2_and_logging_library_87794.html#N87831 3. I'm thinking bit masks could be stored as follows: When getBitMask!(T) is instantiated, it generates an immutable size_t[N]. Element 0 is the size of the array (to allow for storing only the ptr in the GC), element 1 is the size of one instance of the object, in bytes. The size of the memory block must be a multiple of this. Elements 2..$ are all of the offsets that should be scanned for pointers. For example: struct Foo { uint bar; void* baz; } getBitMask!(Foo); // [3, 8, 4]. That leaves the problem of where/how to store the pointers to this information in the GC efficiently. I haven't gotten that far yet, but I remember some concerns have been raised in the past about storing 4 bytes per GC object for a pointer to the bitmask. For my use cases, where I tend to allocate a relatively small number of relatively large objects, this isn't a problem. However, in a heavily OO environment, where people allocate tons of tiny objects, it might be. In the discussion I mentioned Frits van Bommel proposed a reasonable way to encode the information efficiently: http://www.digitalmars.com/d/archives/digitalmars/D/Std_Phobos_2_and_logging_library_87794.html#N87968 -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- The Guinness Book of Records holds the record for being the most stolen book in public libraries
Re: GC Precision
Andrei Alexandrescu, el 26 de octubre a las 11:01 me escribiste: Sean Kelly wrote: dsimcha Wrote: == Quote from Sean Kelly (s...@invisibleduck.org)'s article dsimcha Wrote: I just realized last night that D's templates are probably powerful enough now to generate bit masks that can be used for precise GC heap scanning. I'm halfway (emphasis on halfway) thinking of using this to try to hack the GC and make heap scanning fully precise except for the corner case of unions. However, this ties into several things that others in the D community are doing, so I want to gauge people's responses and make sure I'm not wasting effort on something that will be useless in 6 months. 1. Sean, Leonardo, whoever else may be working on GC implementations, have you by any chance broken ground on precise heap scanning already? I've thought about it, but not done anything about it. The compiler doesn't provide this information, so precise scanning would require a user-level call. You'll also have to deal with arrays of structs, by the way. Arrays of structs are easy: Generate a bitmask for one element, and keep reusing that bitmask until the end of the block. Am I missing something? Nope. One question is, is there enough information for stack variables? My understanding from a while ago was that heap data could be reasonably analyzed, but stack data has no info associated with it. There is some discussion about precise stack in the thread I cited too. The stack can be also precise adding a shadow stack (like a TypeInfo for the stack) but it's costly and it needs compiler support (LLVM has some mechanisms to generate this stack information AFAIK but I never played with it). The problem with the stack is that you still have to interact with C, which has no stack information, so it's a little more controversial about how much the extra complexity will pay off. I agree with David that it's much more reasonable to make the heap precise first and then see how thing are going from that. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- hypocrite opportunist don't infect me with your poison
Re: GC Precision
dsimcha, el 26 de octubre a las 23:05 me escribiste: I've spent some free brain cycles today thinking about this and here's the scheme I have in mind. If anyone thinks this could be improved in a way that would not have substantial ripple effects throughout the compiler/language (because then it might never actually get implemented) let me know. 1. GC.malloc's signature changes to GC.malloc(size_t size, uint ba = 0, size_t* bitmask = null). A null bitmask means use the old-school behavior and either scan everything or don't scan anything based on the NO_SCAN bit. IMHO plain old conservative scanning must be supported to allow for untyped memory blocks to be allocated, because requiring every memory block to have a type associated with it is an unacceptable limitation in a systems language. For now, the only way to get precise scanning would be to call malloc directly or use a template that does. Eventually new would either be fixed to instantiate the bitMask!(T) template or eliminated entirely. Since using the precise scanning by writing a template that calls GC.malloc() is a lot easier than hacking the compiler, this may be a catalyst for getting rid of new. Did you read the thread I posted? What do you think about Fritz's idea on how to encode the pointers information? I'm not very familiar with TypeInfo, but wouldn't be more natural to pass the TypeInfo to GC.malloc() directly if it can get the pointer information itself instead of translating that information? I think if that's possible it will keep the GC interface simpler. 2. Some concern has been expressed in the past about the possibility of using 4 bytes per block in overhead to store pointers to bitmasks. IMHO this concern is misplaced because in any program that takes up enough memory for space efficiency to matter, false pointers waste more space. Furthermore, if you're programming for a toaster oven, elevator controller, etc., you probably aren't going to use the standard out-of-the-box GC anyhow. This seems reasonable, but I don't see why we can't use a more efficient way to store this information in the GC. Implementation simplicity (to have a better GC now instead of a perfect GC in some point in a far future) is a good enough reason :) I'm just curious if you found any flaws in the scheme proposed by Frits or is just you want a simpler implementation. However, I've thought of ways to mitigate this and have come up with the following: A. Store a pointer to the bitmask iff the NO_SCAN bit is set. this is a no-brainer and will prevent any overhead on, for example, arrays of floats. Good idea. B. Add another attributes bit to the GC called something like NEEDS_BITMASK. This bit would be set iff an object mixes pointers and non-pointers. If it's not set, no bitmask pointer would be stored. However, the overhead of an extra bit may or may not be worth it. You mean for the special case where all the attributes of an object are pointers? I think this should be rare enough, so I doubt about the utility, but maybe I'm missing some common case. 3. The bitmask pointer would be stored at the end of every GC-allocated block for which a bitmask pointer is stored. The reason for using the end of the block instead of the beginning is just implementation simplicity: That way, finding the beginning of a block would work the same whether or not we have a bitmask pointer. Did you even consider storing this information outside the memory block (like the flags)? I think storing them in the memory block can be annoying if they are not stored always because now your fixed sized blocks are not fixed. It might be very easy to overcome this, but maybe thinking about the other option is worthy. 4. The bitmask would be a size_t[] created at compile time by a template and stored in the static data segment. Its layout would be [length of array, T.sizeof, offsets that need to be scanned]. For example, if you have something like: Again, I wonder if this information can't be still obtained from the TypeInfo. struct Foo { uint bar; void* ptr; } On a 32-bit machine, bitMask!Foo would be [3, 8, 4]. On a 64-bit, it would be [3, 16, 8]. The reason the size of the array is stored in the array is so that we can get away with storing a single ptr in each memory block instead of a pointer and a length. 5. To store information about pinning, we simply use the high-order bits of the pointer offsets. 1 means pinned, 0 means not pinned. This means that, for any type T, T.sizeof can't be bigger than size_t.max / 2. I think this is a fairly minor limitation. I like from Frits's proposal that information about weak pointer were added too, this might fix another big missing in the memory management area in D. -- Leandro Lucarella (AKA luca) http
Re: Disallow catch without parameter (LastCatch)
grauzone, el 25 de octubre a las 12:09 me escribiste: Right now, you can catch every exception with try { something; } catch { somethingelse; }. Can we get rid of this abomination before D2 is finalized? I claim that it's completely useless, and even more so, every single use of this is a bug. Why every use of this is a bug? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- aFR [...@my.farts.cause.nuclear.reaction.org] has quit IRC (Ping timeout)
Re: No header files?
AJ, el 24 de octubre a las 01:44 me escribiste: Leandro Lucarella llu...@gmail.com wrote in message news:20091023125658.ga23...@llucax.com.ar... AJ, el 22 de octubre a las 22:08 me escribiste: I'm still not clear on exactly what you plan on doing. Ooops! No I don't! Yes, I will be modeling via header files. May I suggest something? If you want to model via header files, write .d files with just declarations (skip implementations). You'll end up with hand written .di (headers) files, but in a .d files, so you can still automatically generate .di files from it. Use the .d files as an import in other modules (i.e., don't provide hand written .di files only). Then, when you want to start implementing your model, just add the bodies to the functions in the modeled .d file. The effect in the development process is the same as hand writing .h files and progressively fill the .cpp files with the implementation, but you are doing all the work in just *one* place (the .cpp/.d files) and generating the headers files (.h/.di) from that. What problems do you find in that scheme? I'm convinced: D is not me. My question was honest, I'm really curious about what problems do see. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- CAYO HUGO CONZI --- TENIA PUESTA PELUCA -- Crónica TV
Re: dmd 1.050 and 2.035 release
Michael P., el 23 de octubre a las 15:36 me escribiste: digited Wrote: Walter Bright Wrote: The main purpose of this is to correct a couple of regressions that were blocking QtD and Tango. http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.050.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.035.zip Many thanks to the numerous people who contributed to this update. Thanks again for small commits to svn! Today i've built DMD1 on Mac 10.5 (Intel) just like this: svn co http://svn.dsource.org/projects/dmd/branches/dmd-1.x/src dmd cd dmd make -f osx.mak and it's a godsand - no more downloading 8 MB of unusable stuff (and obsolete because some patches are already in trunk). I'm surprised that isn't fixed yet. http://d.puremagic.com/issues/show_bug.cgi?id=2908 My guess is that Walter have some mars directory in his development environment so everything works well for him. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Es mejor probar el sabor de sapo y darse cuenta que es feo, antes que no hacerlo y creer que es una gran gomita de pera. -- Dr Ricardo Vaporesso, Malta 1951
Re: No header files?
AJ, el 22 de octubre a las 22:08 me escribiste: I'm still not clear on exactly what you plan on doing. Traditional (read C/C++ like) software development. If you plan on generating the function prototypes Nope. I plan on hand-crafting header files before I create any implementation files. in a .d file and filling out the bodies later, go for it. Oh, by generating (bad choice of word), you meant writing. Yes I do. If you plan on hand writing the .di file Ooops! No I don't! Yes, I will be modeling via header files. May I suggest something? If you want to model via header files, write .d files with just declarations (skip implementations). You'll end up with hand written .di (headers) files, but in a .d files, so you can still automatically generate .di files from it. Use the .d files as an import in other modules (i.e., don't provide hand written .di files only). Then, when you want to start implementing your model, just add the bodies to the functions in the modeled .d file. The effect in the development process is the same as hand writing .h files and progressively fill the .cpp files with the implementation, but you are doing all the work in just *one* place (the .cpp/.d files) and generating the headers files (.h/.di) from that. What problems do you find in that scheme? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Soy como una mosca, parada en el agua. Y vos sos un transatlántico, querés nadar a mi lado. Y me estás ahogando.
Re: Targeting C
Bill Baxter, el 23 de octubre a las 08:51 me escribiste: list ~= array(iota(0, 10)); While we're not on the subject Iota is right up there with inSitu. I know it has a precedent elsewhere, but it sounds about as user friendly as monads. It just sounds like the language it trying to be snooty. Like if you don't even know what iota is, you're clearly not qualified to join our little D club. Maybe you should try Java... or Logo. Compare that to Python where it's called range, something every Joe the Programmer can certainly grok without having to get a Greek to English dictionary. Thanks for mention this, now I don't feel *that* idiotic to have to go and search what iota means every time I see it =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Did you know the originally a Danish guy invented the burglar-alarm unfortunately, it got stolen
Re: Targeting C
Andrei Alexandrescu, el 23 de octubre a las 11:09 me escribiste: Bill Baxter wrote: On Fri, Oct 23, 2009 at 5:13 AM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Yigal Chripun wrote: On 23/10/2009 13:02, bearophile wrote: Chris Nicholson-Sauls: I prefer this (Scala): list = list ++ (0 to 10) That's quite less readable. Scala sometimes has some unreadable syntax. Python has taught me how much useful a readable syntax is :-) Designing languages requires to find a balance between several different and opposed needs. Bye, bearophile how about this hypothetical syntax: list ~= [0..10]; I'm not sure what the type of list is supposed to be, but this works today for arrays: list ~= array(iota(0, 10)); While we're not on the subject Iota is right up there with inSitu. I know it has a precedent elsewhere, but it sounds about as user friendly as monads. It just sounds like the language it trying to be snooty. Like if you don't even know what iota is, you're clearly not qualified to join our little D club. Maybe you should try Java... or Logo. Compare that to Python where it's called range, something every Joe the Programmer can certainly grok without having to get a Greek to English dictionary. Given that range is already taken, what name do you think would work best? (I sometimes deliberately prefer less-used names because the more used ones often come with baggage and ambiguities (as is the case with range). Case in point, in-situ is more informative than in-place because the former suggests emplacement of a substructure within a larger structure. So to me an in-situ class member inside a class has a clear meaning that the member sits right there within the class. But anyhow I will use in-place from now on.) I don't see range taken inside the range module. I think it even makes sense, iota() is the more primitive range ever, so why don't just call it range()? :) Anyway, I think it makes perfect sense to have the compiler translating x..y to a iota/range(x, y). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- CAROZO CON FARINGITIS -- Crónica TV
Re: Revamped concurrency API (Don can you contact Bartosz ?)
Nick B, el 22 de octubre a las 19:35 me escribiste: Leandro Lucarella wrote: Don, el 21 de octubre a las 09:46 me escribiste: All my public email addresses are fake. Bugzilla is just spam bait. It clearly comes from a more innocent age. I once made the mistake of submitting a bug to gcc. Although the GCC Bugzilla hides the email in the submitter field, the idiots include the real email address in the 100% useless 'X-Ref' line. Two weeks later, my email address was dead. I've never made that mistake again. I am contactable through my dsource account. You don't even use a real account for personal e-mails! That's odd. I couldn't reply your private e-mail about changing the title of the bugzilla report because the From address were fake. Yes, I too use fake personal email accounts, as I do not want my gmail accounts hammered with spam. I could add -nospam to the name, but I am unsure how good the spammers are these days to get around this. Any suggestions/comments, anyone ? I just use my real e-mail everywhere and let the spammers eat the world's BW as they please. I just let my anti-spam (bogofilter and gmail in case of the gmail address) to take care of things... -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Que importante, entonces en estos días de globalización refregar nuestras almas, pasarle el lampazo a nuestros corazones para alcanzar un verdadero estado de babia peperianal. -- Peperino Pómoro
Re: Revamped concurrency API (Don can you contact Bartosz ?)
Don, el 21 de octubre a las 09:46 me escribiste: Nick B wrote: Don wrote: Don, are you able to contact Bartosz, re the details of this test case. Nick B Bartosz has sent it to me. I can reproduce the error. It's my top priority, but it'll take a while -- it's nasty. Don - thanks for filing this. I did try to contact you, via bugzilla email (which bounced back)and via Skype,(no reply), without success. Nick B All my public email addresses are fake. Bugzilla is just spam bait. It clearly comes from a more innocent age. I once made the mistake of submitting a bug to gcc. Although the GCC Bugzilla hides the email in the submitter field, the idiots include the real email address in the 100% useless 'X-Ref' line. Two weeks later, my email address was dead. I've never made that mistake again. I am contactable through my dsource account. You don't even use a real account for personal e-mails! That's odd. I couldn't reply your private e-mail about changing the title of the bugzilla report because the From address were fake. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Hoy estuvimos en el museo de antropología, pero yo voy a volver para estar por lo menos un día ahí adentro... es una locura, como Disney pero de indigenas -- Carla Lucarella (10/2008 contando de su viaje a México)
Re: static arrays becoming value types
Yigal Chripun, el 21 de octubre a las 07:18 me escribiste: On 21/10/2009 05:48, Robert Jacques wrote: On Tue, 20 Oct 2009 23:30:48 -0400, Leandro Lucarella llu...@gmail.com wrote: Robert Jacques, el 20 de octubre a las 21:06 me escribiste: Now, if SOL allowed tuples to do things you can't do today in D, like assign a tuple to a struct with the same signature, then this might be a point. But that wasn't the example given. Yes, that's another thing that can be done without real tuple support in the language. Anyway, I guess I was a little exaggerated with '*way far* from ideal', but I'm convinced there is plenty of room for improvements. =) Would you happen to know of a language which does tuples well already? pick any functional language.. my favorite is ML Or Python ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- HACIA NEUQUEN: EL JUEVES SALDRA CARAVANA CON PERROS DESDE CAPITAL EN APOYO AL CACHORRO CONDENADO A MUERTE -- Crónica TV
Re: static arrays becoming value types
language_fan, el 21 de octubre a las 17:52 me escribiste: Wed, 21 Oct 2009 16:54:22 +, language_fan thusly wrote: Wed, 21 Oct 2009 10:48:34 -0500, Andrei Alexandrescu thusly wrote: language_fan wrote: Wed, 21 Oct 2009 11:07:29 -0400, Robert Jacques thusly wrote: My issue was that all your example _showed_ was nominal typing. Though I didn't mention it by name, I did mention that if SOL tuples had structural typing, it might would be a different story. (Well, until/if opImplicitCast was implemented, as it would allow for structural typing.) Why do you insist on using nominal typing for tuples and the library defined literal. If I want plain old tuples without any kind of type name, why should I care about extra hand waving needed to make it work. I'm late in this dialog, but I'm not seeing an impediment here. What does it matter to you that tuples actually have a name vs. not having a name at all? Using tuples in D is a major pain in the ass. In fact it has been made so hard that people start avoiding the feature like plague. I wrote some test code to reveal how inconsistent their semantics are. Note that you need the built-in tuples for some stuff, like assigning and mixed value/ type tuples. Stuples can only be used as values and when the auto- flattening is not desired. STARTS HERE Even though not being an expert in Python (have not really used it), as an experiment I managed to successfully port the examples in 2 minutes without any kind of problems. I think this is an important point too. Maybe tuples are not *that* broken as stated in this thread, but they are quite more complex to understand than tuples in other languages, and they feel somehow hackish. a = (1,1) e1 = a[0] print a def retTest(): return (1,1) (d,e) = (10,20) (d,_) = (10,20) (d,b) = (1, retTest()) a3b = [ (1,1), (2,2) ] a7 = { (1,1) : 5 } a8 = { 5 : (1,1)} In python you can even do: def f(a, b, c): print a, b, c x = (b, c) f(a, *x) # calls to f(a, b, c) I think this is only possible in D with type tuples, not with ... value tuples? That's part of the complexity, having 2 type of tuples is very confusing. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- You are the very reason why everything happens to you
Re: static arrays becoming value types
grauzone, el 21 de octubre a las 22:12 me escribiste: Or even: a, b = foo(); or a, _ = foo(); Works in Python (tm) _ is a regular symbol (variable name in this case), there is nothing special about the second form, which is exactly the same as the first. And BTW, the trailing ; is not needed ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Hey you, standing in the aisles With itchy feet and fading smiles Can you feel me?
Re: this() not executing code on structs
Bartosz Milewski, el 21 de octubre a las 16:33 me escribiste: Andrei Alexandrescu Wrote: this() { myCount = count++; } // ERROR It's worse than that. Try this: struct foo { this(int dummy = 0) { writeln(Default constructor);} } foo x = foo(); Nothing gets printed. If default constructors are disallowed, so should constructors with all parameters defaulted. Fill bug reports in bugzilla, please! -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Los jóvenes no son solo brazos que nos cargan... También se los puede mandar a la guerra, que es su obligación. -- Ricardo Vaporeso
Re: static arrays becoming value types
grauzone, el 21 de octubre a las 23:32 me escribiste: Leandro Lucarella wrote: grauzone, el 21 de octubre a las 22:12 me escribiste: Or even: a, b = foo(); or a, _ = foo(); Works in Python (tm) _ is a regular symbol (variable name in this case), there is nothing special about the second form, which is exactly the same as the first. And I didn't even know this. In Python, it doesn't matter anyway, because it is dynamically typed, and you can assign arbitrary values to the same variable. Apparently, writing foreach (index,_;something) in D isn't a special case either; it just declares a variable named _. Several nested loops using _ are not possible. Using _ is a bad idea if you use gettext though ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- El techo de mi cuarto lleno de estrellas
Re: Revamped concurrency API (Don can you contact Bartosz ?)
Don, el 20 de octubre a las 09:00 me escribiste: Unfortunately, I have undone some of my changes trying to bypass the bug, so at the moment I don't even have the buggy version, but it can be reconstructed. We can discuss it off-line, if you want. Use my email address with -nospam removed. Bartosz I think that Don is the best person to contact you. I will try to contact him. Nick B Don, are you able to contact Bartosz, re the details of this test case. Nick B Bartosz has sent it to me. I can reproduce the error. It's my top priority, but it'll take a while -- it's nasty. Do you have a bugzilla # so we can keep track of it? Thanks. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- HACIA NEUQUEN: EL JUEVES SALDRA CARAVANA CON PERROS DESDE CAPITAL EN APOYO AL CACHORRO CONDENADO A MUERTE -- Crónica TV
Re: Eliminate new for class object creation?
Andrei Alexandrescu, el 19 de octubre a las 22:16 me escribiste: dsimcha wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article Leandro Lucarella wrote: Jason House, el 19 de octubre a las 22:20 me escribiste: Bill Baxter Wrote: On Mon, Oct 19, 2009 at 4:00 PM, Rainer Deyke rain...@eldwood.com wrote: Andrei Alexandrescu wrote: I hereby suggest we get rid of new for class object creation. What do you guys think? *applause* 'X(x)' and 'new X(x)' have distinct meanings in C++. ?In Java/C#/D, the 'new' is just line noise. Well, I think new Foo is how you create a struct on the heap in D. So it's not exactly line noise. I don't mind getting rid of new, but there better be a good way to allocate structs on the heap. And it better not require me to do an import just to be able to call the allocation function. I like the Foo.new syntax myself. --bb Actually, new can also be used for creating classes on the stack... scope T t = new T(); Damn! This is getting confusing. It seems like allocation should be revised altogether :) Scope will go (and this time I'm not kidding). It's very unsafe. Andrei But we need a reasonable way of allocating class instances on the stack as an optimization. Scope provides a nice way to do that. In general, I'm sick of hearing about safety. D is a close-to-the-metal systems language. The programmer has to be given control. In general I think we're going wy off the deep edge trying to make D too safe lately at the expense of convenience and performance. No problem. You will be able to use InSitu!T. It is much better to confine unsafe features to libraries instead of putting them in the language. { auto foo = InSitu!(Foo)(args); // use foo ... // foo goes away } useless discussion Why not Scoped!T ? I think the purpose for this that the lifetime of the object is bounded to the scope, right? I think is hard to figure that out from InSitu!T than Scoped!T. /useless discussion -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- - Mire, don Inodoro! Una paloma con un anillo en la pata! Debe ser mensajera y cayó aquí! - Y... si no es mensajera es coqueta... o casada. -- Mendieta e Inodoro Pereyra
Re: static arrays becoming value types
dsimcha, el 20 de octubre a las 02:44 me escribiste: == Quote from Walter Bright (newshou...@digitalmars.com)'s article Currently, static arrays are (as in C) half-value types and half-reference types. This tends to cause a series of weird problems and special cases in the language semantics, such as functions not being able to return static arrays, and out parameters not being possible to be static arrays. Andrei and I agonized over this for some time, and eventually came to the conclusion that static arrays should become value types. I.e., T[3] should behave much as if it were: struct ?? { T[3]; } Then it can be returned from a function. In particular, void foo(T[3] a) is currently done (as in C) by passing a pointer to the array, and then with a bit of compiler magic 'a' is rewritten as (*a)[3]. Making this change would mean that the entire array would be pushed onto the parameter stack, i.e. a copy of the array, rather than a reference to it. Making this change would clean up the internal behavior of types. They'll be more orthogonal and consistent, and templates will work better. The previous behavior for function parameters can be retained by making it a ref parameter: void foo(ref T[3] a) Vote++. It's funny, I use static arrays so little that I never realized that they weren't passed by value to functions. I'd absolutely love to be able to just return static arrays from functions, and often use structs to do that now, but using structs feels like a really ugly hack. It would be the poor men tuple for returning (homogeneous) stuff =P -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- La máquina de la moneda, mirá como te queda! -- Sidharta Kiwi
Re: static arrays becoming value types
language_fan, el 20 de octubre a las 13:52 me escribiste: Tue, 20 Oct 2009 10:34:35 -0300, Leandro Lucarella thusly wrote: dsimcha, el 20 de octubre a las 02:44 me escribiste: == Quote from Walter Bright (newshou...@digitalmars.com)'s article Currently, static arrays are (as in C) half-value types and half-reference types. This tends to cause a series of weird problems and special cases in the language semantics, such as functions not being able to return static arrays, and out parameters not being possible to be static arrays. Andrei and I agonized over this for some time, and eventually came to the conclusion that static arrays should become value types. I.e., T[3] should behave much as if it were: struct ?? { T[3]; } Then it can be returned from a function. In particular, void foo(T[3] a) is currently done (as in C) by passing a pointer to the array, and then with a bit of compiler magic 'a' is rewritten as (*a)[3]. Making this change would mean that the entire array would be pushed onto the parameter stack, i.e. a copy of the array, rather than a reference to it. Making this change would clean up the internal behavior of types. They'll be more orthogonal and consistent, and templates will work better. The previous behavior for function parameters can be retained by making it a ref parameter: void foo(ref T[3] a) Vote++. It's funny, I use static arrays so little that I never realized that they weren't passed by value to functions. I'd absolutely love to be able to just return static arrays from functions, and often use structs to do that now, but using structs feels like a really ugly hack. It would be the poor men tuple for returning (homogeneous) stuff =P It depends on how you define things. Traditionally tuples are seen as a generalization of pairs (2 elements - n elements). Records, on the other In what tradition? C++ maybe. I never saw a pair type outside C++, but saw tuples everywhere (even in other structured languages like SQL). hand, are generalization of tuples (simple number index - named elements). You need couple of additional layers of generalization to come up with structs (subtyping, member functions, generics etc.) One nasty thing about D's structs is that they don't have structural equivalence relation unlike tuples. So you need to use the same container struct type to get the same semantics. To achieve that you would need some kind of STuple on standard library level or other kinds of hacks. What I find unfortunate in D is that your abstractions come in two sizes - either you use the modest tiny construct that does not scale elegantly or the enormous hammer to crush things down theatretically. I don't understand very well what are you saying anyways... -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Fantasy is as important as wisdom
Re: Eliminate new for class object creation?
Andrei Alexandrescu, el 20 de octubre a las 08:42 me escribiste: Why not Scoped!T ? I think the purpose for this that the lifetime of the object is bounded to the scope, right? I think is hard to figure that out from InSitu!T than Scoped!T. /useless discussion It's not a useless discussions, names are important. Scoped is more OK, let's continue then... ;) evocative for in-function definition, whereas InPlace/InSitu are (at least to me) more evocative when inside a class. class A { InPlace!B member; } Yes, but I think Scoped!T is clearer in average. The member effectively live in the same scope the class does. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Si pudiera acercarme un poco más, hacia vos Te diría que me tiemblan los dos pies, cuando me mirás Si supieras todo lo que me costó, llegar Hoy sabrías que me cuesta respirar, cuando me mirás
Re: static arrays becoming value types
language_fan, el 20 de octubre a las 19:19 me escribiste: One nasty thing about D's structs is that they don't have structural equivalence relation unlike tuples. So you need to use the same container struct type to get the same semantics. To achieve that you would need some kind of STuple on standard library level or other kinds of hacks. What I find unfortunate in D is that your abstractions come in two sizes - either you use the modest tiny construct that does not scale elegantly or the enormous hammer to crush things down theatretically. I don't understand very well what are you saying anyways... Because of the unnecessary nominal typing in D's tuple emulation, redefinitions of Tuples do not have implicit equivalence relation: struct Tuple(T...) { T t; } struct Tuple2(T...) { T t; } void main() { Tuple!(int,int) a; Tuple!(int,int) b; Tuple2!(int,int) c; assert(a == b); // ok assert(a != c); // Error: incompatible types for ((a) != (b)) } In some other language: val a = (1,2) : [Int,Int] val b = (1,2) : [Int,Int] val c = (2,3) : [Int,Int] assert(a == b); // ok assert(a != c); // ok Did you get it now? Yes, thanks for the clarification. Real tuple types do not have a special type tag which gets injected implicitly with structs. So every time you try to do something lightweight by emulating tuples, you need to refer to the global Tuple type or bang your head to the wall. Yes, D support for tuples is way far from ideal. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- If you want to be alone, just be alone If you want to watch the sea, just watch the sea But do it now, timing is the answer, do it now Timing is the answer to success
Re: static arrays becoming value types
Robert Jacques, el 20 de octubre a las 21:06 me escribiste: Real tuple types do not have a special type tag which gets injected implicitly with structs. So every time you try to do something lightweight by emulating tuples, you need to refer to the global Tuple type or bang your head to the wall. Yes, D support for tuples is way far from ideal. How so? I think this is merely the difference between a library type in a flexible language and a built-in type in an inflexible language. I mean the example was essentially: In D: Apple a Apple b Orange c assert(a != c); // Error: incompatible types Apple and Orange In SOL: Apple a Apple b Apple c assert(a != c); // ok, both a and c are apples. I wasn't referring to this particular example, even when I agree this is not a big issue, is much more difficult to end up comparing Apples to Oranges if the language have support for tuple literals (like in the example). In D I think you might find yourself in this situation more often, but still rarely. I think tuple literals is an important thing to encourage people using tuples, specially when you want to support functional programming style. Now, if SOL allowed tuples to do things you can't do today in D, like assign a tuple to a struct with the same signature, then this might be a point. But that wasn't the example given. Yes, that's another thing that can be done without real tuple support in the language. Anyway, I guess I was a little exaggerated with '*way far* from ideal', but I'm convinced there is plenty of room for improvements. =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- FINALMENTE EL CABALLITO FABIAN VA A PASAR UNA BUENA NAVIDAD -- Crónica TV
Re: The demise of T[new]
Andrei Alexandrescu, el 18 de octubre a las 20:16 me escribiste: Here's what I wrote to Walter: I'm going to suggest something terrible - let's get rid of T[new]. I know it's difficult to throw away work you've already done, but really things with T[new] start to look like a Pyrrhic victory. Here are some issues: * The abstraction doesn't seem to come off as crisp and clean as we both wanted; * There are efficiency issues, such as the two allocations that you valiantly tried to eliminate in a subset of cases; * Explaining two very similar but subtly different types to newcomers is excruciatingly difficult (I'll send you a draft of the chapter - it looks like a burn victim who didn't make it); * Furthermore, explaining people when to use one vs. the other is much more difficult than it seems. On the surface, it goes like this: If you need to append stuff, use T[new]. If not, use T[]. Reality is much more subtle. For one thing, T[new] does not allow contraction from the left, whereas T[] does. That puts T[] at an advantage. So if you want to append stuff and also contract from the left, there's nothing our abstractions can help you with. I think this is getting overcomplicated. I don't see it as complex, I see it like this: 2 types should be provided: array and slice. array is a *real* type, storing and owning memory, it should be something like this (conceptually): class array(T) { size_t length; size_t capacity; T[capacity] elements; } 1) a pure reference type. 2) 1 allocation only (interior pointers are not a problem, the GC have to support them anyways). 3) easily appendable (capacity field). slice should be something like this: struct slice(T) { size_t length; T* ptr; } 1) a pure value type. 2) no allocation at all, *ever*. 3) not appendable at all. 4) You can change both ptr and length, and you can mutate the elements (if not immutable). So a slice is a window to peek a chunk of data. Then you have the syntax. In this discussion, T[new] is array and T[] is slice. I find that syntax very confusing. I think it could be even better to just put those 2 types in object.d (well, do public imports of those 2 types in object.d) and let the people write: array!T a; slice!T s; The array literals should be immutable chunks of memory in the static memory, as ClassInfo.init. The type of [1,2,3] should be, for example, slice!(immutable int), so: auto s = [1,2,3]; should create a slice!(immutable int) with length 3 and ptr pointing to the static memory where the [1,2,3] was stored (this is what happens with strings, right? So no surprises here, they are consistent). slice.dup should return an array. If you want to just copy the length and ptr members, use assignment (it's a value type, remember)? auto s = [1,2,3]; auto t = s; assert(s.length == t.length); assert(s.ptr == t.ptr); assert(s != t); Assignment of arrays is just a pointer assignment (is a reference type): auto a = [1,2,3].dup; auto b = a; assert(a is b); array.dup returns another array. array[] returns a slice though (you can allow implicit casting from array to slice but I don't see the point as array[] is short enough and more explicit). slices should not be convertible to arrays (use slice.dup for that). Back to the syntax, I think T[new] is *really* confusing. It tell me nothing about the type, it provides the same information as calling it it wazzzaaap!T for me. I *really* think it would be better to call it array!T. But if we have both types, T[] is not clear anymore that is a slice, again, you can't figure that out. So maybe T[] should be used for arrays, not slices; if you want some syntax sugar I think T[] is more guessable to be an array than a slice, and it would be a little more backward compatible. Maybe slices can be T[..], but I'm not sure is clear enough, again I think we could live with something more explicit like array!T and slice!T. But at least slices should be part of the language, because that should be the type of array literals (damn! that didn't sound right =P). I'm missing something? Why this shouldn't work? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- - Que hacés, ratita? - Espero un ratito...
Re: The demise of T[new]
Leandro Lucarella, el 19 de octubre a las 11:57 me escribiste: slice.dup should return an array. To avoid making the language aware of the array type, slice.dup can be removed and use an array constructor instead: auto a = slice.dup; should be: auto a = array!T(slice); This way, I think the language only have to know about slices. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- He cometido pecados, he hecho el mal, he sido víctima de la envidia, el egoísmo, la ambición, la mentira y la frivolidad, pero siempre he sido un padre argentino que quiere que su hijo triunfe en la vida. -- Ricardo Vaporeso
Re: version(ctfe)
Andrei Alexandrescu, el 19 de octubre a las 08:38 me escribiste: For relatively large chunks of memory, the GC keeps a control block. We could add a member size_t requestedSize that keeps the size that was requested with an allocation/reallocation call. The GC can take initiative in overallocating memory and expose primitives such as requestedSize (how much did the program ask for?) and capacity (how much is really allocated?). With that API, it is possible to implement ~= efficiently. That would mean moving the overhead of arrays to the GC, but that overhead will be present for *all* objects, arrays or not, so I don't think it will be a good idea... Having that information could be used if present though, for example, to avoid scanning chunks of memory that are not used. That could help avoiding false positives (if that chunks of memory are not zeroed already). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Yo soy Peperino, mártir latino, venid al asado pero traed el vino. -- Peperino Pómoro
Re: The demise of T[new]
Leandro Lucarella, el 19 de octubre a las 12:13 me escribiste: Leandro Lucarella, el 19 de octubre a las 11:57 me escribiste: slice.dup should return an array. To avoid making the language aware of the array type, slice.dup can be removed and use an array constructor instead: auto a = slice.dup; should be: auto a = array!T(slice); This way, I think the language only have to know about slices. Unless you want to have an appendable array type in CTFE. I guess the language should know about array anyways :S (I should read the entire thread before posting) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Si el enemigo se siente abatido, recuérdele que su familia está lejos y que mientras siga la pelea él se estará perdiendo el crecimiento de sus hijos. Si está feliz, recuerdele de la existencia de su familia política, en especial de los cuñados que tienen sexo con sus hermanas. -- Ricardo Vaporeso. De la desmoralización del enemigo.
Re: The demise of T[new]
Andrei Alexandrescu, el 19 de octubre a las 10:18 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 18 de octubre a las 20:16 me escribiste: Here's what I wrote to Walter: I'm going to suggest something terrible - let's get rid of T[new]. I know it's difficult to throw away work you've already done, but really things with T[new] start to look like a Pyrrhic victory. Here are some issues: * The abstraction doesn't seem to come off as crisp and clean as we both wanted; * There are efficiency issues, such as the two allocations that you valiantly tried to eliminate in a subset of cases; * Explaining two very similar but subtly different types to newcomers is excruciatingly difficult (I'll send you a draft of the chapter - it looks like a burn victim who didn't make it); * Furthermore, explaining people when to use one vs. the other is much more difficult than it seems. On the surface, it goes like this: If you need to append stuff, use T[new]. If not, use T[]. Reality is much more subtle. For one thing, T[new] does not allow contraction from the left, whereas T[] does. That puts T[] at an advantage. So if you want to append stuff and also contract from the left, there's nothing our abstractions can help you with. I think this is getting overcomplicated. I don't see it as complex, I see it like this: 2 types should be provided: array and slice. array is a *real* type, storing and owning memory, it should be something like this (conceptually): class array(T) { size_t length; size_t capacity; T[capacity] elements; } At the point I introduce arrays I hadn't described classes. You are talking about the book, right? You don't have to! You can explain arrays without talking about classes at all! See the Python Tutorial for example: http://docs.python.org/tutorial/index.html You see all kind of complex data structures (lists, dictionaries, tuples, strings, sets), input and output, and even exceptions! before classes. And I read it, and was a very easy and pleasant reading. Talking about a class here was just to prove my point more easily because I *know* everybody here knows very well about classes semantics. I was not describing it for a book. One major problem with writing a The X Programming Language book is sequencing. It's very easy to explain a complicated feature if the listener knows all others. It is very difficult to introduce them serially. I don't think an array would be the case, come on! =) 1) a pure reference type. 2) 1 allocation only (interior pointers are not a problem, the GC have to support them anyways). 3) easily appendable (capacity field). slice should be something like this: struct slice(T) { size_t length; T* ptr; } structs and pointers have also not been introduced yet. I don't know what this have to do with the book. Should be D designed based on how good are you to explain the concepts on the book? I think this is getting ridiculous... seriously. I don't want to be rude, I know you're putting a lot of work in the book and we all appreciate that, but you didn't mention any technical point about what I wrote. I'm missing something? Why this shouldn't work? It may work, but I was unable to pull it off reasonably well. What problems did you find? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- DESCARTAN BIDET VIRTUAL PORQUE NO LAVA -- Cronista TV
Re: version(ctfe)
Andrei Alexandrescu, el 19 de octubre a las 10:33 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 19 de octubre a las 08:38 me escribiste: For relatively large chunks of memory, the GC keeps a control block. We could add a member size_t requestedSize that keeps the size that was requested with an allocation/reallocation call. The GC can take initiative in overallocating memory and expose primitives such as requestedSize (how much did the program ask for?) and capacity (how much is really allocated?). With that API, it is possible to implement ~= efficiently. That would mean moving the overhead of arrays to the GC, but that overhead will be present for *all* objects, arrays or not, so I don't think it will be a good idea... I forgot to mention that ~= would also have a means to communicate the GC to overallocate. My point is simple: the problem is that slices don't store enough info. That info could get in the memory control block. The control block is not part of the object's memory, so I don't think it's something you want to manipulate frequently (because of locality issues). This works well for the GC because when you manipute control information often is when you are collecting, so for collection most of the control info should be cached and have good locality. In collections you have the exact opposite scheme, you don't look at the data, only the control info. When you manipulate an array you will be probably touching both. That's why I think you should keep all the array data in one place. Well, that and because I don't think is a good idea to transfer array complexities to the GC. It's just not the place for that. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Si por el chancho fuera, se autocomería con chimichurri Worshestershire!
Re: The demise of T[new]
Andrei Alexandrescu, el 19 de octubre a las 11:16 me escribiste: I'm missing something? Why this shouldn't work? It may work, but I was unable to pull it off reasonably well. What problems did you find? I thought I explained that above and in several other posts. I have the feeling this is going in circles, but let me add one more thing. People would want to have a reasonable way of choosing between T[new] and T[]. The differences between them are subtle (I have two tables showing the primitives of T[] and T[new], which are very similar). If T[new] is array and T[] is slice as I described them, I see no subtlety, they are huge differences, one is a dynamic array, the other is a view on somebody else's memory. I know you probably hate when people says this (that's what I avoided doing it before :): I works very well in Python. You have arrays (well, lists, but the interface is the same as an array) and slices. I never heard anybody complaining about that being confusing. That static decision concerns future appends to the array, which doesn't strike me as something you know from the get-go through future iterations of a design. Use of auto messes up things further: a nice function may choose to return T[new] because it just created an array (an implementation detail), but clients may find that unexpected. I don't see much problem. You should always return an array (T[new]) if you have one, because you can get an slice from it (the inverse is not true). Because of this, implicit conversion from array to slice can be a good idea, so people expecting a slice when an array is returned will never know an array was returned anyways. If you need to keep appending to the array, you can have the original array and keep appending to it without any performance hit (no copying, no new allocations). What's wrong with that? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Cuando intenté arrimarle mi brazo Se puso a hablar de Miller, de Anais Nin y Picasso Y si osaba intentar robarle un beso Se ponía a leer de Neruda unos versos Me hizo mucho mal la cumbiera intelectual
Re: The demise of T[new]
Andrei Alexandrescu, el 19 de octubre a las 12:40 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 19 de octubre a las 11:16 me escribiste: I'm missing something? Why this shouldn't work? It may work, but I was unable to pull it off reasonably well. What problems did you find? I thought I explained that above and in several other posts. I have the feeling this is going in circles, but let me add one more thing. People would want to have a reasonable way of choosing between T[new] and T[]. The differences between them are subtle (I have two tables showing the primitives of T[] and T[new], which are very similar). If T[new] is array and T[] is slice as I described them, I see no subtlety, they are huge differences, one is a dynamic array, the other is a view on somebody else's memory. Their primitives overlap 90% in syntax and semantics. So what? Ranges and slices too. I know you probably hate when people says this (that's what I avoided doing it before :): I works very well in Python. You have arrays (well, lists, but the interface is the same as an array) and slices. I never heard anybody complaining about that being confusing. Python lists and slices are quite different from D arrays. Not the API. I don't see much problem. You should always return an array (T[new]) if you have one, because you can get an slice from it (the inverse is not true). Because of this, implicit conversion from array to slice can be a good idea, so people expecting a slice when an array is returned will never know an array was returned anyways. If you need to keep appending to the array, you can have the original array and keep appending to it without any performance hit (no copying, no new allocations). What's wrong with that? People expecting a slice and using auto or templates are in for a rude awakening. Ok, you are in one of those days when you don't listen to reasons. I give up! =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Si ella es el sol, yo soy la luna Si ella es el mar, soy el desierto Y estamos en eclipse total Y estamos en eclipse total
Re: LRU cache for ~=
Andrei Alexandrescu, el 19 de octubre a las 13:51 me escribiste: I just wrote this to Sean and Walter and subsequently discussed it with Walter. Walter thinks this should work. Does anyone have the time and inclination to test this out? It would involve hacking into druntime's implementation of ~= (I'm not sure what the function name is). I'd really appreciate this; I'm overloaded as it is. == In wake of the recent demise of T[new], I was thinking of finding ways of making ~= efficient for T[]. Currently ~= is slow because accessing GC.sizeOf(void*) acquires a global lock and generally must figure out a lot of things about the pointer to make a decision. Also, ~= is dangerous because it allows slices to stomp over other slices. I was thinking of solving these issues by keeping an LRU (Least Recently Used) cache inside the implementation of ~=. The LRU would only have a few entries (4-8) and would store the parameters of the last ~= calls, and their cached capacities. So whenever code calls arr ~= b, the LRU is searched first. If the system finds arr (both bounds) in the LRU, that means the cached capacity is correct and can solve the matter without an actual trip to the GC at all! Otherwise, do the deed and cache the new slice and the new capacity. This also solves the lack of safety: if you request a growth on an array you just grew, it's impossible to have a valid slice beyond that array. This LRU would allow us to keep the slice API as it currently is, and also at excellent efficiency. What do you think? I think this is moving in the wrong direction. It's a patch, not a solution. And this makes dynamic arrays more coupled with the way the GC works. I think the GC shouldn't even provide a sizeOf(void*), we should move in that direction, removing restrictions to the GC instead of enforcing the current ones; at lest if the goal is to eventually have a better GC (a copying GC doesn't even have to store the size of the cell, for example). I hope you eventually realize that you are complicating things much more than necessary. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- ACCIDENTE FATAL EN FLORES, MUEREN DOS PERSONAS Y UN BOLIVIANO -- Crónica TV
Re: The demise of T[new]
Andrei Alexandrescu, el 19 de octubre a las 14:31 me escribiste: By the way: implementation of @property has been canceled. Keep throwing the good news :( -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Es mas posible, que un elefante maneje un cero km a que un camello habite un departamento de un ambiente. -- Peperino Pómoro
Re: Revamping associative arrays
Bill Baxter, el 19 de octubre a las 14:18 me escribiste: On Mon, Oct 19, 2009 at 1:58 PM, KennyTM~ kenn...@gmail.com wrote: On Oct 20, 09 03:40, Piotrek wrote: Bill Baxter pisze: Just get rid of the the one-argument foreach over AAs altogether and force the user to be explicit about it. I wouldn't do so. Would anybody do an error by thinking that foreach (elem,table) should iterate over keys? Bearophile. And anyone coming from python, at the least. And anyone who agrees with the logic of connecting 'in' with what gets iterated. And only python that I am aware of. Java,C#,PHP (which hold most of all programmers) are defaulting to values unless explicitly stated. and Javascript. and Objective-C. I took a look at C# yesterday, and I don't think it is true there. As far as I can tell IDictionary is the closest thing to AA in C#, and for it default iteration yields Key,Value pairs called DictionaryEntry. MSDN Says: Since each element of the IDictionary object is a key/value pair, the element type is not the type of the key or the type of the value. Instead, the element type is DictionaryEntry. I guess everybody knows, but this is what C++ does =P -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Did you know the originally a Danish guy invented the burglar-alarm unfortunately, it got stolen
Re: LRU cache for ~=
Andrei Alexandrescu, el 19 de octubre a las 17:24 me escribiste: dsimcha wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article Making ~= work well for slices does not preclude creating a distinct library type. Andrei Yes, I see LRU/MRU/whatever as a kludge to allow convenience without being unsafe egregiously inefficient. The fact that it is a kludge is not a criticism because there is clearly no easy answer, and thus a kludge is genuinely necessary. However, I think there needs to be a separate array builder type for heavy duty appending operations. In TDPL I would just say that concatenating slices can be inefficient and that people should use array builder for heavy duty appending, length changing, etc., w/o getting into the details. But how about the opposite view. What if the *previous* implementation of GC and ~= were a kludge that led to egregious inefficiency and revolting unsafety, kludge that that now is getting fixed. What I'm saying is that with the cache in place we'll have slices that are safe and efficient. Right now they are not safe and not efficient. I can hardly find reasons to characterize the new state of affairs as kludgey. One surprising (but safe) behavior that remains with slices is this: void fun(int[] a) { a[0] = 0; a ~= 42; a[0] = 42; } The caller may or may not see 42 in the first slot after the call. And for me this is enough to remove appending from slicing and having a proper array type. There is no reason to keep that buggy behaviour. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- DONAN UN PENE EN NICARAGUA -- Crónica TV
Re: LRU cache for ~=
Andrei Alexandrescu, el 19 de octubre a las 20:12 me escribiste: Bill Baxter wrote: On Mon, Oct 19, 2009 at 5:07 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Rainer Deyke wrote: Andrei Alexandrescu wrote: One surprising (but safe) behavior that remains with slices is this: void fun(int[] a) { a[0] = 0; a ~= 42; a[0] = 42; } The caller may or may not see 42 in the first slot after the call. Your definition of safe is clearly not aligned with mine. What's yours? Probably something like safe from easy-to-write hard-to-debug programming errors. I agree that it would stink if all these changes were made and *still* one of the top gotchas with arrays/slices remained. It also makes me think slices and appending just don't belong together. Appending to a view ... just say no. How to reconcile this viewpoint with that of people who find ~= all too darn convenient? Use a proper array type, not a view (slice). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- No recuerdo las flores, no conozco el viento Aquí donde envejecen juntos presos y carceleros Los días no pasan, el tiempo no pasa Y vivimos contando el tiempo Y moriremos contando el tiempo
Re: Eliminate new for class object creation?
Jason House, el 19 de octubre a las 22:20 me escribiste: Bill Baxter Wrote: On Mon, Oct 19, 2009 at 4:00 PM, Rainer Deyke rain...@eldwood.com wrote: Andrei Alexandrescu wrote: I hereby suggest we get rid of new for class object creation. What do you guys think? *applause* 'X(x)' and 'new X(x)' have distinct meanings in C++. ?In Java/C#/D, the 'new' is just line noise. Well, I think new Foo is how you create a struct on the heap in D. So it's not exactly line noise. I don't mind getting rid of new, but there better be a good way to allocate structs on the heap. And it better not require me to do an import just to be able to call the allocation function. I like the Foo.new syntax myself. --bb Actually, new can also be used for creating classes on the stack... scope T t = new T(); Damn! This is getting confusing. It seems like allocation should be revised altogether :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Si el enemigo se siente abatido, recuérdele que su familia está lejos y que mientras siga la pelea él se estará perdiendo el crecimiento de sus hijos. Si está feliz, recuerdele de la existencia de su familia política, en especial de los cuñados que tienen sexo con sus hermanas. -- Ricardo Vaporeso. De la desmoralización del enemigo.
Re: 64-bit
dsimcha, el 17 de octubre a las 14:19 me escribiste: == Quote from Lutger (lutger.blijdest...@gmail.com)'s article Currently: LDC is a mature compiler that does linux 64 bit well, but is not available for D2, the 'alpha' branch of the language and also doesn't work on windows. The outdated compiler you speak of would probably be GDC, this project has recently been revived. The is no 64-bit dmd yet. At the moment all efforts I believe are on finishing the D2 language and current dmd bugs, as well as a book called 'The D programming language'. IIRC the deadline is somewhere end of this year. What happens after that I don't know, I haven't seen any statement that work on 64-bit is planned. I would rather bet on GDC and / or LDC getting full 64-but support for D2 before dmd. Where has GDC been revived? It doesn't look like there have been any checkins on the sourceforge site since Feb. http://bitbucket.org/goshawk/gdc/ -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- You look so tired-unhappy, bring down the government, they don't, they don't speak for us.
Re: T[new] misgivings
Andrei Alexandrescu, el 16 de octubre a las 09:12 me escribiste: Max Samukha wrote: On Fri, 16 Oct 2009 14:25:44 +0200, Don nos...@nospam.com wrote: Yes, but you could allocate the data immediately after the Array structure, so you only have one allocation. And in the common case, where it never exceeds the original capacity, they stay together and preserve cache locality. void *data; // = raw_data; size_t length; size_t capacity; // = 512 ubyte[512] raw_data; Great! And if the length later exceeds the capacity, try to reallocate in place. If impossible, allocate a new block, copy the data, adjust the data pointer and shrink the original block to the size of the Array struct. Right? That's the idea. The only problem that Walter pointed out was that moving GCs may have a problem with internal pointers. GC have to support internal pointers anyways, I don't see how this changes anything... -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- We're rotten fruit We're damaged goods What the hell, we've got nothing more to lose One gust and we will probably crumble We're backdrifters
Re: dmd support for IDEs and the D tool chain
Ary Borenszweig, el 16 de octubre a las 14:20 me escribiste: I can't agree more. Everything you wrote is in my TODO list, starting with a compiler, which already compiles most of the druntime (and hopefully will compile it fully by the end of this week). I'll release it to public as soon as Brad creates a project page at dsource. Is it a port of DMD? Because I think the main problem with above is that the front-end is not very good... I think it has a lot of evolved code and starting from scratch might be a good idea. And the back-end is not free! You can't distributed and I don't think it can be ported. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- El techo de mi cuarto lleno de cometas
D and open development model
Hi, I'm sorry to spam here with self references, but I don't know if Walter and other D developers read Planet D, and I really appreciate if they could read this blog post: D and open development model: http://llucax.com.ar/blog/blog/post/6cac01e1 This tries to be a constructive criticism and a recognition to the advances made in the last year(s?). I was about to write it directly to the D group but I thought it could hit a more wider audience as a blog post, and it could attract some people that had left D because of its closeness. I hope you find it useful. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- The difference is simple: hackers build things, crackers break them.
Re: D and open development model
bearophile, el 15 de octubre a las 17:49 me escribiste: Leandro Lucarella: I hope you find it useful. Wonderful, baby steps lead you to many places :-) Thank you for that post. Isn't GIT better for CVS? Of course. Maybe you mistaken DVCS (Distributed Version Control System) with CVS? I didn't mentioned CVS at all (it's ancient and I wouldn't recommend it at all). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- More than 50% of the people in the world have never made Or received a telephone call
Re: D and open development model
Andrei Alexandrescu, el 15 de octubre a las 17:01 me escribiste: Leandro Lucarella wrote: Hi, I'm sorry to spam here with self references, but I don't know if Walter and other D developers read Planet D, and I really appreciate if they could read this blog post: D and open development model: http://llucax.com.ar/blog/blog/post/6cac01e1 This tries to be a constructive criticism and a recognition to the advances made in the last year(s?). I was about to write it directly to the D group but I thought it could hit a more wider audience as a blog post, and it could attract some people that had left D because of its closeness. I hope you find it useful. Nice! Mea culpa for the all-too-brief release notes. Now that I know people are looking, I'll beef them up. Thanks =) Mea culpa for waiting too long to ask for it ;) One thing - D2 should be release fairly soon because Andrei is writing a book that has a deadline and the language has to be finalized by the time the book is published. Well that's not quite it happened historically. The impinging release of D2 was conceived to occur concurrently with, not determined by, the book. If I could, I'd probably choose to not have a deadline either but that's not how book publishing works. I know, I was just trying to inform people not involved in D how things are now. I understand the book situation and I know is a tricky one, because having a book is another *huge* step to let D hit mainstream. So I agree is a compromise one have to make. As far as commit notification goes, no later than yesterday I asked Brad Anderson about automated emails. He said he's a bit strapped for time, but will arrange soon such that Phobos commits are emailed to an address on my server. I'll create a mailing list open to anyone interested. That's very nice to hear! Thanks. Thanks for a nice article. No problem, it's good to know that it was appreciated. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Señor, usted es militar? - No, no. Tiene un hermano militar? - No, no, no. Tiene algún pariente militar? - No, no, no, no. Tiene algún amigo íntimo militar? - No, no, pero por qué me lo pregunta? Porque me está pisando el pie. -- Tato vs. Tato (1980, Gobierno de Videla)
Re: D and open development model
Bill Baxter, el 15 de octubre a las 15:51 me escribiste: On Thu, Oct 15, 2009 at 3:01 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: Leandro Lucarella wrote: Hi, I'm sorry to spam here with self references, but I don't know if Walter and other D developers read Planet D, and I really appreciate if they could read this blog post: D and open development model: http://llucax.com.ar/blog/blog/post/6cac01e1 This tries to be a constructive criticism and a recognition to the advances made in the last year(s?). I was about to write it directly to the D group but I thought it could hit a more wider audience as a blog post, and it could attract some people that had left D because of its closeness. I hope you find it useful. Nice! Mea culpa for the all-too-brief release notes. Now that I know people are looking, I'll beef them up. One thing - D2 should be release fairly soon because Andrei is writing a book that has a deadline and the language has to be finalized by the time the book is published. Well that's not quite it happened historically. The impinging release of D2 was conceived to occur concurrently with, not determined by, the book. If I could, I'd probably choose to not have a deadline either but that's not how book publishing works. As far as commit notification goes, no later than yesterday I asked Brad Anderson about automated emails. He said he's a bit strapped for time, but will arrange soon such that Phobos commits are emailed to an address on my server. I'll create a mailing list open to anyone interested. Thanks for a nice article. It wasn't mentioned, so I'm not sure if everyone is aware that the commits have been available by RSS feed from Dsource ever since Phobos and DMD appeared there. (In fact there's a feed for all projects on dsource). You're right, I forgot to mention the RSS. I'm subscribed to it, that's how I peek at the commits now. But the (current) RSS is far from ideal because the patch is not part of the RSS article body, so I have to click on each and every commit to see the actual patch. And RSS is one way only, so you can't give feedback. But the new mailing list will change that, fortunately :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- MATAN AL PERRO: DICEN QUE ESTABA POSEIDO POR EL DEMONIO... -- Crónica TV
Re: dmd 1.050 and 2.035 release
Walter Bright, el 14 de octubre a las 20:46 me escribiste: The main purpose of this is to correct a couple of regressions that were blocking QtD and Tango. http://www.digitalmars.com/d/1.0/changelog.html http://ftp.digitalmars.com/dmd.1.050.zip http://www.digitalmars.com/d/2.0/changelog.html http://ftp.digitalmars.com/dmd.2.035.zip Many thanks to the numerous people who contributed to this update. Thanks for the first releases with full svn history! 8-) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Wake from your sleep, the drying of your tears, Today we escape, we escape.
Re: dmd 1.049 and 2.034 release
Walter Bright, el 13 de octubre a las 14:16 me escribiste: Rainer Schuetze wrote: Hi, the problem is related to a change that was probably done to improve http://d.puremagic.com/issues/show_bug.cgi?id=1170 see my comments there for more details. I checked into svn a compiler change folding in your patch. Can you try it out with QtD? Thanks for the small commits :) BTW, unless you're planning to skip DMD 2.035, I think you increased the DMD 2 version accidentally to 2.036 ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Yeah, I'm a great quitter. It's one of the few things I do well. I come from a long line of quitters. My father was a quitter, my grandfather was a quitter... I was raised to give up. -- George Constanza
Re: Revamped concurrency API
Jeremie Pelletier, el 13 de octubre a las 01:59 me escribiste: Leandro Lucarella wrote: Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ I know of this article, he mentions the word but he doesn't say where it comes from. My native language is french (I'm from Quebec, Canada), I don't know every word of the english dictionary. That's why I asked, I'm just curious as to what it meant. Woops! Sorry, I understood exactly the opposite from you mail =/ -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Sus discipulos se miraron sin entended hasta que uno preguntose: Peperino, soy Daniel Q. de Olivos tengo 54 años y aún soy virgen. A lo que Peperino respondiole: Si sos ganso, ganso ser. Y lo frotó, y lo curó y lo sanó. A lo que todos dijeron: ¡¡¡Peperino se la come, Peperino se la come!!! -- Peperino Pómoro
Re: dmd development model.
Robert Clipsham, el 13 de octubre a las 16:26 me escribiste: Leandro Lucarella wrote: The RC can be just a tag in the VCS (I think it would be nicer to have an easily distributable package though, Robert even offered himself to do nightly builds automatically for you, so that shouldn't be a problem if the offer is still open). This is still on my to do list... I've pretty much got what I want working manually now, just gotta find some time to set it up to run automatically. Once it's in place, having smaller commits will really make it more useful as you'll be able to pinpoint the exact changes which caused issues or made improvements. Thanks Robert for taking care of this. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- I've always been mad, I know I've been mad, like the most of us... very hard to explain why you're mad, even if you're not mad...
Re: Amusing D facts: typesafe variadic arrays are lazy!
Andrei Alexandrescu, el 13 de octubre a las 10:30 me escribiste: downs wrote: Did you know the following code compiles? module test; import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { debug if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } void main() { Assert(false, O hai thar! ); } It's true! :) Gosh!!! What's happening over here? I even tried this: import std.stdio; void Assert(bool cond, string delegate()[] dgs...) { if (!cond) { string str; foreach (dg; dgs) str ~= dg(); throw new Exception(str); } } string fun(string a, string b) { writeln(Concatenating...); return a ~ b; } void main() { Assert(true, fun(O hai thar! , wyda)); Assert(false, fun(O hai thar! , wyda)); } This example only prints Concatenatning... once, meaning that fun is also lazified!!! This is very exciting! The fact that this little anomaly hasn't caused trouble is a good sign it could actually replace lazy! What is the relation between assert and pure/nothrow? Is assert allowed? I think it should be, since an assert is expressing a very essential property of the software, it can't happen in a normal flow of the program. If this is the case, I guess assert should be kept as a language construct so it can be always be used in pure/nothrow functions. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- En la calle me crucé con un señor muy correcto, que habitualmente anda en Falcon; iba corriendo con dos valijas en la mano y dijo: Voy para Miami, tiene algún mensaje o ... y le dije: No, no, no... -- Extra Tato (1983, Triunfo de Alfonsín)
Re: dmd development model.
Walter Bright, el 12 de octubre a las 14:56 me escribiste: Moritz Warning wrote: I think the people in question are too busy with life atm. but I've also heard that there might not be enough time for review. That's fine, but I've also emailed them that if they needed more time to let me know, and those generated no response either. If people want to be on the beta list, email me and let me know. I was about to ask the same thing via a private mail, but since there is already a public discussion, here is what I think =) I know it could be a little hard for you to change the way you work and start making small self-contained commits, but since there are a lot of bug fixes with patches in bugzilla now (thanks for releasing the code BTW, which made this possible :), at least for those patches, is very easy to do a single commit for each one. And I agree, making DMD releases more organized could improve a *lot* this situation. All you have to do is schedule the release, you can have a period of time where you fold in new changes / bug fixes, then declare a feature freeze (bug fix folding freeze for DMD 1) and make a release candidate. You can give, I don't know, about a week, for testing the RC and if there are no regressions or complains, you do the actual release (or fix the regressions before releasing if there is any). The RC can be just a tag in the VCS (I think it would be nicer to have an easily distributable package though, Robert even offered himself to do nightly builds automatically for you, so that shouldn't be a problem if the offer is still open). I think you are making huge improvements in moving DMD to a more open development model (which I think it's crucial for widespread adoption of D). If you can do smaller commits, improve the release scheduling and do RCs, it would be a new huge step in that direction. Thanks. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- La máquina de la moneda, mirá como te queda! -- Sidharta Kiwi
Re: Revamped concurrency API
Jeremie Pelletier, el 12 de octubre a las 22:45 me escribiste: I agree. Particularly about lent. Immutable and mutable weren't considered complete without const, so I'm surprised that local and shared are considered complete without lent. You can even implement it without escape analysis. Strangely, from what I remember of Bartosz's posts, it was unique that was the sticking point, though you can implement both unique and owned as library types (though they do become less efficient). I may sound ignorant, but that does lent means? I mean the word itself, I couldn't find something relevant on google. The terms unique, shared and lent used here generaly refers to the terms used by Bartoz Milewski in his blog[1]. I think he defines lent in this particular blog post[2], but maybe you might need to read a couple of posts more to understand everything. [1] http://bartoszmilewski.wordpress.com/ [2] http://bartoszmilewski.wordpress.com/2009/05/21/unique_ptr-how-unique-is-it/ -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Sometimes you got to suffer a little in your youth to motivate you to succeed later in life. Do you think if Bill Gates got laid in high school, do you think there'd be a Microsoft? Of course not. You gotta spend a lot of time stuffin your own locker with your underwear wedged up your arse before you think I'm gona take over the world with computers! You'll see I'll show them.
Re: dmd support for IDEs
digited, el 10 de octubre a las 22:19 me escribiste: Walter Bright ?: The nice thing about an xml file is while D is relatively easy to parse, xml is trivial. Why file? An IDE can call compiler process and get output with info from stdout, that will be much faster, and if IDE will need to store the info, it will, or will not, itself. And why XML? XML is seriously bloated, I think JSON can be better. With web 2.0 and all, JSON parsers are almost as popular as XML parser, but much easier to implement :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- For a minute there I lost myself, I lost myself. Phew, for a minute there, I lost myself, I lost myself.
Re: dmd support for IDEs
Walter Bright, el 10 de octubre a las 18:19 me escribiste: In my discussions with companies about adopting D, the major barrier that comes up over and over isn't Tango vs Phobos, dmd being GPL, debugger support, libraries, bugs, etc., although those are important. It's the IDE. They say that the productivity gains of D's improvements are overbalanced by the loss of productivity by moving away from an IDE. And what is it about an IDE that is so productive? Intellisense (Microsoft's word for autocompletion). I think you've got that answer because they are not using D alread. When they start using D, they will start complaining about Phobos vs. Tango, debugger support, librararies, bugs, etc. ;) (maybe not DMD being GPL though, even when I think it's important). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Ah, se va en 1981? Pero por qué? ... Ah, porque ya había sido determinado, entonces quiere decir que pronto vamos a elegir presidente nuevo nosot... Ah, nosotros no? Ah, lo van a elegir en la ... Ah! Quiere que le diga? Muy bien pensado, porque cada vez que lo elegimos nosotros no duran nada! -- Tato vs. Tato (1980, Gobierno de Videla)
Re: dmd support for IDEs
Walter Bright, el 11 de octubre a las 02:38 me escribiste: Lutger wrote: What about file/line/column of the symbol? Is this much work / hard work to add? file/line of course, but I don't see a point to column. See Clang error messages: http://clang.llvm.org/diagnostics.html That's *nice* =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Ever tried? Ever failed? - Try again! Fail better!
Re: dmd support for IDEs
Walter Bright, el 11 de octubre a las 12:40 me escribiste: Leandro Lucarella wrote: I think you've got that answer because they are not using D alread. When they start using D, they will start complaining about Phobos vs. Tango, debugger support, librararies, bugs, etc. ;) (maybe not DMD being GPL though, even when I think it's important). I've heard this from D fans as well, who are unable to get D adopted at work because of the lack of IDE. I can't because of the other issues =( (we don't use an IDE at my work, not at least if you don't consider VIM an IDE =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Soñé que tenia un caballo Que me trataba mejor que vos Tenia tan buena onda con ella Era mi yegua, mucho mas que vos
Re: dmd support for IDEs
Walter Bright, el 11 de octubre a las 14:13 me escribiste: Leandro Lucarella wrote: Walter Bright, el 11 de octubre a las 02:38 me escribiste: Lutger wrote: What about file/line/column of the symbol? Is this much work / hard work to add? file/line of course, but I don't see a point to column. See Clang error messages: http://clang.llvm.org/diagnostics.html That's *nice* =) I agree, it looks good on paper. In fact, I implemented it in the C and C++ compiler from the beginning (1982 or so). It's still in dmc, try it - it'll print out the error message, followed by the source text of the offending line, followed by a ^ under where things went wrong. Nobody cared. Nobody has ever commented on it - and there have been hundreds of thousands of users of it. No magazine review ever mentioned it. When I mention it to people as cool, look at this they never respond. When the conversation is about the quality of error messages, that feature never comes up. So I dropped it for dmd. Nobody noticed. Nobody asked why it was done for dmc, and not for dmd. Nobody asked for it. Nothing. (Until now.) So I am hard pressed to believe this is a worthwhile feature. There is a cost to it in memory consumption and compiler execution time, so it's not quite free. Well, I don't know the reasons for that. Maybe bad timing? I don't know why people didn't like it in the past. I just know it's a damn good feature. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- So you run and you run to catch up with the sun but it's sinking. Racing around to come up behind you again. The sun is the same in a relative way but you're older, Shorter of breath and one day closer to death.
Re: What does Coverity/clang static analysis actually do?
Leandro Lucarella, el 1 de octubre a las 16:24 me escribiste: Walter Bright, el 1 de octubre a las 11:21 me escribiste: I've been interested in having the D compiler take advantage of the flow analysis in the optimizer to do some more checking. Coverity and clang get a lot of positive press about doing this, but any details of exactly *what* they do have been either carefully hidden (in Coverity's case) or undocumented (clang's page on this is blank). All I can find is marketing hype and a lot of vague handwaving. Clang is still in development. It will be released with LLVM in the upcoming 2.6 version for the first time. The C and objective C support is supposed to be fairly mature though, but I guess documenting the static analyzer is not very high in their priority list (maybe this will change after the release). You can ask in the Clang ML, Clang developers (and LLVM in general) are very receptive. I just found this: http://clang-analyzer.llvm.org/available_checks.html -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- El otro día tenía un plan Pero después me olvidé y me comí un flan
Re: clear()
Andrei Alexandrescu, el 9 de octubre a las 11:40 me escribiste: I'm talking with Sean and Walter about taking the first step towards eliminating delete: defining function clear() that clears the state of an object. Let me know of what you think. Bike-shed, but what about the previously suggested name recycle()? I think it make the intention more clear (no pun intended ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Far away across the field The tolling of the iron bell Calls the faithful to their knees To hear the softly spoken magic spells.
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 7 de octubre a las 16:03 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 7 de octubre a las 15:23 me escribiste: You seem to be asserting that without additional built-in language support, manual memory management is unduly difficult. Why so? Because of this: auto x = cast(MyClass) malloc(MyClass.classinfo.init.length); x.__ctor( a, b, c ); // construct ... x.__dtor(); free( cast(void*) x ); :) You even forgot to register your object as a root in the GC, so if your MyClass has any pointers to the GC your program will blow in your face. If you plan to library support to ease this and avoid repetitive and bug-prone work, you can ignore my complains... I too think it would be great to add the necessary support to the stdlib. In fact, since you have a great deal of expertise in the matter, feel free to suggest API functions! They'd need to be approved by Sean too because probably they belong to druntime. I think the only API change should be adding a function to call the destructors but not GC.free() (as David suggested). Then, the other changes are only moving operators to library code. So nothing changes much there. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- No existe nada más intenso que un reloj, ni nada más flaco que una bicicleta. No intenso como el café, ni flaco como escopeta. -- Ricardo Vaporeso
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 6 de octubre a las 21:42 me escribiste: should call a destructor but not call delete() or notify the GC that the memory is free. That is correct. In particular, an object remains usable after delete. Why would you do that? What is the rationale to not notify the GC? Because there may be other live references to the object. But when using delete that's exactly what it should happen. You are hiding a bug if you let that happen on purpose. You're saying that there is a problem, but you're not telling us what's wrong. Why the hell do you want to destroy an object without recycling its memory? Why does the inability to do so cause a problem? The matter has been discussed quite a bit around here and in other places. I'm not having as much time as I'd want to explain things. In short, destroying without freeing memory avoids dangling references and preserves memory safety without impacting on other resources. But D is a system programming language. Well it is but there are quite a few more things at stake. First, it is a reality that it is often desirable to distinguish between calling the destructor and reclaiming memory. D's current delete continues the bad tradition started by C++ of conflating the two. Why is a bad idea? If you are destroying an object, the object will be in an inconsistent state. What's the point of keeping it alive. Again, you're just hiding a bug; letting the bug live longer. The language should try to expose bugs ASAP, not delay the detection. I think is a good idea not to force the GC to free the memory immediately with a delete, but it should if it's easy. Other protection methods as using mprotect to protect the objects pages it's very desirable too, because you can spot an access to a inconsistent (destroyed) object as soon as it first happen. If you wrote delete x; the language should assume you know what you're doing. I think delete should be present in SafeD and if you want manual memory management you should build on malloc and free. If you want to introduce a new semantic, I think you should provide a new method, not change the semantic of an existent one. And BTW, is there any reason why this can't be implemented in the library instead of using an operator? Why don't you provide a destroy() function for that in Phobos? Really, I can't see any advantages on changing the delete operator semantics, only problems. If you only want to deinitialize an object, you can write a .destroy() method for example, and call that. I think delete have a strong established semantic to change it now, and without any gain. It has a thoroughly broken and undesired semantics. It would be a step forward to divorce it of that. Why it's broken? Why it's undesired? In fact i'd love to simply make delete disappear as a keyword and make it a function. I agree on this one, no need for an operator (AFAIK). But again, I don't see how letting the user to use a destroyed object is any safer. It's really bad in fact. It seems like a performance hack to me -- you've got an object that isn't valid anymore, but you want to hang on to the memory for some other purpose. And you could override new() and delete(), but you don't want to incur the performance penalty of calling the runtime to fetch the deallocator. It's a safety hack, not a performance hack. But you shouldn't provide safety where the programmer is not expecting it. delete is for *manual* memory management. It makes no sense to guarantee that the memory is *not* freed. It makes sense not guaranteeing that it will actually be freed either. I think that's a good idea actually, because it gives more flexibility to the GC implementation. I think we should move away from the idea that delete is for manual memory management. We should leave that to the likes of malloc and free alone. Why? Using malloc and free is a lot more trouble, you have to register the roots yourself for example. It's not like you do malloc() and free() and everything works magically. You have to have more knowledge of the GC to use them. Being able to manually manage the *GC* heap (if the GC support that, if not it can make it a NOP) is good IMHO. The only remaining use that I see is a way to reset a shared object without explicitly passing around a reference to the new version of the object. This seems potentially dangerous, and nothing I want for default behavior. Well incidentally at least as of now delete obj puts null in obj... That's nice :) I think it's a false sense of security. Why it's bad for D? (I don't care that much about C++ reasons :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Debemos creer en los sueños del niño
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 7 de octubre a las 13:06 me escribiste: I think is a good idea not to force the GC to free the memory immediately with a delete, but it should if it's easy. Other protection methods as using mprotect to protect the objects pages it's very desirable too, because you can spot an access to a inconsistent (destroyed) object as soon as it first happen. (mprotect is much too coarse to be useful.) With the dispose() function the state of the object will be restored to default construction: void dispose(T)(T obj) if (is(T == class) || is(typeof(*T.init))) { ... call destructor if any ... ... obliterate object with .init ... ... invoke default ctor if any ... } Ok, if you're going to name that dispose, is fine with me. End of discussion. With the addition of calling a constructor after destroying the object, make a little more sense too (I still find it too bug prone, you can end up with corruption if you dispose an object that other part of the program think it's not disposed yet, i.e., in a state different than the recently constructed object). If you want to introduce a new semantic, I think you should provide a new method, not change the semantic of an existent one. Agreed. I hereby vote for deprecating delete with extreme prejudice. And BTW, is there any reason why this can't be implemented in the library instead of using an operator? Why don't you provide a destroy() function for that in Phobos? That sounds great. Really, I can't see any advantages on changing the delete operator semantics, only problems. I agree. I'm glad to see that. Why? Using malloc and free is a lot more trouble, you have to register the roots yourself for example. It's not like you do malloc() and free() and everything works magically. You have to have more knowledge of the GC to use them. Being able to manually manage the *GC* heap (if the GC support that, if not it can make it a NOP) is good IMHO. We can make things a tad better with library functions, but we do need to have a garbage collected heap that guarantees safety. I don't think I understand this very well. What kind of safety? If the user disposed/freed an object before it should, it's an user bug, with unavoidable bad side effects. The best you can do is make the program blow in the user face ASAP. I don't understand what all this have to do with GC safety. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- It's not a lie, if you believe it. -- George Constanza
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 7 de octubre a las 14:16 me escribiste: Sean Kelly wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article dsimcha wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article It is a bad idea because distinguishing between release of (expensive) resources from dangerous memory recycling is the correct way to obtain deterministic resource management within the confines of safety. This is based on two faulty assumptions: 1. Memory is cheap. (Not if you are working with absurd amounts of data). 2. Garbage collection is never a major bottleneck. (Sometimes it's a worthwhile tradeoff to add a few manual delete statements to code and sacrifice some safety for making the GC run less often.) malloc. So for placement construction of a class, I guess it would look something like: auto x = cast(MyClass) malloc(MyClass.classinfo.init.length); x.__ctor( a, b, c ); // construct ... x.__dtor(); free( cast(void*) x ); Is that right? Yes, I think so, but I haven't checked all the details. For example I'm not sure whether __ctor copies .init over the memory before running the user-defined constructor, or expects that to have been done already. My understanding from Walter is that __ctor(x, y, z) are simply the functions this(x, y, z) as written by the user, so you'd need to memcpy the .init by hand before calling __ctor. What I don't understand is why you're willing to make that hard to do manual memory management in D. Do you see that you're making the programmer's job deliberately for no reason? D needs conservative GC, which means slow GC; by definition. D is a system programming language, so it's expected to be fast, but because of the GC there will be often situations where you have to do manual MM. Why are you making that much harder? You know that in the search for safety you'll be making much more unsafe (or bug-prone) to do manual MM? -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Ya ni el cielo me quiere, ya ni la muerte me visita Ya ni el sol me calienta, ya ni el viento me acaricia
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 7 de octubre a las 14:18 me escribiste: Manfred_Nowak wrote: Andrei Alexandrescu wrote: if I saw a highlighted keyword that I had no idea what it does I'd get quite worried Why wouldn't you try to look at the documentation of the language---as you do with the documentation of a library? -manfred I didn't say I wouldn't. I just said I'd be much more worried. My point is, languages are never modular. To be even marginally effective in a language, you must have some understanding of it all. That definitely isn't the case for libraries. Languages are modular when they let you define new syntax, but that's another topic ;) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- You look so tired-unhappy, bring down the government, they don't, they don't speak for us.
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 7 de octubre a las 15:23 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 7 de octubre a las 14:16 me escribiste: Sean Kelly wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article dsimcha wrote: == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article It is a bad idea because distinguishing between release of (expensive) resources from dangerous memory recycling is the correct way to obtain deterministic resource management within the confines of safety. This is based on two faulty assumptions: 1. Memory is cheap. (Not if you are working with absurd amounts of data). 2. Garbage collection is never a major bottleneck. (Sometimes it's a worthwhile tradeoff to add a few manual delete statements to code and sacrifice some safety for making the GC run less often.) malloc. So for placement construction of a class, I guess it would look something like: auto x = cast(MyClass) malloc(MyClass.classinfo.init.length); x.__ctor( a, b, c ); // construct ... x.__dtor(); free( cast(void*) x ); Is that right? Yes, I think so, but I haven't checked all the details. For example I'm not sure whether __ctor copies .init over the memory before running the user-defined constructor, or expects that to have been done already. My understanding from Walter is that __ctor(x, y, z) are simply the functions this(x, y, z) as written by the user, so you'd need to memcpy the .init by hand before calling __ctor. What I don't understand is why you're willing to make that hard to do manual memory management in D. Do you see that you're making the programmer's job deliberately for no reason? D needs conservative GC, which means slow GC; by definition. D is a system programming language, so it's expected to be fast, but because of the GC there will be often situations where you have to do manual MM. Why are you making that much harder? You know that in the search for safety you'll be making much more unsafe (or bug-prone) to do manual MM? You seem to be asserting that without additional built-in language support, manual memory management is unduly difficult. Why so? Because of this: auto x = cast(MyClass) malloc(MyClass.classinfo.init.length); x.__ctor( a, b, c ); // construct ... x.__dtor(); free( cast(void*) x ); :) You even forgot to register your object as a root in the GC, so if your MyClass has any pointers to the GC your program will blow in your face. If you plan to library support to ease this and avoid repetitive and bug-prone work, you can ignore my complains... -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Y tuve amores, que fue uno sólo El que me dejó de a pie y me enseñó todo...
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 6 de octubre a las 11:01 me escribiste: Hello, D currently allows defining class allocators and deallocators. They have a number of problems that make them unsuitable for D 2.0. The most obvious issue is that D 2.0 will _not_ conflate destruction with deallocation anymore: invoking delete against an object will call ~this() against it but will not recycle its memory. I don't think it is a good idea (GC-wise) to say that in the specs. I think the GC implementor should be free to decide if a delete really free the memory or not. Some collectors can do this very naturally (like the current one) and some others don't (like allocators that uses pointer-bump allocation). I think the language should divide destruction and deallocation, but I don't think is a good idea not to notify the GC at all when delete is used. I think the GC should be able to do whatever it feels is good for him (so the user should not rely either on the memory being actually freed or otherwise). -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- If you don't know what direction you should take You don't know where you are
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 6 de octubre a las 19:26 me escribiste: Christopher Wright wrote: What exactly is your suggestion? It seems that you mean that: delete obj; should call a destructor but not call delete() or notify the GC that the memory is free. That is correct. In particular, an object remains usable after delete. Why would you do that? What is the rationale to not notify the GC? You're saying that there is a problem, but you're not telling us what's wrong. Why the hell do you want to destroy an object without recycling its memory? Why does the inability to do so cause a problem? The matter has been discussed quite a bit around here and in other places. I'm not having as much time as I'd want to explain things. In short, destroying without freeing memory avoids dangling references and preserves memory safety without impacting on other resources. But D is a system programming language. If you wrote delete x; the language should assume you know what you're doing. If you only want to deinitialize an object, you can write a .destroy() method for example, and call that. I think delete have a strong established semantic to change it now, and without any gain. It seems like a performance hack to me -- you've got an object that isn't valid anymore, but you want to hang on to the memory for some other purpose. And you could override new() and delete(), but you don't want to incur the performance penalty of calling the runtime to fetch the deallocator. It's a safety hack, not a performance hack. But you shouldn't provide safety where the programmer is not expecting it. delete is for *manual* memory management. It makes no sense to guarantee that the memory is *not* freed. It makes sense not guaranteeing that it will actually be freed either. I think that's a good idea actually, because it gives more flexibility to the GC implementation. The only remaining use that I see is a way to reset a shared object without explicitly passing around a reference to the new version of the object. This seems potentially dangerous, and nothing I want for default behavior. Well incidentally at least as of now delete obj puts null in obj... That's nice :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Never let a fool kiss you, or let a kiss fool you
Re: Eliminate class allocators and deallocators?
Andrei Alexandrescu, el 6 de octubre a las 21:36 me escribiste: I don't think it is a good idea (GC-wise) to say that in the specs. I think the GC implementor should be free to decide if a delete really free the memory or not. Some collectors can do this very naturally (like the current one) and some others don't (like allocators that uses pointer-bump allocation). I think the language should divide destruction and deallocation, but I don't think is a good idea not to notify the GC at all when delete is used. I think the GC should be able to do whatever it feels is good for him (so the user should not rely either on the memory being actually freed or otherwise). I agree insofar as a GC could be tipped by the compiler that no live reference of the object exists after delete. Great! For example, this would let me protect the object pages (if it's a large object that uses one or more full pages) when they are freed so the program segfaults as soon as a deleted object is used when it shouldn't. That could be a nice debugging feature :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Hey you, with you ear against the wall Waiting for someone to call out Would you touch me?
Re: dmd 1.048 and 2.033 releases
Jacob Carlborg, el 5 de octubre a las 16:08 me escribiste: 2. A while ago, (I can't find the post, it may have been on reddit) you mentioned that you were going to add property notation. Is that still going to happen? I'm really looking forward to that, and if not, is there a reason? There are some traces of it in the code: http://www.dsource.org/projects/dmd/changeset/195 search for property. -Steve int bar() @property { return 42; } writeln(bar); Yay! :) Cool :) Unfortunately, this still compiles :( int bar() { return 42; } writeln(%d, bar); And this too: int bar() @property { return 42; } writeln(%d, bar()); So it appears that @property is a noop for now, but is valid syntax. Also interesting from this revelation is that attributes are coming :D I just hope that they also will be user defined. Ok, this is getting interesting... 8-) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Dentro de 30 años Argentina va a ser un gran supermercado con 15 changuitos, porque esa va a ser la cantidad de gente que va a poder comprar algo. -- Sidharta Wiki
Re: DMD svn and contract inheritance
Andrei Alexandrescu, el 5 de octubre a las 19:17 me escribiste: Jason House wrote: Walter Bright Wrote: Robert Clipsham wrote: Leandro Lucarella wrote: Thanks for finally taking this way, Walter =) http://www.dsource.org/projects/dmd/timeline Now that DMD is under version control it should be fairly easy for me to adapt the automated build system used for ldc for dmd. I can set it up to automatically build dmd after a commit, and run dstress/build popular projects and libraries, even package up dmd for Nightly builds and maybe even post the results to the D newsgroups/IRC channels. If you'd be interested to see this Walter, let me know what exactly you want automating/how and where you want results and I'll see about setting it up for you. The problem is if some package fails, then I have a large debugging problem trying to figure out unfamiliar code. With small commits to dmd, it should be trivial to know what small change in dmd caused a user observable change in behavior. If things look good on the dmd side, I'd really hope the code authors would help with debugging their code. Knowing of a failure within an hour is way better than finding out a month later. BTW, such regression tests work much better when all failing tests can be identified. It can help with figuring out patterns. Stopping on the first failure can be somewhat limiting, especially if the failure will stick around for a week. We clearly can't define the language around a best-effort kind of flow analysis. I consider Walter's extra checks during optimization a nice perk, but definitely not something we can consider a part of the language. The language definition must work without those. I guess you answered to the wrong mail, Jason is talking about Robert's offering to set up a build/test bot for DMD, to build and test each commit, using dstress and maybe other popular libraries/programs. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- When I was a child I had a fever My hands felt just like two balloons. Now I've got that feeling once again I can't explain you would not understand This is not how I am. I have become comfortably numb.
Re: Multiple subtyping with alias this and nested classes
Andrei Alexandrescu, el 2 de octubre a las 19:10 me escribiste: Leandro Lucarella wrote: We might have very different taste, but I find that a little... horrible. What do you have against mixins? I think you're trying to use D as C++ :) If mixins work better, all the better. How would you use them to achieve multiple inheritance? Don't design with multiple inheritance in mind, use interfaces + mixins for common functionality instead. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Bermú con papafritas y good show!
Re: Multiple subtyping with alias this and nested classes
Andrei Alexandrescu, el 3 de octubre a las 11:23 me escribiste: Leandro Lucarella wrote: Andrei Alexandrescu, el 2 de octubre a las 19:10 me escribiste: Leandro Lucarella wrote: We might have very different taste, but I find that a little... horrible. What do you have against mixins? I think you're trying to use D as C++ :) If mixins work better, all the better. How would you use them to achieve multiple inheritance? Don't design with multiple inheritance in mind, use interfaces + mixins for common functionality instead. But you're just saying it. I think you'd agree I wouldn't just follow that dogma noncritically just because you told me what to do. No, because the language is designed to do that AFAIK, so it will be much easier and clear (for who writes the code and who reads it). I think you hack with alias this is more obscure (we might be hitting personal taste here, I grant you that). I don't think many people design with multiple inheritance in mind. They design aiming at a good design. But you always have to take into account the tools you have when designing. What's the point of designing a perfect bridge assuming you have a material that doesn't exist? Of course you can do that, but when you hit reality, you'll have to hack your design to fit your real tools. So you can design something that looks like multiple-inheritance, because it's easier (or nicer) to do so. But when you want to put that in reality, you have to choose what tool to use. In C++ you probably want to use MI (because the language has a good support for it), but in D you probably want to use interfaces + mixins (because the language has good support for it). Of course you can even implement it in C, or even assembly; you can implement it as in C in C++ or D too, but it would be harder and more obscure. In my experience, some designs can make gainful use of multiple inheritance of classes, and some of my best designs do use multiple inheritance simply because it was the best tool for the job. Sure, the problem comes when the language don't support MI ;) So, there we are, you have D, which doesn't support MI per se, you have to hack it. You can do it with the nested-inherited-classes+alias-this hack, or by using interfaces+mixins. We agree at least that you have the same result with both right? Then, I guess is just a matter of taste. I simply find much more obscure and complex the nested-inherited-classes+alias-this hack than interfaces+mixins :) Scala supports that with mixins, D supports that with multiple subtyping. I don't know what you mean about multiple subtyping. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- I am so psychosomatic it makes me sick just thinking about it! -- George Constanza
Re: Multiple subtyping with alias this and nested classes
Andrei Alexandrescu, el 3 de octubre a las 12:03 me escribiste: So, there we are, you have D, which doesn't support MI per se, you have to hack it. You can do it with the nested-inherited-classes+alias-this hack, or by using interfaces+mixins. We agree at least that you have the same result with both right? Then, I guess is just a matter of taste. I simply find much more obscure and complex the nested-inherited-classes+alias-this hack than interfaces+mixins :) I don't see using a nested class (or any class) with alias this as a hack. It's the way the whole thing is supposed to work in the first place. Ok, then, I just find it ugly and unnecessary since you can do the same with interfaces+mixins. It's just a matter of personal preferences (as I said in my first mail), there is no point on arguing about it. =) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- I'll take a quiet life, a handshake of carbon monoxide, with no alarms and no surprises, no alarms and no surprises.
Re: Multiple subtyping with alias this and nested classes
Andrei Alexandrescu, el 2 de octubre a las 13:00 me escribiste: I just realized that nested classes work so well with alias this, you'd think it was an evil plot all along. It wasn't, but I'm happy about the coincidence. Here's how to effect multiple subtyping in D very effectively: import std.stdio; class Base1 { void fun() { writeln(Base.fun); } } class Base2 { void gun() { writeln(Base.fun); } } class Multiple : Base1 { // Override method in Base1 override void fun() { writeln(Multiple.fun); } // Override method in Base2 class MyBase2 : Base2 { override void gun() { writeln(Multiple.gun); } } // Effect multiple subtyping Base2 _base2; alias _base2 this; this() { _base2 = new MyBase2; } } void main() { auto obj = new Multiple; Base1 obj1 = obj; obj1.fun(); Base2 obj2 = obj; obj2.gun(); } The program above segfaults because somehow obj2 is null. That is a bug I just reported. For now, you can replace obj2.gun() with obj.gun() to make things work. When we first introduced alias this, I knew multiple subtyping was possible. I didn't expect it to dovetail so nicely with nested classes. We might have very different taste, but I find that a little... horrible. What do you have against mixins? I think you're trying to use D as C++ :) -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- EL PRIMER MONITO DEL MILENIO... -- Crónica TV
Re: A possible leak
bearophile, el 1 de octubre a las 07:23 me escribiste: Can the D GC be improved to avoid such problem, maybe like the CPython GC? And is such improvement worth it (= useful in practical programs)? I've tested it with LDC (using classes instead of structs, because D1 doesn't support struct constructors) and it works with a perfectly stable memory usage. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- A lo que Peperino respondióles: aquel que tenga sabañones que se los moje, aquel que padece calvicie no padece un osito, no es bueno comer lechón en día de gastritis, no mezcleis el vino con la sandía, sacad la basura después de las ocho, en caso de emergencia rompa el vidrio con el martillo, a cien metros desvio por Pavón. -- Peperino Pómoro
Re: A possible leak
bearophile, el 1 de octubre a las 12:39 me escribiste: Leandro Lucarella: I've tested it with LDC (using classes instead of structs, because D1 doesn't support struct constructors) and it works with a perfectly stable memory usage. That's a different situation, the compiler is different, the data structure is different, and the runtime too may be a little different. I have tested with LDC with both structs and classes and the two programs don't leak. Sure, the point was: this is not a problem inherently to the D GC, it's just a bug in a particular (version of the) compiler you are testing. -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Si pudiera acercarme un poco más, hacia vos Te diría que me tiemblan los dos pies, cuando me mirás Si supieras todo lo que me costó, llegar Hoy sabrías que me cuesta respirar, cuando me mirás
Re: Defining some stuff for each class in turn
Andrei Alexandrescu, el 1 de octubre a las 11:25 me escribiste: What do you think? I think this is close to Python metaclasses[1], but much more specific. It's amazing how many cool things one can do with Python metaclasses (there are several articles discussing them[2]) and decorators. I would love to see something similar in D but operating at compile-time. I think it would be nice to point to a more general solution (like AST macros) than implementing all sort of small and specific tricks for each problem instead. [1] http://docs.python.org/reference/datamodel.html#customizing-class-creation [2] http://en.wikipedia.org/wiki/Metaclass http://www.ibm.com/developerworks/linux/library/l-pymeta.html -- Leandro Lucarella (AKA luca) http://llucax.com.ar/ -- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) -- Wake from your sleep, the drying of your tears, Today we escape, we escape.
DMD svn and contract inheritance
Thanks for finally taking this way, Walter =) http://www.dsource.org/projects/dmd/timeline -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) He andáu muchos caminos, muchos caminos he andáu, Chile tiene el buen vino y Suecia, el bacalao. Esta'o Unido tiene el hot do', Cuba tiene el mojito, Guatemala, el cornalito y Brasil la feishoada.