Re: sleepy receiveTimeout?
On Sat, 18 Dec 2010 23:19:47 +0100 Joost 't Hart joost.t.h...@planet.nl wrote: Quoting the documentation: /Suspends the calling thread for at least the supplied period./ What does at least mean here? Is there also an at most? I do not want my friend to end up in cyberspace. :-) Nope, there isn't :) In ordinary multitasking environment there is no guarantee on upper bound. -- Nick Voronin elfy...@gmail.com
Re: sleepy receiveTimeout?
Nick Voronin wrote: On Sat, 18 Dec 2010 23:19:47 +0100 Joost 't Hart joost.t.h...@planet.nl wrote: Quoting the documentation: /Suspends the calling thread for at least the supplied period./ What does at least mean here? Is there also an at most? I do not want my friend to end up in cyberspace. :-) Nope, there isn't :) In ordinary multitasking environment there is no guarantee on upper bound. Note that the absence of upper bound is not related to sleep. In ordinary multitasking environment there is no guarantee that your program will not be stopped at some arbitrary point for an arbitrary long time no matter what it does. Jerome -- mailto:jeber...@free.fr http://jeberger.free.fr Jabber: jeber...@jabber.fr signature.asc Description: OpenPGP digital signature
Re: define methods apart
On 12/18/10 07:19, spir wrote: Hello, I cannot find a way to define methods (I mean member functions) outside the main type-definition body: struct X {} void X.say () {writeln(I say!);} == Element.d(85): semicolon expected, not '.' Do I overlook anything, or is this simply impossible? In the latter case, what is the problem? (In many languages, not only dynamic ones, method are or at least can be defined apart.) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com As bearophile says, it just isn't the D way to do things. But, if you absolutely must (or just want to, for playing sakes) there are ways of faking it using opDispatch. Here's one I just tossed together and tested (DMD 2.050) right now. -- import std.stdio; class Foo { static addExternalMethod( void function( Foo ) fp, string id ) { _methodRegistry[ id ] = fp; } private static void function( Foo )[ string ] _methodRegistry; this ( string name ) { _name = name; } @property const string name () { return _name; } private string _name; void opDispatch ( string Id ) () { if ( auto fp = Id in _methodRegistry ) { (*fp)( this ); } } } void _foo_sayHello (Foo self) { writefln( Hello, I am %s., self.name ); } static this () { Foo.addExternalMethod( _foo_sayHello, sayHello ); } void main () { auto foo = new Foo( Grant ); foo.sayHello(); } -- Of course, there is the obvious issue of the 'method' signatures having to be the same, in this case. You'd have to find a better solution to the 'registry' issue, at the very least, in order to make it really usable. Generally speaking, though, I'm not sure what the real value would be in doing this in D. Did you have a particular use case in mind, or was it just idle exploration? -- Chris N-S
Re: sleepy receiveTimeout?
On 12/19/2010 09:56 AM, Nick Voronin wrote: On Sat, 18 Dec 2010 23:19:47 +0100 Joost 't Hartjoost.t.h...@planet.nl wrote: Quoting the documentation: /Suspends the calling thread for at least the supplied period./ What does at least mean here? Is there also an at most? I do not want my friend to end up in cyberspace. :-) Nope, there isn't :) In ordinary multitasking environment there is no guarantee on upper bound. Surely got that bit, but I guess it makes sense to refer a bit more to some good old thread state names: After (exactly!) the given period of suspension the thread returns into ready state. When (if ever) it will become the running thread again depends ... Cheers, Joost
Re: sleepy receiveTimeout?
On Sun, 19 Dec 2010 10:50:08 +0100 Joost 't Hart joost.t.h...@planet.nl wrote: Quoting the documentation: /Suspends the calling thread for at least the supplied period./ What does at least mean here? Is there also an at most? I do not want my friend to end up in cyberspace. :-) Nope, there isn't :) In ordinary multitasking environment there is no guarantee on upper bound. Surely got that bit, but I guess it makes sense to refer a bit more to some good old thread state names: After (exactly!) the given period of suspension the thread returns into ready state. When (if ever) it will become the running thread again depends ... This all nice in theory, but are you sure that every sleep() causes setting of hardware timer? In every OS? In every minor version of OS even? If not (and I'm pretty sure it's not so), then you need to add more details. All about how scheduler works. Or this precise talk on what happen after time is up would just mislead people. Aside from the fact that sometime after time is up thread would become runnable again (which is really obvious, no?) there is nothing to say. -- Nick Voronin elfy...@gmail.com
Re: define methods apart
On Sun, 19 Dec 2010 03:37:37 -0600 Christopher Nicholson-Sauls ibisbase...@gmail.com wrote: On 12/18/10 07:19, spir wrote: Hello, I cannot find a way to define methods (I mean member functions) outside the main type-definition body: struct X {} void X.say () {writeln(I say!);} == Element.d(85): semicolon expected, not '.' Do I overlook anything, or is this simply impossible? In the latter case, what is the problem? (In many languages, not only dynamic ones, method are or at least can be defined apart.) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com As bearophile says, it just isn't the D way to do things. But, if you absolutely must (or just want to, for playing sakes) there are ways of faking it using opDispatch. Here's one I just tossed together and tested (DMD 2.050) right now. [code snipped] Generally speaking, though, I'm not sure what the real value would be in doing this in D. Did you have a particular use case in mind, or was it just idle exploration? Thank you very for this example use of opdispatch :-) I'm still exploring the language (which I like very much, except for some given features *). Actually, I just wanted to know whether it's possible, because I'm used to this way and find it more practicle or readable in various cases. But it is not a problem. Denis (*) Some inherited from C/C++ (unhelpful syntax or semantics, mainly), some among the newest (too abstract or complicated, i'd say). -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: opAssign work not with initialisation?
spir wrote: On Sat, 18 Dec 2010 13:08:14 + Adam Burton adz...@gmail.com wrote: struct S { int value; void opAssign(int value) { this.value = value; } } unittest { S s1; s1 = 3;// OK S s2 = 3; // _build_ error } == Element.d(105): Error: cannot implicitly convert expression (3) of type int to S That compiles for me. I am running 2.050 on linux. Does not with dmd 2.049 on (ubuntu) Linux. If it's solved in 2.050, then let us let down. Actually this is my bad, I forgot to add the unittest switch :-P. Still happens in 2.050. As a work-around try S s2 = S(3), failing that then try adding a constructor that accepts an int (opAssign is only used during assignment, not construction). ;-) Sure, but this bypasses opAssign and assigns .value directly, I guess. What do you think? Yes it will. AFAIK that is how it is supposed to work, opAssign is used for assignment to existing variables and the constructor or initialisation is used when creating it. So even if the above compiled you wouldn't get your call to opAssign in S s2 = 3. Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Classes or stucts :: Newbie
I am new to D (like many have done C++ , Java ). Can a class be instantiated on the stack ? eg class C { private int _I1; private int _I2; public: this(int pI) // constructor { _I1 = pI; _I2 = pI + 1; } // ... other methods etc } void f() // just a function { C myC(3); // C++ syntax BUT is there a d equivalent } It appears that D ASSUMES myC is really a myC*(in C++) and therefore requires C myC = new C(3); // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) Is there any way in D to instantiate a stack object ? Will a struct do? Does a struct have a constructor (as opposed to an opcall?) I would be very grateful for a response. David Currie
Re: Classes or stucts :: Newbie
On Mon, 20 Dec 2010 18:00:31 +0300, David Currie curri...@iinet.net.au wrote: I am new to D (like many have done C++ , Java ). Can a class be instantiated on the stack ? eg class C { private int _I1; private int _I2; public: this(int pI) // constructor { _I1 = pI; _I2 = pI + 1; } // ... other methods etc } void f() // just a function { C myC(3); // C++ syntax BUT is there a d equivalent } It appears that D ASSUMES myC is really a myC*(in C++) and therefore requires C myC = new C(3); // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) Is there any way in D to instantiate a stack object ? Will a struct do? Does a struct have a constructor (as opposed to an opcall?) I would be very grateful for a response. David Currie Try the following: scope c = new C(3); Unfortunately last I've heard it's going to be deprecated in favor of a library solution: InSitu!(C) c = InSitu!(C)(3); // IIRC not implemented yet
Re: Classes or stucts :: Newbie
On Mon, 20 Dec 2010 18:00:31 +0300, David Currie curri...@iinet.net.au wrote: I am new to D (like many have done C++ , Java ). Can a class be instantiated on the stack ? eg class C { private int _I1; private int _I2; public: this(int pI) // constructor { _I1 = pI; _I2 = pI + 1; } // ... other methods etc } void f() // just a function { C myC(3); // C++ syntax BUT is there a d equivalent } It appears that D ASSUMES myC is really a myC*(in C++) and therefore requires C myC = new C(3); // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) Is there any way in D to instantiate a stack object ? Will a struct do? Does a struct have a constructor (as opposed to an opcall?) I would be very grateful for a response. David Currie To your second question, yes, structs would do: struct C { this(int i) { ... } } C c = C(3);
Re: Classes or stucts :: Newbie
David Currie: I am new to D (like many have done C++ , Java ). Welcome to D :-) What language do you refer to, D1 or D2? The answers here are about the latest versions of D2. Can a class be instantiated on the stack ? There was a way built in the language to do that (using scope, it works still but it's deprecated), but now you have to use the std library. See the std.conv.emplace, but keep in mind it has issues (more than the issues of scope!) like I think not calling the object destructor. It appears that D ASSUMES myC is really a myC*(in C++) Right, in D class instances are always managed by reference, even when you allocate them on the stack using the emplace trick. // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) A difference is that the Oracle Java Garbage Collector has a Eden memory for the newly allocated objects that's much faster than the current D GC :-) Will a struct do? Sometimes a struct is enough. D structs are managed by value or by pointer, but they don't support inheritance. In D structs and classes are different (like the memory layout of a class instance is decided by the compiler, while struct fields are in memory as you want them, with the alignment you desire) and they are used for different purposes. Does a struct have a constructor (as opposed to an opcall?) In D2 the struct constructor is this() as for classes. Bye, bearophile
Re: Classes or stucts :: Newbie
Denis Koroskin: Unfortunately last I've heard it's going to be deprecated in favor of a library solution: InSitu!(C) c = InSitu!(C)(3); // IIRC not implemented yet It's named scoped, see about its problems: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Bye, bearophile
Re: Classes or stucts :: Newbie
On 12/20/2010 04:00 PM, David Currie wrote: I am new to D (like many have done C++ , Java ). Me too. Let's see what we can figure out together :-) Can a class be instantiated on the stack ? eg class C { private int _I1; private int _I2; public: this(int pI) // constructor { _I1 = pI; _I2 = pI + 1; } // ... other methods etc } void f() // just a function { C myC(3); // C++ syntax BUT is there a d equivalent } It appears that D ASSUMES myC is really a myC*(in C++) It is not so much a *, but reference semantics (like T param in C++). and therefore requires C myC = new C(3); // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) Is there any way in D to instantiate a stack object ? Not a class object. Only values are on the stack. The reference semantics requires a living entity to refer to. Will a struct do? Yes, if you so wish, but new also works. Structs have value semantics. Does a struct have a constructor (as opposed to an opcall?) You can define one, but you cannot redefine the default this() constructor. Because structs have value semantics, D wants to make sure that T.init member values are slotted in by default. Note that T.init for a class type is the null reference. I would be very grateful for a response. Hope this helps a bit. Cheers, Joost. David Currie
Re: Classes or stucts :: Newbie
See the std.conv.emplace, Sorry, see std.typecons.scoped and its problems: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Bye, bearophile
Re: Classes or stucts :: Newbie
There's also scoped() in std.typecons, but I think this will still allocate on the heap. Not sure.. On 12/19/10, bearophile bearophileh...@lycos.com wrote: David Currie: I am new to D (like many have done C++ , Java ). Welcome to D :-) What language do you refer to, D1 or D2? The answers here are about the latest versions of D2. Can a class be instantiated on the stack ? There was a way built in the language to do that (using scope, it works still but it's deprecated), but now you have to use the std library. See the std.conv.emplace, but keep in mind it has issues (more than the issues of scope!) like I think not calling the object destructor. It appears that D ASSUMES myC is really a myC*(in C++) Right, in D class instances are always managed by reference, even when you allocate them on the stack using the emplace trick. // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) A difference is that the Oracle Java Garbage Collector has a Eden memory for the newly allocated objects that's much faster than the current D GC :-) Will a struct do? Sometimes a struct is enough. D structs are managed by value or by pointer, but they don't support inheritance. In D structs and classes are different (like the memory layout of a class instance is decided by the compiler, while struct fields are in memory as you want them, with the alignment you desire) and they are used for different purposes. Does a struct have a constructor (as opposed to an opcall?) In D2 the struct constructor is this() as for classes. Bye, bearophile
Re: Classes or stucts :: Newbie
On 12/19/10, bearophile bearophileh...@lycos.com wrote: See the std.conv.emplace, Sorry, see std.typecons.scoped and its problems: http://d.puremagic.com/issues/show_bug.cgi?id=5115 Bye, bearophile Is this another bug?: import std.stdio; import std.typecons; class A { ~this() { writeln(dtor); } } void main() { { A a1 = scoped!A(); // doesn't call dtor after the scope auto a2 = scoped!A(); // calls dtor after the scope } }
Re: Classes or stucts :: Newbie
Andrej Mitrovic: There's also scoped() in std.typecons, but I think this will still allocate on the heap. Not sure.. It allocates on the stack. Bye, bearophile
Re: Classes or stucts :: Newbie
Andrej Mitrovic: Is this another bug?: I don't exactly know what's going on, but I have added a modified version of your code to the issue 5115. Bye, bearophile
Re: Classes or stucts :: Newbie
On Mon, 20 Dec 2010 07:00:31 -0800 David Currie curri...@iinet.net.au wrote: Can a class be instantiated on the stack ? Yes, check std.conv.emplace http://www.digitalmars.com/d/2.0/phobos/std_conv.html#emplace and alloca() I don't know details about interaction of such objects with GC though. Also there is scarcely documented storage class scope, which for class objects means that they will be destroyed upon scope exit, but also currently results in that object itself will be placed on the stack, no memory in heap is allocated. C myC(3); // C++ syntax BUT is there a d equivalent It appears that D ASSUMES myC is really a myC*(in C++) Not exactly. All class objects have reference semantic, so when you declare variable of type C you really declare a reference. The reference is what you get from new, pass as parameters, etc. Will a struct do? structs on the contrary have value semantic, so when you declare struct variable you get the memory for struct allocated on stack or in data segment. When you pass or return structs -- you return or pass value, that is a copy of data. You may be also interested in the way dynamic arrays are handled, as arrays are value type, yet they hold a pointer to memory. This means that passing them as parameter or returning them does copy pointer and length, but actual data is stil shared until you do something which will force D to relocate it. All kind of not obvious implications here. Does a struct have a constructor (as opposed to an opcall?) Yes, and more. http://www.digitalmars.com/d/2.0/struct.html -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On Monday 20 December 2010 07:00:31 David Currie wrote: I am new to D (like many have done C++ , Java ). Can a class be instantiated on the stack ? eg class C { private int _I1; private int _I2; public: this(int pI) // constructor { _I1 = pI; _I2 = pI + 1; } // ... other methods etc } void f() // just a function { C myC(3); // C++ syntax BUT is there a d equivalent } It appears that D ASSUMES myC is really a myC*(in C++) and therefore requires C myC = new C(3); // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) Is there any way in D to instantiate a stack object ? Will a struct do? Structs are value types. Therefore, they go on the stack unless you have a pointer to them. struct Foo {} Foo a; //on stack Foo* b = new Foo(); //on heap Classes are reference types. The are therefore always on the heap. It's like what you get in Java. class Bar {} Bar a; //On the heap. Structs do not have inheritance (and thus don't have polymorphism), but they can be used for RAII. Assigning one to another means copying it (or moving it if the compiler determines that it can). Because struct member functions are not virtual, they often can be inlined. Classes do have inheritance (and thus do have polymorphism), but they can't use RAII. Assigning one to another means assigning a reference. Both references now refer to the same object. You'll have to use a clone method of some kind to get an actualy, deep copy. Because class member functions are almost always virtual, it's much rarer that they can be inlined. The language did have scoped classes, which put the class itself on the stack instead of the heap: class Bar {} scope Bar a; //On the stack. But it's inherently unsafe, so it's being removed from the language. There will be a library solution to do it, but again, it's unsafe. If you were to pass a scaped class to any other function, you risk the reference escaping, and then you'll end up with a reference to an object that doesn't exist once the function that declared it exits. Classes are meant to be on the heap. structs are meant to be on the stack but can be on the heap. Generally-speaking, if you use a class if you need a reference type or need polymorphism. Otherwise, you use a struct (reasons for using one or the other can, of course, get more complicated that that, but that's the core of it). Allowing classes on the like C++ does allows for problems like sheering and disallows polymorphism. D opted to split the concept into two different types of types: classes and structs. The language which is closest to D with regards to structs and classes that I'm aware of is C#, though I believe that D structs are definitely more powerful than C# structs. In D, you just don't use classes as often as you'd do in Java or C++, because structs in D do a lot of what classes do in those languages. For any user-defined type, you need to decide whether a struct or a class is more appropriate for what you're trying to do. The approach has definite benefits, but it does take some getting used to. Does a struct have a constructor (as opposed to an opcall?) structs can have constructs just like classes - they just can't have default constructors. The reason for this is that all types in D have an init property that variables of that type are initialized to when they are default initialized. For integral types, it's 0; for bool, it's false; for references and pointers it's null; etc. For structs, it's what the member variables are directly initialized to. init precludes having an arbitrary constructor, because init must be determinable at compile time, can't have exceptions being thrown, etc. We may get some sort of limited default constructor for structs at some point, but it's not at all straightforward to have one, so we don't. The solution then, if you need one, is to use a static opCall() function, and then do Foo a = Foo(); //calls static opCall(). instead of Foo a; //Just uses Foo.init. So, structs _do_ have constructors, just not default constructors. - Jonathan M Davis
Re: Classes or stucts :: Newbie
Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Bye, bearophile
Re: Classes or stucts :: Newbie
On Sunday 19 December 2010 13:23:42 Jonathan M Davis wrote: On Monday 20 December 2010 07:00:31 David Currie wrote: I am new to D (like many have done C++ , Java ). Can a class be instantiated on the stack ? eg class C { private int _I1; private int _I2; public: this(int pI) // constructor { _I1 = pI; _I2 = pI + 1; } // ... other methods etc } void f() // just a function { C myC(3); // C++ syntax BUT is there a d equivalent } It appears that D ASSUMES myC is really a myC*(in C++) and therefore requires C myC = new C(3); // but this ALWAYS requires calling the memory allocator // this is what Java does (forces your Class instance onto the Heap) Is there any way in D to instantiate a stack object ? Will a struct do? Structs are value types. Therefore, they go on the stack unless you have a pointer to them. struct Foo {} Foo a; //on stack Foo* b = new Foo(); //on heap Classes are reference types. The are therefore always on the heap. It's like what you get in Java. class Bar {} Bar a; //On the heap. Structs do not have inheritance (and thus don't have polymorphism), but they can be used for RAII. Assigning one to another means copying it (or moving it if the compiler determines that it can). Because struct member functions are not virtual, they often can be inlined. Classes do have inheritance (and thus do have polymorphism), but they can't use RAII. Assigning one to another means assigning a reference. Both references now refer to the same object. You'll have to use a clone method of some kind to get an actualy, deep copy. Because class member functions are almost always virtual, it's much rarer that they can be inlined. The language did have scoped classes, which put the class itself on the stack instead of the heap: class Bar {} scope Bar a; //On the stack. But it's inherently unsafe, so it's being removed from the language. There will be a library solution to do it, but again, it's unsafe. If you were to pass a scaped class to any other function, you risk the reference escaping, and then you'll end up with a reference to an object that doesn't exist once the function that declared it exits. Classes are meant to be on the heap. structs are meant to be on the stack but can be on the heap. Generally-speaking, if you use a class if you need a reference type or need polymorphism. Otherwise, you use a struct (reasons for using one or the other can, of course, get more complicated that that, but that's the core of it). Allowing classes on the like C++ does allows for problems like sheering and disallows polymorphism. D opted to split the concept into two different types of types: classes and structs. The language which is closest to D with regards to structs and classes that I'm aware of is C#, though I believe that D structs are definitely more powerful than C# structs. In D, you just don't use classes as often as you'd do in Java or C++, because structs in D do a lot of what classes do in those languages. For any user-defined type, you need to decide whether a struct or a class is more appropriate for what you're trying to do. The approach has definite benefits, but it does take some getting used to. Does a struct have a constructor (as opposed to an opcall?) structs can have constructs just like classes - they just can't have default constructors. The reason for this is that all types in D have an init property that variables of that type are initialized to when they are default initialized. For integral types, it's 0; for bool, it's false; for references and pointers it's null; etc. For structs, it's what the member variables are directly initialized to. init precludes having an arbitrary constructor, because init must be determinable at compile time, can't have exceptions being thrown, etc. We may get some sort of limited default constructor for structs at some point, but it's not at all straightforward to have one, so we don't. The solution then, if you need one, is to use a static opCall() function, and then do Foo a = Foo(); //calls static opCall(). instead of Foo a; //Just uses Foo.init. So, structs _do_ have constructors, just not default constructors. I should probably add that structs can have reference semantics as well if they have pointers or references internally, and they don't have a postblit constructor or, it doesn't do a deep copy (a postblit constructor - this(this) - being the constructor which runs after a struct has been memcpy-ed by the compiler, since the default copying of a struct uses memcpy). structs are generally value types, however, and classes are always reference types. - Jonathan M Davis
Re: Classes or stucts :: Newbie
On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. The compiler can help, but it can't fix the problem any more that it can guarantee that a pointer to a local variable doesn't escape once you've passed it to another function. In _some_ circumstances, it can catch escaping pointers and references, but in the general case, it can't. If we have library solutions for people who want to play with fire, that's fine. But scoped classes is just not one of those things that the language really needs. They complicate things unnecessarily for minimal benefit. - Jonathan M Davis
rdmd bug?
Hello, I'm being driven nuts by this problem, I don't know 100% if it's it's a bug or if it's intended behavior, I'm new to D( also new to reporting bugs ) so I can't really tell. Anyway, the problem is, if I call rdmd from outside the folder in which the main source resides in, and main includes another file in that folder, I get an error. example: ...\projectfolder\src\main.d ...\projectfolder\src\test.d // main.d module main; import test.d; void main() { hello(); } // end main.d // test.d module test.d; import std.stdio; void hello() { writeln(Hello); } // end test.d // If I'm in a shell, and I do this, I get an error: ...\projectfolderrdmd src\main.d src\main.d(2): Error: module test is in file 'test.d' which cannot be read import path[0] = C:\D\dmd2\windows\bin\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin\..\..\src\druntime\import // but if I do this, it works: ...\projectfolder\srcrdmd main.d ...\projectfolder\srcHello world // also works ...\projectfolder\srcdmd main.d test.d Anyway, I want to be able to compile with rdmd from a different folder, is this a bug? or should I use a different tool? :-S *aahhh* Other info: OS: Windows rdmd build 20101220 dmd: 2.050
Re: Classes or stucts :: Newbie
On Sun, 19 Dec 2010 14:38:17 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. How do you define a need for scoped classes? I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. It looks perfectly reasonable for me to want to have first. Do you know why things which makes program act more deterministic are shunned from D? Does it really add so much to safety that it is worth reducing programmer's control? Second is irrelevant to types, if I want to speed up some code and can do it by placing things on stack rather than in heap -- what does it matter if it is class or struct or integer? We have alloca() anyway, so removing modifier won't save me from myself, just push me to more C-like code. Which kind of defeats the purpose of using D. The compiler can help, but it can't fix the problem any more that it can guarantee that a pointer to a local variable doesn't escape once you've passed it to another function. Absolutely. Yet we won't have library solution for pointers instead of language support (hopefully)? :) I think it all goes against being practical as an objective of the language. Safety is important but you don't achieve safety by means of making unsafe thing unconvenient and inefficient. If there is emplace() then there is no reason not to have scope storage class. At least looking from user's POV. I don't know how hard it is on the compiler. In _some_ circumstances, it can catch escaping pointers and references, but in the general case, it can't. In _general_ case there is no safety in D. With all low-level capabilities one can always defeat compiler. Removing intermediate-level safer (yet unsafe) capabilities arguabily gains nothing but frustration. I'm all for encouraging good practices, but this is different. -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On 12/20/10, Nick Voronin elfy...@gmail.com wrote: I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. There's still an alternative for the first part, scope(exit): import std.stdio; class A { ~this() { writeln(A.dtor); } void test() { writeln(test); } } void main() { A a = new A(); scope(exit) { clear(a); } a.test(); } test A.dtor A.dtor
Re: Classes or stucts :: Newbie
On Sunday 19 December 2010 16:50:34 Nick Voronin wrote: On Sun, 19 Dec 2010 14:38:17 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. How do you define a need for scoped classes? I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. It looks perfectly reasonable for me to want to have first. Do you know why things which makes program act more deterministic are shunned from D? Does it really add so much to safety that it is worth reducing programmer's control? Then use a struct. That's one of the reasons that they exist. And if you _really_ want to make sure that a class' destructor gets run, you can always use clear() (which is arguably an abomination in its own right). And if you use that in combination with scope(exit), then you get a class which is guaranteed to be destroyed when the function exits, and (assuming that clear() is fully implemented and actually zeroes out the vtable - which I don't think that it does yet), you won't be using garbage memory (though obviously it will still go boom - likely due to a segfault). Part of the whole point of separating classes and structs is to separate the issue of where they go - on the stack or on the heap. So, putting classes on the stack kind of negates the whole point of having both structs and classes in the first place. In _general_ case there is no safety in D. With all low-level capabilities one can always defeat compiler. Removing intermediate-level safer (yet unsafe) capabilities arguabily gains nothing but frustration. I'm all for encouraging good practices, but this is different. In the general case when using SafeD, there D _is_ safe. scoped classes are definitely not in SafeD. structs already are on the stack. If you want something on the stack, then use structs. And if you _really_ want a class on the stack for whatever reason (which I _really_ question), then there will be a library solution to the problem. By putting classes on the stack, you're pretty much ignoring the differences between structs and classes. - Jonathan M Davis
Re: rdmd bug?
On Mon, 20 Dec 2010 01:24:02 +0100 CrypticMetaphor crypticmetapho...@gmail.com wrote: Anyway, the problem is, if I call rdmd from outside the folder in which the main source resides in, and main includes another file in that folder, I get an error. // If I'm in a shell, and I do this, I get an error: ...\projectfolderrdmd src\main.d src\main.d(2): Error: module test is in file 'test.d' which cannot be read import path[0] = C:\D\dmd2\windows\bin\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin\..\..\src\druntime\import Anyway, I want to be able to compile with rdmd from a different folder, is this a bug? or should I use a different tool? :-S *aahhh* Add -Ifullpath_to_projectfolder\src. It's the way it works IMHO, if you import something it must be relative to search path or to current dir. There may be a better way (replace current dir with the dir where source is, but it will take away control), but this works. There is a bug though, I can't make it work with -Irelative_path_to_src. Looks like .deps contain paths relative to where rdmd was ran, while dmd interprets them as paths relative to where .deps file is. -- Nick Voronin elfy...@gmail.com
Re: rdmd bug?
Add -Ifullpath_to_projectfolder\src. It's the way it works IMHO, if you import something it must be relative to search path or to current dir. There may be a better way (replace current dir with the dir where source is, but it will take away control), but this works. There is a bug though, I can't make it work with -Irelative_path_to_src. Looks like .deps contain paths relative to where rdmd was ran, while dmd interprets them as paths relative to where .deps file is. I've tried -Ipath to src but this doesn't work either, but I've found a workaround. I start a batch file that goes to the correct directory and then executes rdmd with the argument(the absolute path) I pass to the batch file, this works :D Thanks for the help! So, should I report this as a bug?
Re: rdmd bug?
So, should I report this as a bug? What am i saying!? of course I should. It annoyed the hell outta me _ *goes to report*
Re: Classes or stucts :: Newbie
On Sun, 19 Dec 2010 17:26:20 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 16:50:34 Nick Voronin wrote: On Sun, 19 Dec 2010 14:38:17 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. How do you define a need for scoped classes? I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. It looks perfectly reasonable for me to want to have first. Do you know why things which makes program act more deterministic are shunned from D? Does it really add so much to safety that it is worth reducing programmer's control? Then use a struct. Here is where we diverge. Choosing struct vs class on criteria of their placement makes no sense to me. Difference in default placement hardly matters at all, you can perfectly put structs in heap or in static segment yet still maintain same properties. It's those properties which matter when I choose one or another, not where it will reside in particular part of program. That's one of the reasons that they exist. And if you _really_ want to make sure that a class' destructor gets run, you can always use clear() (which is arguably an abomination in its own right). This is what I don't understand. Fine. structs are meant for stack, class for heap. Conceptually, anyway. Still there will be ways to put class on stack and struct in heap. And there is(will be) clear(). Now I do see benefit of scope storage. It looks clean, it is supported by compiler meaning reasonable level of protection against misuse, it is extremely effective. What are benefits of _not having_ it? -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On Sunday 19 December 2010 18:13:54 Nick Voronin wrote: On Sun, 19 Dec 2010 17:26:20 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 16:50:34 Nick Voronin wrote: On Sun, 19 Dec 2010 14:38:17 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. How do you define a need for scoped classes? I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. It looks perfectly reasonable for me to want to have first. Do you know why things which makes program act more deterministic are shunned from D? Does it really add so much to safety that it is worth reducing programmer's control? Then use a struct. Here is where we diverge. Choosing struct vs class on criteria of their placement makes no sense to me. Difference in default placement hardly matters at all, you can perfectly put structs in heap or in static segment yet still maintain same properties. It's those properties which matter when I choose one or another, not where it will reside in particular part of program. That's one of the reasons that they exist. And if you _really_ want to make sure that a class' destructor gets run, you can always use clear() (which is arguably an abomination in its own right). This is what I don't understand. Fine. structs are meant for stack, class for heap. Conceptually, anyway. Still there will be ways to put class on stack and struct in heap. And there is(will be) clear(). Now I do see benefit of scope storage. It looks clean, it is supported by compiler meaning reasonable level of protection against misuse, it is extremely effective. What are benefits of _not having_ it? Except that the compiler _can't_ protect against misuse. That's one of the main reasons that it's going away as part of the language. Structs are intended to their lifetime be the same as their scope. The lifetime for classes, on the other hand, is essentially as long as the program is running (though the garbage collector can obviously collect them in cases where they aren't used anymore). By trying to force a reference type to have a scoped lifetime, you're going against how they work, and it's just asking for trouble. Yes, it _can_ be done, but no, it _can't_ be done safely. As I understand it, Andrei isn't even entirely happy that clear() exists. I believe that pretty much the only reason that it exists is because there are cases where classes hold resources and you want to make sure that they get released rather than waiting for the object to get destroyed at some indeterminate point in the future. But really, the garbage collected heap is supposed to be managed by the garbage collector. And with scope, you're trying to take something that's designed to live on the garbage collected heap and put it on the stack. You're taking something that is designed to be used in one type of storage and using it in another. It's going to cause problems. C++ has a number of issues pricely because it allows classes to live on both the stack and the heap. By separating types that live on the stack from those that live on the heap, you avoid those problems. And actually, the fact that structs can live in the heap in D can be problematic, as evidenced by the bugs relating to destructors for structs on the heap. Not only do their destructors not get run, it's questionable whether the language will _ever_ be such that the destructors of structs on the heap will be run. The result is that in many cases, structs should either be designed to be on the stack or on the heap. D was designed so that classes live on the heap, and that's the way it works. Putting them on the stack is going against how classes are intended to work, and it's asking for trouble. - Jonathan M Davis
Re: Classes or stucts :: Newbie
Jonathan M Davis: Whereas, I would argue that it's completely unnecessary. Recently even the Oracle Java VM allocates some class instances on the stack, when Escape Analysis finds it's safe to do so. And D lacks the very efficient GC of the JVM, so for D it's even more important to use the stack for some classes. Think about the pure tag of D2. D1 lacks the pure annotation, but an advanced D1 compiler may add some logic able to tell if a function is pure, and use this info for performance purposes. The problem here is that if you change the function a little your function may stop being pure and the optimization becomes impossible. The pure annotation of D2 is a contract between the programmer and the compiler. In the same way, even if a D compiler gains an automatic escape analysis like Java and a much more efficient GC, a way to annotate a class as scoped is useful still, because like pure it's a contract between the compiler and the programmer, it enforces that a class instance doesn't escape a scope (if you try to escape it, the good compiler in most cases gives an error. While in this case the JVM just doesn't allocate the object on the stack), this also means guaranteed performance and deallocation determinism. Another thing to keep in account is that we aren't talking just about the stack, but generally about in-place allocation. So if you have a class instance A, one of its fields may be another class instance B, that's scoped. Here B is allocated on the heap, because B is contained inside A, that is (generally) on the heap. Yet B is allocated in-place. Having a single heap allocation instead of two when you create an instance A is a significant performance gain (and I think Java doesn't perform this optimization yet). A well designed type system is then able to make all this safe. The compiler can help, but it can't fix the problem any more that it can guarantee that a pointer to a local variable doesn't escape once you've passed it to another function. In _some_ circumstances, it can catch escaping pointers and references, but in the general case, it can't. See also: http://en.wikipedia.org/wiki/Linear_types Stronger and more powerful type systems are possible (D has means to break any type system, but the programmer does this knowing what she or he is doing. And there are ways similar to @safe to statically disallow the means you may use to break this part of the type system). So, putting classes on the stack kind of negates the whole point of having both structs and classes in the first place. This is false, the definition of D class instance doesn't specify where the instance memory is allocated. In the general case when using SafeD, there D _is_ safe. scoped classes are definitely not in SafeD. SafeD is not safe. It allows integer overflows, memory overflows, etc. SafeD just disallows a certain (important) kind of memory bugs. This is why some people have asked to call it memory safe. If you take a look at coding standards that specify how to write high integrity software (MISRA-C, SPARK, Joint Strike Fighter Air Vehicle C++ Coding Standards, etc), you will see that they forbid ALL heap allocations, because stack allocations are more deterministic and more predictable, so they are safer. If you disallow recursion the max required size of the stack is even computable statically, avoiding stack overflows. - Nick Voronin: Safety is important but you don't achieve safety by means of making unsafe thing unconvenient and inefficient. I know that sounds a little weird, but in practice this is how some parts of D are designed :-) Yet, Walter has said many things that he doesn't like safety by convention. So I presume there is some contradiction here :-) A language like Cyclone has tried to make low-level operations in a very C-language safe, and it succeeds in this, but Cyclone is both slow, fussy, not handy, a failure. So by design D doesn't try to make low-level operation safe, it just add safe(r) hi-level operations. You are allowed to use the low-level means still, but in this case you are fully on your own, like in C. For a lot of time I have not appreciated much this basic design decision, but so far it has worked well enough, far better than Cyclone. Bye, bearophile
Re: Classes or stucts :: Newbie
On Sunday 19 December 2010 18:33:56 bearophile wrote: Jonathan M Davis: Whereas, I would argue that it's completely unnecessary. Recently even the Oracle Java VM allocates some class instances on the stack, when Escape Analysis finds it's safe to do so. And D lacks the very efficient GC of the JVM, so for D it's even more important to use the stack for some classes. Think about the pure tag of D2. D1 lacks the pure annotation, but an advanced D1 compiler may add some logic able to tell if a function is pure, and use this info for performance purposes. The problem here is that if you change the function a little your function may stop being pure and the optimization becomes impossible. The pure annotation of D2 is a contract between the programmer and the compiler. In the same way, even if a D compiler gains an automatic escape analysis like Java and a much more efficient GC, a way to annotate a class as scoped is useful still, because like pure it's a contract between the compiler and the programmer, it enforces that a class instance doesn't escape a scope (if you try to escape it, the good compiler in most cases gives an error. While in this case the JVM just doesn't allocate the object on the stack), this also means guaranteed performance and deallocation determinism. Another thing to keep in account is that we aren't talking just about the stack, but generally about in-place allocation. So if you have a class instance A, one of its fields may be another class instance B, that's scoped. Here B is allocated on the heap, because B is contained inside A, that is (generally) on the heap. Yet B is allocated in-place. Having a single heap allocation instead of two when you create an instance A is a significant performance gain (and I think Java doesn't perform this optimization yet). A well designed type system is then able to make all this safe. The compiler can help, but it can't fix the problem any more that it can guarantee that a pointer to a local variable doesn't escape once you've passed it to another function. In _some_ circumstances, it can catch escaping pointers and references, but in the general case, it can't. See also: http://en.wikipedia.org/wiki/Linear_types Stronger and more powerful type systems are possible (D has means to break any type system, but the programmer does this knowing what she or he is doing. And there are ways similar to @safe to statically disallow the means you may use to break this part of the type system). So, putting classes on the stack kind of negates the whole point of having both structs and classes in the first place. This is false, the definition of D class instance doesn't specify where the instance memory is allocated. In the general case when using SafeD, there D _is_ safe. scoped classes are definitely not in SafeD. SafeD is not safe. It allows integer overflows, memory overflows, etc. SafeD just disallows a certain (important) kind of memory bugs. This is why some people have asked to call it memory safe. The whole point of safe when talking about safe in D is memory saftey. And scoped classes are an issue of memory safety. They are _not_ safe with regards to memory. If the compiler can determine that a particular class object can be put on the stack and optimize it that way. Fine, but it's pretty rare that it can do that - essentially only in cases where you don't pass it to _anything_ except for pure functions (including calls to member functions). And if the compiler can do that, then it there's no need for the programmer to use scope explicitly. And no, a compiler _can't_ do pure optimizations on its own, generally-speaking, because that would require looking not only at the body of the function that's being called but at the function bodies of any functions that it calls. D is not designed in a way that the compiler even necessarily has _access_ to a function's body when compiling, and you can't generally look at a function's body when doing optimizations when calling that function. So, _some_ pure optimizations could be done, but most couldn't. This is not the case with scoped classes, because purity already gives you the information that you need. If you take a look at coding standards that specify how to write high integrity software (MISRA-C, SPARK, Joint Strike Fighter Air Vehicle C++ Coding Standards, etc), you will see that they forbid ALL heap allocations, because stack allocations are more deterministic and more predictable, so they are safer. If you disallow recursion the max required size of the stack is even computable statically, avoiding stack overflows. - Nick Voronin: Safety is important but you don't achieve safety by means of making unsafe thing unconvenient and inefficient. I know that sounds a little weird, but in practice this is how some parts of D are designed :-) Yet, Walter has said many things that he
Re: string comparison
Compared to the relatively snappy response other threads have been receiving I'm going to assume that nobody is interested in my inquiry. That's cool. Can anybody point me to an IRC chatroom for D noobs, and is there anywhere to post errata for the book?
Re: string comparison
On Saturday 18 December 2010 23:01:30 doubleagent wrote: Andrei's quick dictionary illustration [in his book, 'The D Programming Language'] doesn't seem to work. Code attached. On my computer, with d2-0.5.0, I got the following output while testing. andrei 0 andrei andrei 1 andrei Also, why doesn't 'splitter' show up on the site's documentation of std.string? And what advantage does 'splitter(strip(line))' offer over 'split(line)'? begin 644 dictionary.d M:6UP;W)T('-T9YS=1I;RP@W1D+G-TFEN9SL*G9O:60@;6%I;b...@i('L* M75I;G1;W1R:6YG72!D:6-T:6]N87)Y.R`O+R!V6VM=+!S;R!S=')I;FM M/G5I;G0*69OF5A8V@@*QI;F4[('-T9EN+F)Y3e...@i*2![@D)+R\@ M8G)E86L@V5N=5N8V4@:6YT;R!W;W)DPH)2\O($%D9!E86-H('=OF0@ M:6...@=AE('-E;G1E;F-E('1O('1H92!V;V-A8G5L87)Y@D)9F]R96%C:`H M=V]R9#L@W!L:71T97(HW1R:7`H;EN92DI*2![@D)6EF(AW;W)D(EN M(1I8W1I;VYAGDI(-O;G1I;G5E.R`O+R!N;W1H:6YG('1O(1O@D)6%U M=\@;F5W260@/2!D:6-T:6]N87)Y+FQE;F=T:#L*0D)9EC=EO;F%R5MW M;W)D72`](YE=TED.PH)0EWFET969L;b...@b)7-=5S(BP@;F5W260L('=O .F0I.PH)7T*7T*?0H` ` end Whatever you did to attach your code, it just comes up as gibberish to me. The errata page is here: http://erdani.com/tdpl/errata/index.php?title=Main_Page I have no idea what example you're looking at, or what the problem is. There are some examples in the book which are not 100% correct (most, if not all of them, are in the errata) and a few which don't work yet due to bugs in dmd or features which are not completely implemented yet (e.g. currently, you can only have one alias this per class/struct, but TDPL says that you can have multiple). The reason that std.string.splitter() does not show in the documentation is that its return type is auto, and there is currently a bug in ddoc that makes it so that auto functions don't end up in the generated documentation. Looking at the code, it pretty much just forwards to std.algorithm.splitter() using whitespace as its separator, so you can look at the documentation there if you'd like. Looking at the code for std.algorithm.splitter(), I'd say that the main advantage of splitter() over split() is that it generates a lazy range. So, if you don't want to process the whole range or if you don't want to use as much memory by having to duplicate the entire range that you passed to split()/splitter(), then you'd use splitter(). split() does have the advantage that it gives you an array, so you don't have to use std.array.array() if you want an array, like you'd have to do with splitter(). Overall, splitter() is more generic. split() is specific to std.string, and std.string has a version of splitte() presumably so that there is a version which matches up with split()'s behavior. - Jonathan M Davis
Re: string comparison
Check your client setting, everything is perfect on my side (Opera built-in news client).