Re: why mkdir can't create tree of dirs?
On Tuesday, 9 February 2016 at 23:23:10 UTC, Jonathan M Davis wrote: On Tuesday, February 09, 2016 20:20:59 Suliman via Digitalmars-d-learn wrote: It's look like that I can only create one nesting level sub folder, for example there is exists dir: D:\foo I can't create dir D:\foo\bar\baz I can only create D:\foo\bar D:\foo\bar Is it's rational limit or it is bug? Here is error when I tried to folder in folder thet do not exists. It's not very handy to write all levels by hands... td.windows.syserror.WindowsException@C:\D\dmd2\windows\bin\..\..\src\phobos\stdfile.d(2048): F:\foo\imgs_projected\jma_vis\1602\123: ╨б╨╕╤Б╤В╨╡╨╝╨╡ ╨╜╨╡ ╤Г╨┤╨╨╡╤В╤Б╤П ╨╜╨░╨╣╤В╨╕ ╤Г╨║╨░╨╖╨░╨╜╨╜╤Л╨╣ ╨┐╤Г╤В╤М. (error 3) You can use std.file.mkdirRecurse instead of std.file.mkdir. std.file.mkdirRecurse is similar to mkdir -p like std.file.mkdir is similar to mkdir. - Jonathan M Davis What profit to split it's in two functions? Why mkdir can't work in recursive mode?
Re: Is this nogc? dmd and gdc disagree
On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote: GDC claims that byKeyValue() allocates a closure, but DMD is just fine with me calling it @nogc. I'm inclined to agree with GDC here, unless DMD is doing some magic so that actually doesn't allocate a closure. I cannot reproduce your results. Your example won't compile for me with DMD HEAD: source/app.d(16,14): Error: function app.Enumap!(E, int).Enumap.byKeyValue is @nogc yet allocates closures with the GC source/app.d(17,37):app.Enumap!(E, int).Enumap.byKeyValue.__lambda1 closes over variable this at source/app.d(16,14) source/app.d(26,26): Error: template instance app.Enumap!(E, int) error instantiating
Re: How to allocate arrays of objects?
On Thursday, 11 February 2016 at 04:07:18 UTC, cy wrote: The following program segfaults for me, compiling it with dmdv2.070 as well as the latest git. I must be doing it wrong. There's a way to specify class construction, or emplace, or something. But I can't find it! How do I deal with arrays of objects? class A { int stuff; } void main() { A[] as = new A[2]; assert(as.length==2); as[0].stuff = 42; } Looking at it in gdb, the program segfaults on "A[] as = new A[2]" and never reaches "as[0].stuff = 42". But removing "as[0].stuff = 42" causes the program to stop segfaulting! assert(as.length == 2) doesn't get reached either. You've allocated space for two class references, but you haven't actually allocated any class instances. This means both as[0] and as[1] are null, hence your segfault.
Re: How to allocate arrays of objects?
On Thursday, 11 February 2016 at 04:31:12 UTC, cy wrote: Oh, I get it. `as` is an array of 2 pointers to A objects, both pointers set to null. So I need to say like: as[0..$] = new A(); before accessing .stuff on as[0]. Pedantically, no. It's an array of two class references. I don't think it's helpful to think of class references as pointers. That's just an implementation detail. Still no clue why it segfaulted on the allocation though, rather than the statement with the null dereference. Hidden optimization? You said, removing "as[0].stuff = 42" causes the program to stop segfaulting! Which indicates that was where the segfault was happening. The debugger was just stopping before that.
Re: Things that keep D from evolving?
On Thursday, 11 February 2016 at 04:51:39 UTC, Matt Elkins wrote: - Syntactic sugars (associtive arrays, powerful foreach, slices...) I'm still adjusting to the idea of AAs as part of the language rather than library. Not sure I like it, but on the other hand it doesn't really hurt. The foreach construct isn't any better (or worse) than C++'s, unless I'm missing something (which is very possible). But slices are awesome! In D you can `foreach` over a list of types (AliasSeq) at compile time, not just over ranges at runtime. (For the moment, it's still only available in function bodies though, unlike `static if`.)
Re: Odd Associative Array Reference Behavior
On 2/10/16 10:10 PM, Matt Elkins wrote: Consider the following definition of Foo and an accompanying unittest: [code] struct Foo { @property int[int] aa() {return m_aa;} @property ref int[int] aaRef() {return m_aa;} int[int] m_aa; } unittest { Foo foo; assert(5 !in foo.m_aa); // Sanity-check to start off foo.aa[5] = 1; // Add an element with key 5 assert(5 !in foo.m_aa); // ...huh. 5 didn't make it in? foo.aaRef[5] = 1; // Try again, using the ref variant assert(5 in foo.m_aa); // Works! } [/code] I was under the impression that associative arrays are reference types; if I pass a non-ref "copy" of one, shouldn't insertions still be reflected in the original? Am I dealing with a bug or a misunderstanding on my part? Misunderstanding. An AA under the hood is simply a pointer. Initialized to null. When you pass it around, you are passing a pointer. AA assign checks for null and allocates a new AA impl to hold the data. But this doesn't affect other copies (that were null). So what is happening is aa() returns a null AA. You assign to it, which allocates a new AA impl, and sets the rvalue to point at it. The rvalue promptly disappears. The original m_aa is still set to point at null. If you add more elements, you will see you can do so using the non-ref version. It's only on the first assignment that the reference changes. After that, it's the same reference forever (unless reassigned of course). -Steve
Re: Things that keep D from evolving?
On Wednesday, 10 February 2016 at 20:21:22 UTC, Chris Wright wrote: On Wed, 10 Feb 2016 08:57:51 +, thedeemon wrote: Currently (at least last time I checked) GC pauses the world, then does all the marking in one thread, then all the sweeping. Right. We can do the marking in several parallel threads (this is much harder to implement but still doable), Parallel marking would not be a breaking change by any means. No user code runs during GC collections, so we can do anything. The major fly in the ointment is that creating threads normally invokes the GC, since Thread is an object, and invoking the GC during a collection isn't the best. This can be solved by preallocating several mark threads. Then you just divide the stack and roots between those threads. Moderately annoying sync issues This doesn't guarantee an even distribution of work. You can solve that problem with a queue, though that requires locking. The main wrinkle is writing a bit to shared data structures, which can be slow. On the other hand, in the mark phase, we're only ever going to write the same value to each, so it doesn't matter if GC thread A . I don't know how to tell the CPU that it doesn't have to read back the memory before writing it. and we can kick the sweeping out of stop-the-world pause and do the sweeping lazily This would be a breaking change. Right now, your destructors are guaranteed to run when no other code is running. You'd need to introduce locks in a few places. I'm not saying this is a bad thing. I think people generally wouldn't notice if we made this change. But some code would break, so we'd have to stage that change. Anyway, I'm hacking up parallel mark phase to see how it would work. I could use some GC benchmarks if anyone's got them lying around. https://github.com/D-Programming-Language/druntime/tree/master/benchmark/gcbench
How to allocate arrays of objects?
The following program segfaults for me, compiling it with dmdv2.070 as well as the latest git. I must be doing it wrong. There's a way to specify class construction, or emplace, or something. But I can't find it! How do I deal with arrays of objects? class A { int stuff; } void main() { A[] as = new A[2]; assert(as.length==2); as[0].stuff = 42; } Looking at it in gdb, the program segfaults on "A[] as = new A[2]" and never reaches "as[0].stuff = 42". But removing "as[0].stuff = 42" causes the program to stop segfaulting! assert(as.length == 2) doesn't get reached either.
Re: Things that keep D from evolving?
On Tuesday, 9 February 2016 at 13:41:30 UTC, NX wrote: There are several reasons I want to use D rather than C# / Go / something else: I will focus on comparing against C++, because that has been my favorite general purpose language for a long time. While I often have to use C, Java, C#, etc. for various business reasons, when faced with the choice on pure technical merits I will go for C++ any day (haven't tried Go, but was unimpressed by my initial read-over). D is the first language I have ever encountered with a serious chance of unseating C++ as my personal favorite. - Interfacing with native API without jumping through hoops Concur. Though I get this with C++, too. - Incredibly high abstraction and meta-programming possibilities with relatively easier syntax + semantics. Yes. The lack of powerful meta-programming is so frustrating in languages like Java and C#. C++ and D both have the power, but only D has the ease of reading and writing. - It's harder to reverse engineer native code than byte code equivalent. Meh. True, but this doesn't do much for me; it still isn't -that- hard to reverse native code, at least to the point of exploitation (to the point of copying is much harder). It just takes longer. - Trading off anything according to your needs. Yes. This is critical. I actually feel like D does this a little worse than C++ (though not significantly so), if only because it is difficult to completely avoid the GC, and if you want to avoid it and still use inheritance you need to break out the custom allocators. Most of the time this isn't a problem. - Expressiveness and purity, immutablity concepts. Expressiveness is key, though I haven't found D to be terribly more expressive than C++. A little better here, a little worse there. On the other hand, it is usually syntactically nicer when expressing concepts, sometimes greatly so. Immutability is nice. The attention paid to threading was what caused me to take a closer look at D in the first place. - Having GC (but not a horribly slow one) Meh. I know there are things which are much easier to express with a GC, but they don't really come up for me. On the other hand, I often need deterministic cleanup, so the GC can be kind of an annoyance, since it lends itself to a lot of wrapping things in structs and forcing me to pay more attention to lifetime rules than I have to in C++. The other (main?) purported benefits of a GC (avoiding leaks and dangling pointers) don't do much for me, since it is almost trivially easy to avoid those problems in C++ anyway, without introducing the headaches of the GC; certainly it is easier than the focus I have to give D object lifetimes now. That may be a matter of relative practice, though, since I've used C++ for a long long time and D for...3 weeks? :) - Syntactic sugars (associtive arrays, powerful foreach, slices...) I'm still adjusting to the idea of AAs as part of the language rather than library. Not sure I like it, but on the other hand it doesn't really hurt. The foreach construct isn't any better (or worse) than C++'s, unless I'm missing something (which is very possible). But slices are awesome! - Compile times Oh god yes. This makes metaprogramming so much more palatable. - Not bound to a specific platform (unlike C#, easier to do cross-platform work in many cases) I'll go it one step further, and note that D feels more portable than C++ to me...at least to the major platforms I usually work on. Maybe it's the simple fact that things like sockets are defined in the libraries, or that I don't have to #include :). I wish D could be better. I really want it with all of my heart... D has a lot to offer. Here are a few other things I've really liked over C++: * Modules. C++ is supposed(?) to get them at some point I suppose, but for here and now it's a clear advantage for D. * Not syntactically separating interface and implementation (e.g., C++'s header vs source file dichotomy). This was never a true separation in C++, and just led to lots of extra syntax and minor DRY violations. Of course you could write everything inline anyway...until it depended on something declared later. * Related to the point above, not having to think about whether to make something inline. Sure, C++ compilers make that choice for you, but you still have to decide whether to allow them (or at least the ones without link-time code generation) by putting your source in the header file. Needless headache for something a compiler can do. * Properly doing away with the C preprocessor. I haven't seen a need for it that wasn't addressed by another D feature. * Properly doing away with MI. Unlike some languages which just canned it, D actually replaced its functionality with other features. * Thread-local by default. So simple. So useful. * The in keyword. This is nice syntactic sugar over having a special trait in C++ which
Re: Things that keep D from evolving?
On Thursday, 11 February 2016 at 05:05:22 UTC, tsbockman wrote: On Thursday, 11 February 2016 at 04:51:39 UTC, Matt Elkins wrote: - Syntactic sugars (associtive arrays, powerful foreach, slices...) I'm still adjusting to the idea of AAs as part of the language rather than library. Not sure I like it, but on the other hand it doesn't really hurt. The foreach construct isn't any better (or worse) than C++'s, unless I'm missing something (which is very possible). But slices are awesome! In D you can `foreach` over a list of types (AliasSeq) at compile time, not just over ranges at runtime. (For the moment, it's still only available in function bodies though, unlike `static if`.) Neat! I didn't know that. You can do that in C++, but in typical fashion not with a convenient foreach statement. You have to do some crazy type list recursion stuff. So chalk up another point for D's "ease of metaprogramming" :).
Does D optimize sqrt(2.0)?
If I just type out sqrt(2.0) in D, is that automatically made into a constant for me? Thanks.
Re: How to allocate arrays of objects?
On Thursday, 11 February 2016 at 04:07:18 UTC, cy wrote: A[] as = new A[2]; assert(as.length==2); as[0].stuff = 42; Oh, I get it. `as` is an array of 2 pointers to A objects, both pointers set to null. So I need to say like: as[0..$] = new A(); before accessing .stuff on as[0]. Still no clue why it segfaulted on the allocation though, rather than the statement with the null dereference. Hidden optimization?
Re: Is this nogc? dmd and gdc disagree
On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote: I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is @nogc. Here's a semi-reduced test-case: Here's an @nogc version of `byKeyValue()`: @nogc auto byKeyValue() const { static immutable keys = [EnumMembers!K]; return zip(keys[], _store[]); } Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V.
Re: Odd Associative Array Reference Behavior
On Thursday, 11 February 2016 at 03:47:09 UTC, Steven Schveighoffer wrote: Misunderstanding. An AA under the hood is simply a pointer. Initialized to null. When you pass it around, you are passing a pointer. AA assign checks for null and allocates a new AA impl to hold the data. But this doesn't affect other copies (that were null). So what is happening is aa() returns a null AA. You assign to it, which allocates a new AA impl, and sets the rvalue to point at it. The rvalue promptly disappears. The original m_aa is still set to point at null. Makes sense (though it defies my intuition; I would have expected an NPE or crash at time of assignment). Thanks!
Algebraic template instance holder
Hi, why this is not working ? class Base{ int a; } class BaseTemplate(E):Base{ E value; this(E value){ this.value=value; } } class Concrete:BaseTemplate!int{ this(int value){ super(value); } } unittest{ Algebraic!(Concrete) holder; Concrete a=new Concrete(4); holder =Algebraic!Concrete(a); }
Re: Things that keep D from evolving?
On Tuesday, 9 February 2016 at 17:41:34 UTC, NX wrote: I would want it to be solved rather than being worked on... which requires design change which is probably not going to happen. There is still room for improvement though. Right. I think there are at least two things that can improve current GC without any changes in design: parallel marking and lazy sweeping. Currently (at least last time I checked) GC pauses the world, then does all the marking in one thread, then all the sweeping. We can do the marking in several parallel threads (this is much harder to implement but still doable), and we can kick the sweeping out of stop-the-world pause and do the sweeping lazily: when you try to allocate some memory it will not just look in free lists, it will try to collect some unused unswept memory from the heap first. This way allocations become a bit slower but GC pause time reduces significantly. Concurrent sweeping is another possibility. Of course, it's all easier said than done, without an actual hero who would code this, it remains just talk.
Is this nogc? dmd and gdc disagree
I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is @nogc. Here's a semi-reduced test-case: --- import std.range; import std.traits: EnumMembers; import std.typecons : tuple, staticIota; import std.algorithm : map; struct Enumap(K, V) if(EnumMembers!K == staticIota!(0, EnumMembers!K.length)) { enum length = EnumMembers!K.length; private V[length] _store; ref auto opIndex(K key) inout { return _store[key]; } @nogc auto byKeyValue() const { return only(EnumMembers!K).map!(key => tuple(key, this[key])); } } @nogc void main() { import std.typecons : tuple; import std.algorithm : map; enum E { a, b, c, d }; immutable elements = Enumap!(E, int)([1,2,3,4]); auto pairs = elements.byKeyValue.map!(pair => tuple(pair[0], pair[1] + 1)); } --- GDC claims that byKeyValue() allocates a closure, but DMD is just fine with me calling it @nogc. I'm inclined to agree with GDC here, unless DMD is doing some magic so that actually doesn't allocate a closure.
Odd Associative Array Reference Behavior
Consider the following definition of Foo and an accompanying unittest: [code] struct Foo { @property int[int] aa() {return m_aa;} @property ref int[int] aaRef() {return m_aa;} int[int] m_aa; } unittest { Foo foo; assert(5 !in foo.m_aa); // Sanity-check to start off foo.aa[5] = 1; // Add an element with key 5 assert(5 !in foo.m_aa); // ...huh. 5 didn't make it in? foo.aaRef[5] = 1; // Try again, using the ref variant assert(5 in foo.m_aa); // Works! } [/code] I was under the impression that associative arrays are reference types; if I pass a non-ref "copy" of one, shouldn't insertions still be reflected in the original? Am I dealing with a bug or a misunderstanding on my part?