Google Android
Is it possible to implement support for Google Android on the D?
Re: what are the most common bugs in your D apps?
davidl пишет: Actually I'm not sure about what kind of bugs my d apps usually have. But I notice that the harmonia project(I now make it uptodate) gets the problem of integer overlapping(actually I find it quite hard to detect and fix). What's your opinion and experience? I can not get used that copying of classes through the assign symbol (=) does not copy them as in C++
Re: new D2.0 + C++ language
Weed пишет: Hi! I want to offer the dialect of the language D2.0, suitable for use where are now used C/C++. Main goal of this is making language like D, but corresponding zero-overhead principle like C++: at least to something like this idea? )
Re: new D2.0 + C++ language
Piotrek пишет: Weed pisze: Weed пишет: Hi! I want to offer the dialect of the language D2.0, suitable for use where are now used C/C++. Main goal of this is making language like D, but corresponding zero-overhead principle like C++: at least to something like this idea? ) The idea could be ok but have you written a compiler or specification? My experience in the creation of the compilers is reduced to half-read book Compilers: Principles, Techniques, and Tools. It was easier to write the differences from D, as fully to specification - I hoped that receive point to some fundamental problems, but there seems all to be good (excluding holy war about GC, of course) Or is it wishful thinking like let's make the language that's productive to the skies while faster than asm? ;) No. ) I'm not suggesting anything new, it is suggested that all the time-tested things.
Re: new D2.0 + C++ language
Denis Koroskin пишет: On Thu, 19 Mar 2009 19:54:10 +0300, Weed resume...@mail.ru wrote: naryl пишет: Weed Wrote: naryl яПНяПНяПНяПНяПН: Weed Wrote: BCS яПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПН: Yes you can be very careful in keeping track of pointers (not practical) or use smart pointers and such (might end up costing more than GC) I am do not agree: GC overexpenditure CPU or memory. Typically, both. I wouldn't be so sure about CPU: http://shootout.alioth.debian.org/debian/benchmark.php?test=alllang=gdclang2=gppbox=1 You should not compare benchmarks - they depend on the quality of the testing code. Then find a way to prove that GC costs more CPU time than explicit memory management and/or reference counting. I suggest that reference counting for -debug. Yes, it slows down a bit. As invariant{}, in{}, out(){}, assert() Yeah, ref-count your objects in debug and let the memory leak in release! Not leak - that may be a reference to non-existent object. The design of invariant{} does not reveal all problems with the class in all cases which compiled to the release. So that they abandon invariant{}? Yes, this language is the same danger as the C++.
Re: new D2.0 + C++ language
Yigal Chripun пишет: what you suggest is C++ with better syntax, *NOT* a variant of D. for that look at: http://en.wikipedia.org/wiki/Significantly_Prettier_and_Easier_C%2B%2B_Syntax No! Only because of the value semantic returns used pointers instead of references for pointing to objects. C++ has the wrong semantics which D fixes. No sane person that moved to D would ever want to go back to C++ and its huge pile of issues. C++ implements only very basic mechanisms for OOP and even that is done poorly. Also, Your point of view about performance and GC is very much outdated and completely wrong. I will not go into GC implementation details since others did that already. All I'll say is that C++ will eventually get GC too. it was planned to be added in C++0x (the new standard that's planned for 2009) but was postponed because of lack of time and tight deadlines. to quote Wikipedia: qoute Transparent garbage collection C++0x will not feature transparent garbage collection directly. Instead, the C++0x standard will include features that will make it easier to implement garbage collection in C++. Only optional
Re: new D2.0 + C++ language
BCS пишет: Hello Weed, BCS ?: Reply to Weed, If you know the best way for language *without GC* guaranteeing the existence of an object without overhead - I have to listen! Never delete anything? One of the arguments for GC is that it might well have /less/ overhead than any other practical way of managing dynamic memory. Mmm When I say overhead I mean the cost of executions, and not cost of programming So do I. I figure unless it save me more times than it costs /all/ the users, run time cost trumps. This is a philosophical dispute. A good and frequently used code can be written once and then used 10 years in 50 applications in 1 installations. Here, the costs of programming may be less than the cost of end-user's time and hardware. Yes you can be very careful in keeping track of pointers (not practical) or use smart pointers and such (might end up costing more than GC) I am do not agree: GC overexpenditure CPU or memory. Typically, both. ditto naryl on CPU As for memory, unless the thing overspends into swap and does so very quickly (many pages per second) I don't think that matters. This is because most of the extra will not be part of the resident set so the OS will start paging it out to keep some free pages. This is basically free until you have the CPU or HDD locked hard at 100%. The other half is that the overhead of reference counting and/or the like will cost in memory (you have to store the count somewhere) and might also have bad effects regarding cache misses. Once again I repeat: forget about reference counting - it is only for the debug purposes. I think this addition should be switchable by compiler option. It did not included into the resulting code. Ref-counting needed for multithreaded programs, when there is a risk to get and use a reference to an object that another process has already been killed. This situation needs to be recognized and issued to a run-time error. This is addition to synchronization of threads, which is realized in D.
Re: new D2.0 + C++ language
Christopher Wright пишет: And regarding performance, eventually it will come a lot from a good usage of multiprocessing, The proposal will be able support multiprocessing - for it provided a references counting in the debug version of binaries. If you know the best way for language *without GC* guaranteeing the existence of an object without overhead - I have to listen! You cannot alter the reference count of an immutable variable. Why? Because it's immutable! Unless you're storing a dictionary of objects to reference counts somewhere, that is. Which would be hideously slow and a pain to use. Not that reference counting is fun. Precisely. I wrote the cost for that: 1 dereferencing + inc/dec of counter. It's more expensive than dereferencing. If your const object points to its reference count, then the reference count is also const, so you can't alter it. It is designed not so. There will be a hidden dereferencing: const ref Obj object - struct{ Obj* object;- Obj object; int counter; }; For all objects will be created such structs. this inside the object returns ptr to struct. Any appeal by reference to an object would cause such dereferencing. Creating reference to object in a code block will cause an increase in the counter. Destruction of reference will cause an automatic decrease in the counter. By the way, upon arrival into the try{} it will save values of reference counters for the correct exit if exception will be generated. So the best you can possibly do is one hashtable lookup for every time you alter the reference count for a non-mutable variable. That is a huge overhead, much more so than garbage collection.
Re: new D2.0 + C++ language
Christopher Wright пишет: Weed wrote: + Sometimes allocation and freeing of memory in an arbitrary unpredictable time unacceptable. (in game development or realtime software, for example. One hundred million times discussed about it there, I guess) So you are optimizing for the uncommon case? GC is an attempt of optimizing for the uncommon case )
Re: new D2.0 + C++ language
Simen Kjaeraas пишет: Weed resume...@mail.ru wrote: Simen Kjaeraas пишет: Weed resume...@mail.ru wrote: I think the point you're trying to make is that a GC is more memory intensive. + Sometimes allocation and freeing of memory in an arbitrary unpredictable time unacceptable. (in game development or realtime software, for example. One hundred million times discussed about it there, I guess) Then use the stub GC or disable the GC, then re-enable it when you have the time to run a sweep (yes, you can). Then a memory overrun If so, you have allocated a lot of things you shouldn't have, or otherwise would have the same problem using manual allocation. No, as far as I know that some pieces of language does not imply a manual release memory. (See below) A need language that does not contain a GC (or contains optional). Many C++ programmers do not affect the D only because of this. While GC in D is not optional, it can be stubbed out or disabled, Then some part of the language will stop working (dynamic arrays, and possibly delegates) Yes. So don't use those parts, It is not impossible without blocking at the compiler level (by CLI option) in the real world. or disable the GC and enable it when you have the time. Again, the memory will be overrun)
Re: new D2.0 + C++ language
Christopher Wright пишет: + Sometimes allocation and freeing of memory in an arbitrary unpredictable time unacceptable. (in game development or realtime software, for example. One hundred million times discussed about it there, I guess) So you are optimizing for the uncommon case? GC is an attempt of optimizing for the uncommon case ) I don't think so. Programmers have more important things to do than write memory management systems. My boss would not be happy if I produced an application that leaked memory at a prodigious rate, and he would not be happy if I spent much time at all on memory management. You should use language with GC in this case. With the application I develop at work, we cache some things. These would have to be reference counted or deleted and recomputed every time. Reference counting is a lot of tedious developer effort. Recomputing is rather expensive. Deleting requires tedious developer effort and determining ownership of everything. This costs time and solves no problems for the customers. I do not agree. I am quite easy to give tracking the creation and deletion of the objects on the stack and on the heap. I do not see problem there. Although there is an alternative - C++, but not D. And you do not need to do reference counting for all the objects in the program. Normally, objects in need not so much as objects do not need. (Therefore, I propose to extend the stack usage for storing and passing objects.) Unfortunately, not yet thought of another way to memory management And the best manual memory management that I am likely to write would not be faster than a good garbage collector. What sort of applications do you develop? games, images processing Have you used a garbage collector in a large application? I do not write really large applications
Re: new D2.0 + C++ language
BCS пишет: I figure unless it save me more times than it costs /all/ the users, run time cost trumps. This is a philosophical dispute. A good and frequently used code can be written once and then used 10 years in 50 applications in 1 installations. Here, the costs of programming may be less than the cost of end-user's time and hardware. You are agreeing with me. As for memory, unless the thing overspends into swap and does so very quickly (many pages per second) I don't think that matters. This is because most of the extra will not be part of the resident set so the OS will start paging it out to keep some free pages. This is basically free until you have the CPU or HDD locked hard at 100%. The other half is that the overhead of reference counting and/or the like will cost in memory (you have to store the count somewhere) and might also have bad effects regarding cache misses. Once again I repeat: forget about reference counting - it is only for the debug purposes. I think this addition should be switchable by compiler option. It did not included into the resulting code. Ref-counting needed for multithreaded programs, when there is a risk to get and use a reference to an object that another process has already been killed. This situation needs to be recognized and issued to a run-time error. As I understand the concept reference counting is a form of GC. In the proposed language is a way to learn mistake - deleting object in another thread that still have a reference. In other words, it is a way to provide proof that the reference refers to an object rather than the emptiness or garbage. It has nothing to do with threading. The point is to keep track of how many references, in any thread, there are to a dynamic resource and to free it when there are no more. Normally (as in if you are not doing things wrong) you never release/free/delete a reference counted resource so it doesn't even check if it is delete. Also because the count is attached to the referenced resource, it can't do that check because the count is deleted right along with it. For that concept (the only meaning of the term reference counting I known of) the idea of turning it off for non-debug builds is silly. Are you referring to something else?
Re: new D2.0 + C++ language
Christopher Wright пишет: Weed wrote: bearophile пишет: Weed: I want to offer the dialect of the language D2.0, suitable for use where are now used C/C++. Main goal of this is making language like D, but corresponding zero-overhead principle like C++: ... The code on this language almost as dangerous as a code on C++ - it is a necessary cost for increasing performance. No, thanks... And regarding performance, eventually it will come a lot from a good usage of multiprocessing, The proposal will be able support multiprocessing - for it provided a references counting in the debug version of binaries. If you know the best way for language *without GC* guaranteeing the existence of an object without overhead - I have to listen! You cannot alter the reference count of an immutable variable. Why?
Re: new D2.0 + C++ language
BCS пишет: Reply to Weed, If you know the best way for language *without GC* guaranteeing the existence of an object without overhead - I have to listen! Never delete anything? One of the arguments for GC is that it might well have /less/ overhead than any other practical way of managing dynamic memory. Mmm When I say overhead I mean the cost of executions, and not cost of programming Yes you can be very careful in keeping track of pointers (not practical) or use smart pointers and such (might end up costing more than GC) I am do not agree: GC overexpenditure CPU or memory. Typically, both. but neither is particularly nice.
Re: new D2.0 + C++ language
Christopher Wright пишет: And regarding performance, eventually it will come a lot from a good usage of multiprocessing, The proposal will be able support multiprocessing - for it provided a references counting in the debug version of binaries. If you know the best way for language *without GC* guaranteeing the existence of an object without overhead - I have to listen! You cannot alter the reference count of an immutable variable. Why? Because it's immutable! Unless you're storing a dictionary of objects to reference counts somewhere, that is. Which would be hideously slow and a pain to use. Not that reference counting is fun. Precisely. I wrote the cost for that: 1 dereferencing + inc/dec of counter. Ok, you can make reference counting is disabled by option. In any case, to release code that does not been included, it is only for -debug!
Re: new D2.0 + C++ language
naryl пишет: Weed Wrote: BCS яПНяПНяПНяПНяПН: Yes you can be very careful in keeping track of pointers (not practical) or use smart pointers and such (might end up costing more than GC) I am do not agree: GC overexpenditure CPU or memory. Typically, both. I wouldn't be so sure about CPU: http://shootout.alioth.debian.org/debian/benchmark.php?test=alllang=gdclang2=gppbox=1 You should not compare benchmarks - they depend on the quality of the testing code. But it is important to provide an opportunity to write a program efficiently.
Re: new D2.0 + C++ language
Robert Jacques пишет: *sigh* All memory allocation must make some kernel calls. D's GC makes fewer calls than a traditional malloc. Actually, modern malloc replacements imitate the way GCs allocate memory since it's a lot faster. (Intel's threading building blocks mentions this as part of its marketing and performance numbers, so modern mallocs are probably not that common) and 2) requires a global lock on access. Who? Traditional malloc requires taking global lock (and as point 1, often a kernel lock. Again, fixing this issue is one of Intel's TBB's marketing/performance points) Yes, there are several alternatives available now, but the same techniques work for enabling multi-threaded GCs. D's shared/local model should support thread local heaps, which would improve all of the above. It does not prevent pre-create the objects, or to reserve memory for them in advance. (This is what makes the GC, but a programmer would do it better) I think the point you're trying to make is that a GC is more memory intensive. + Sometimes allocation and freeing of memory in an arbitrary unpredictable time unacceptable. (in game development or realtime software, for example. One hundred million times discussed about it there, I guess) Actually, since fast modern mallocs and GC share the same underlying allocation techniques, they have about the same memory usage, etc. Of course, a traditional malloc with aggressive manual control can often return memory to the kernel in a timely manner, so a program's memory allocation better tracks actual usage as opposed to the maximum. Doing so is very performance intensive and GCs can return memory to the system too (Tango's does if I remember correctly). I think so: during the performance of malloc is controlled by the OS. And it is so does the optimization of memory allocation for programs. And OS has more facilities to do this. GC there will be just extra layer. A need language that does not contain a GC (or contains optional). Many C++ programmers do not affect the D only because of this.
Re: new D2.0 + C++ language
naryl пишет: Weed Wrote: naryl яПНяПНяПНяПНяПН: Weed Wrote: BCS яПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПН: Yes you can be very careful in keeping track of pointers (not practical) or use smart pointers and such (might end up costing more than GC) I am do not agree: GC overexpenditure CPU or memory. Typically, both. I wouldn't be so sure about CPU: http://shootout.alioth.debian.org/debian/benchmark.php?test=alllang=gdclang2=gppbox=1 You should not compare benchmarks - they depend on the quality of the testing code. Then find a way to prove that GC costs more CPU time than explicit memory management and/or reference counting. I suggest that reference counting for -debug. Yes, it slows down a bit. As invariant{}, in{}, out(){}, assert()
Re: new D2.0 + C++ language
Weed пишет: Hi! colorized example: http://paste.dprogramming.com/dpd6j5co
Re: new D2.0 + C++ language
Kagamin пишет: Kagamin Wrote: Weed Wrote: - Its does not contains garbage collection and - allows active using of a stack for the objects (as in C++) - Its uses syntax and a tree of objects taken from the D you just need to add syntactical support for it. Yes ...well, you already has it with structure constructors... Remember that we have already discussed this here several times, and came to the conclusion (?) that emulation of the value semantic by structs unreasonably difficult
new D2.0 + C++ language
Hi! I want to offer the dialect of the language D2.0, suitable for use where are now used C/C++. Main goal of this is making language like D, but corresponding zero-overhead principle like C++: - Its does not contains garbage collection and - allows active using of a stack for the objects (as in C++) - Its uses syntax and a tree of objects taken from the D The code on this language almost as dangerous as a code on C++ - it is a necessary cost for increasing performance. Compiler for that language does not exist! And it is unlikely that I will be able to do it. In any case, I want to discuss before thinking about compiler. I just give you an example of using, without a description of pure syntax because I do not propose anything new for those who remember C++ and D. Ask the questions! /* Demonstration of a new dialect of the D language It describes only what differs from D2.0 This language is compatible with C and (probably) D ABI, but not with C++. */ /* Structures and classes are completely similar, except structs are having controlled alignment and the lack of polymorphism. The structures are POD and fully compatible with the structures of the language C. */ struct S { int var0; int var1; int var2; // Structs constructors are entirely same as in a classes: this() { var1 = 5; } } interface I { void incr(); } // The structures is a POD. // They supports inheritance without a polymorphism and they support // interfaces too. struct SD : S, I { int var3; int var4; void incr() { ++var3; ++var4; } /* Structs constructors are similar to the class constructors. Calling base constructor super () is required. */ this() { super(); var4 = 8; } } class C, I { int var; void incr() { ++var; } /* Instead of overloading the operator = for classes and structures, there is present constructor, same as the copy constructor in C++ - in the parameters it accepts only object of the same type. This is differs from D and the need to ensure that copy constructor can change the source object (for example, to copy objects linked to the linked-list). Unlike the C++ constructor, it first makes a copy of the bitwise the original object, then an additional postblit, the same way as occurs in D2.0. This allows increase performance of copying than in C++. And about references: When compiling with -debug option compiler builds binary with the reference-counting. This approach is criticized by Walter Bright there: http://www.digitalmars.com/d/2.0/faq.html#reference-counting But, if the language is not have GC, reference-counting is a good way to make sure that the object which it references exists. The cost - an additional pointer dereferencing and checking the counter (and this is only when compiling with option -debug!). */ this( ref C src ) { var3 = src.var3; var4 = src.var4; } } class CD : C { real var2; void dumb_method() {}; } void func() { /* Classes to be addressed in the heap by pointer. * need to distinguish the classes in heap of classes in the stack. I.e., creating classes and structures takes place the same as creating them in the C++. */ CD cd_stack; // Creates class in a stack CD* cd_heap = new CD; // Creates class in a heap, new returns // pointer (same as in C++) C* c_heap = new C; C c_stack; // Copying of a objects (same as in C++) cd_stack = *cd_heap; *cd_heap = cd_stack; /* Copying of a pointers to the objects c_heap pointer points to the object cd_heap, with the object to which the previously pointed c_heap is not removed (as there is no GC and not used smartpointer template). This is memory leak! */ c_heap = cd_heap; /* Slicing demo: As a parent object is copied from derived class with additional fields and methods. The real var2 field data is not available in c_stack and not will be copied: */ c_stack = *cd_heap; /* Attempt to place an object of type C into the derived object of type CD. Field real var2 is not filled by C object. There field now contains garbage: */ cd_stack = c_stack; cd_stack.var2; // - garbage data }
Re: new D2.0 + C++ language
bearophile пишет: Weed: I want to offer the dialect of the language D2.0, suitable for use where are now used C/C++. Main goal of this is making language like D, but corresponding zero-overhead principle like C++: ... The code on this language almost as dangerous as a code on C++ - it is a necessary cost for increasing performance. No, thanks... And regarding performance, eventually it will come a lot from a good usage of multiprocessing, The proposal will be able support multiprocessing - for it provided a references counting in the debug version of binaries. If you know the best way for language *without GC* guaranteeing the existence of an object without overhead - I have to listen! that in real-world programs may need pure functions and immutable data. I do not see any problems with this That D2 has already, while C++ is less lucky.
Re: Old problem with performance
Christopher Wright пишет: Weed wrote: As a result, classes will be slow, or require more code to achieve speeds comparable to C++. That is actually a model of classes D harder than C++. Yes, C++ offers more unsafe optimizations than D. Straight to the point! I am choosing unsafe but fast code. Unsafe at so much on how much is unsafe any code on C++. I think the issue is closed. :)
Re: Old problem with performance
Don пишет: Weed wrote: Don пишет: That must mean that you inherit that class only to avoid duplicating code. And that is easily done with template mixins. It is possible that this polymorphism is not needed and should be prohibited for operations by value. The class is ready, why it should not be used and have to redo it? Can not think about changing when the class is ready - he could have enormous complexity and hierarchy. This is the fundamental tradeoff at the heart of the matter. In D, the choice of whether an object will use polymorphism or not is considered a fundamental design decision. This is awful! Much easier to give to the application programmer to decide how it will use the derived class somewhere. Such a division should be a basic principle of designing a complex program. Even in C++, all of your base classes should be abstract. Why? See, for example, http://www.artima.com/intv/modern.html It did not say how that all base classes should be abstract If you want to move between polymorphism and non-polymorphism in C++, it's a non-trivial refactoring. D gets significant benefits from this. Benefits: 1. Disappeared slicing 2. ? That's not what I had in mind at all. I don't think slicing is such a big deal in itself; it's just a symptom. What do you mean? Language complexity. We do not schoolgirls! :) Who is afraid of the complexity should use BASIC. C++ allows you to defer the decision, but it doesn't come for free. Clarify what you mean? (Generally speaking, statically typed languages do force you to make more decisions at design time). Notice that you have little gotchas in C++, such as the need to declare a virtual destructor on every struct you think you might someday use polymorphically. It sticks around, even if it never gets used. One of the nice things about a D struct, compared to a C++ struct, is that you *know* it's simple, it never has that kind of baggage. D does choose different trade-offs from C++. If it was always the same, it'd be the same language! There is no need to compare the structs from C++ and D. In fact, in C++ classes and structures are the same. Well, although the keywords are identical, there are two different varieties of C++ objects muddied together: PODs, and polymorphic types. You declare a type to be polymorphic by declaring a virtual function inside it. In D, you do it with the 'class' keyword. I like D's idea of POD structs + without them you can not ensure compatibility with C, but it is very important. Now we are talking about classes. In C++ classes with the same problems, such as what they do not have a common base class (Object in D). Passing classes by value is not a problem - is an advantage. Passing a polymorphic class by value rarely makes sense. You can't get (runtime) polymorphism unless you go through a pointer. Or reference (). Thus, even polymorphic class on stack can be used safely in C++. Same thing. You're either not using value semantics, or not using polymorphism. Not both at once. If you needed polymorphism you should use references or pointers, where necessary performance you use value semantics. C++ allows both options, D - no. As I said earlier, the presence of pointers is also an advantage, although they are dangerous and can lead to complex bugs. I don't think that is analagous. The issue is not primarily about with the 'danger' of passing classes by value. It's about clear separation of concepts. BTW, if you're concerned about performance, you'd do well to use compile-time polymorphism rather than run-time, when possible. D's metaprogramming support leaves C++ for dead. I think if there was a language with all the features as in D but with the model objects from C++, he would have won great popularity. Mainly it would have moved C++ developers who are satisfied with the model classes of C++ but not satisfied with the absence of other modern features: metaprogramming, contracts, delegates, closures etc. I think D will get adequate popularity once it has a good library situation. It only needs language changes inasfaras they are necessary for library design. What D better than Java or C#? I'm wasting my time here. I'll not make any further comments on this subject. Okay
Re: Old problem with performance
bearophile пишет: Weed: We do not schoolgirls! :) Who is afraid of the complexity should use BASIC. I like D1 mostly because it's quite less complex that C++, that's the first thing I ask to a new language like D. Complexity kills. I am cite myself: That is actually a model of classes D harder than C++. You probably don't want D, you want ATS: http://www.ats-lang.org/ There uses preprocessor. It is wrong.
Re: Old problem with performance
Daniel Keep пишет: Weed wrote: bearophile пишет: Weed: We do not schoolgirls! :) Who is afraid of the complexity should use BASIC. I like D1 mostly because it's quite less complex that C++, that's the first thing I ask to a new language like D. Complexity kills. I am cite myself: That is actually a model of classes D harder than C++. Man, wish I could have done that when writing my thesis... :) Sorry, this has already been discussed here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=84842
Re: Old problem with performance
Don пишет: Weed wrote: naryl пишет: --bb http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.Dartnum=83506 You should use a struct there! Your code does not show you doing anything that would even remotely suggest using a class is worthwhile. You're doing value operations on value types. That's what structs are for. Why? What if I have not substantiated the fact that c1 is a class I should use there a structure? Used in D a model of placement classes only in heap have a rule if you made the class and trying to pass it by value is somewhere in your code, there is a design error? Explains why the question is given in this form: I am received or wrote a classes. Is it right to overload the operator opAdd and use them? I think yes. But why not allow this operation at the same speed that allows C++? If you pass it by value you'll lose polymorphism. Debatable By the way, in my example the transfer class by value is not important(!), it is important to create a temporary class on the stack. Then we can pass a reference without problem (C++ allows this through the ) Sure, but you're not using polymorphism. There is no, but the same object can be used in other places, including the polymorphism That must mean that you inherit that class only to avoid duplicating code. And that is easily done with template mixins. It is possible that this polymorphism is not needed and should be prohibited for operations by value. The class is ready, why it should not be used and have to redo it? Can not think about changing when the class is ready - he could have enormous complexity and hierarchy. This is the fundamental tradeoff at the heart of the matter. In D, the choice of whether an object will use polymorphism or not is considered a fundamental design decision. This is awful! Much easier to give to the application programmer to decide how it will use the derived class somewhere. Such a division should be a basic principle of designing a complex program. D gets significant benefits from this. Benefits: 1. Disappeared slicing 2. ? C++ allows you to defer the decision, but it doesn't come for free. Clarify what you mean? (Generally speaking, statically typed languages do force you to make more decisions at design time). Notice that you have little gotchas in C++, such as the need to declare a virtual destructor on every struct you think you might someday use polymorphically. It sticks around, even if it never gets used. One of the nice things about a D struct, compared to a C++ struct, is that you *know* it's simple, it never has that kind of baggage. D does choose different trade-offs from C++. If it was always the same, it'd be the same language! There is no need to compare the structs from C++ and D. In fact, in C++ classes and structures are the same. I like D's idea of POD structs + without them you can not ensure compatibility with C, but it is very important. Now we are talking about classes. In C++ classes with the same problems, such as what they do not have a common base class (Object in D). Passing classes by value is not a problem - is an advantage. As I said earlier, the presence of pointers is also an advantage, although they are dangerous and can lead to complex bugs. BTW, if you're concerned about performance, you'd do well to use compile-time polymorphism rather than run-time, when possible. D's metaprogramming support leaves C++ for dead. I think if there was a language with all the features as in D but with the model objects from C++, he would have won great popularity. Mainly it would have moved C++ developers who are satisfied with the model classes of C++ but not satisfied with the absence of other modern features: metaprogramming, contracts, delegates, closures etc.
Re: Old problem with performance
Christopher Wright пишет: Kagamin wrote: Weed Wrote: But why not allow this operation at the same speed that allows C++? If you pass it by value you'll lose polymorphism. It is possible that this polymorphism is not needed and should be prohibited for operations by value. The class is ready, why it should not be used and have to redo it? Can not think about changing when the class is ready - he could have enormous complexity and hierarchy. It's probably already designed to be reference-type. I think, you'll have big troubles trying to change its semantic to value-type and effectively you'll have to redo it. In other words, it is not always easy to translate C++ to D. It's probably not worthwhile to translate any large codebase into another programming language, in most cases, and if you do, you will probably need to rewrite large portions of it anyway. As a result, classes will be slow, or require more code to achieve speeds comparable to C++. That is actually a model of classes D harder than C++.
Re: Old problem with performance
Don пишет: Weed wrote: Weed пишет: Bill Baxter пишет: On Sun, Feb 22, 2009 at 1:02 AM, Weed resume...@mail.ru wrote: Bill Baxter пишет: 2009/2/21 Weed resume...@mail.ru: Weed пишет: Bill Baxter пишет: Why don't you just show us the class in the way you would like to write it in C++, and we'll show you how to write it in D, or finally agree with you that it's not possible. But as long as you continue to be hand-wavy about common base classes we're at a bit of an impasse. So far everyone thinks D can do what you want it to do based on your vague descriptions. As I said, you can write everything using goto and if. ...But why you do not like the original example of this thread? Please post again. I don't seem to recall any detailed example. --bb http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.Dartnum=83506 You should use a struct there! Your code does not show you doing anything that would even remotely suggest using a class is worthwhile. You're doing value operations on value types. That's what structs are for. Why? What if I have not substantiated the fact that c1 is a class I should use there a structure? Used in D a model of placement classes only in heap have a rule if you made the class and trying to pass it by value is somewhere in your code, there is a design error? Explains why the question is given in this form: I am received or wrote a classes. Is it right to overload the operator opAdd and use them? I think yes. But why not allow this operation at the same speed that allows C++? Actually, in D, it's really difficult to give a class value semantics. If a, b are members of some class, consider (1) a = a + b; (2) a += b; It is nearly impossible to efficiently make both of these have the same effect!! You can only do it with either copy-on-write, ie, even case (2) always allocates; or by using a proxy class. This is something which I consider to be a serious problem. Much more serious than the speed issue. We already talked about this idea: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81432 (see text It is possible to think up other example where there is no overload:)
Re: Old problem with performance
Don пишет: That must mean that you inherit that class only to avoid duplicating code. And that is easily done with template mixins. It is possible that this polymorphism is not needed and should be prohibited for operations by value. The class is ready, why it should not be used and have to redo it? Can not think about changing when the class is ready - he could have enormous complexity and hierarchy. This is the fundamental tradeoff at the heart of the matter. In D, the choice of whether an object will use polymorphism or not is considered a fundamental design decision. This is awful! Much easier to give to the application programmer to decide how it will use the derived class somewhere. Such a division should be a basic principle of designing a complex program. Even in C++, all of your base classes should be abstract. Why? If you want to move between polymorphism and non-polymorphism in C++, it's a non-trivial refactoring. D gets significant benefits from this. Benefits: 1. Disappeared slicing 2. ? That's not what I had in mind at all. I don't think slicing is such a big deal in itself; it's just a symptom. What do you mean? C++ allows you to defer the decision, but it doesn't come for free. Clarify what you mean? (Generally speaking, statically typed languages do force you to make more decisions at design time). Notice that you have little gotchas in C++, such as the need to declare a virtual destructor on every struct you think you might someday use polymorphically. It sticks around, even if it never gets used. One of the nice things about a D struct, compared to a C++ struct, is that you *know* it's simple, it never has that kind of baggage. D does choose different trade-offs from C++. If it was always the same, it'd be the same language! There is no need to compare the structs from C++ and D. In fact, in C++ classes and structures are the same. Well, although the keywords are identical, there are two different varieties of C++ objects muddied together: PODs, and polymorphic types. You declare a type to be polymorphic by declaring a virtual function inside it. In D, you do it with the 'class' keyword. I like D's idea of POD structs + without them you can not ensure compatibility with C, but it is very important. Now we are talking about classes. In C++ classes with the same problems, such as what they do not have a common base class (Object in D). Passing classes by value is not a problem - is an advantage. Passing a polymorphic class by value rarely makes sense. You can't get (runtime) polymorphism unless you go through a pointer. Or reference (). Thus, even polymorphic class on stack can be used safely in C++. As I said earlier, the presence of pointers is also an advantage, although they are dangerous and can lead to complex bugs. I don't think that is analagous. The issue is not primarily about with the 'danger' of passing classes by value. It's about clear separation of concepts. BTW, if you're concerned about performance, you'd do well to use compile-time polymorphism rather than run-time, when possible. D's metaprogramming support leaves C++ for dead. I think if there was a language with all the features as in D but with the model objects from C++, he would have won great popularity. Mainly it would have moved C++ developers who are satisfied with the model classes of C++ but not satisfied with the absence of other modern features: metaprogramming, contracts, delegates, closures etc. I think D will get adequate popularity once it has a good library situation. It only needs language changes inasfaras they are necessary for library design. What D better than Java or C#?
Re: Old problem with performance
Weed пишет: Bill Baxter пишет: On Sun, Feb 22, 2009 at 1:02 AM, Weed resume...@mail.ru wrote: Bill Baxter пишет: 2009/2/21 Weed resume...@mail.ru: Weed пишет: Bill Baxter пишет: Why don't you just show us the class in the way you would like to write it in C++, and we'll show you how to write it in D, or finally agree with you that it's not possible. But as long as you continue to be hand-wavy about common base classes we're at a bit of an impasse. So far everyone thinks D can do what you want it to do based on your vague descriptions. As I said, you can write everything using goto and if. ...But why you do not like the original example of this thread? Please post again. I don't seem to recall any detailed example. --bb http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.Dartnum=83506 You should use a struct there! Your code does not show you doing anything that would even remotely suggest using a class is worthwhile. You're doing value operations on value types. That's what structs are for. Why? What if I have not substantiated the fact that c1 is a class I should use there a structure? Used in D a model of placement classes only in heap have a rule if you made the class and trying to pass it by value is somewhere in your code, there is a design error? Explains why the question is given in this form: I am received or wrote a classes. Is it right to overload the operator opAdd and use them? I think yes. But why not allow this operation at the same speed that allows C++?
Re: Old problem with performance
naryl пишет: --bb http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.Dartnum=83506 You should use a struct there! Your code does not show you doing anything that would even remotely suggest using a class is worthwhile. You're doing value operations on value types. That's what structs are for. Why? What if I have not substantiated the fact that c1 is a class I should use there a structure? Used in D a model of placement classes only in heap have a rule if you made the class and trying to pass it by value is somewhere in your code, there is a design error? Explains why the question is given in this form: I am received or wrote a classes. Is it right to overload the operator opAdd and use them? I think yes. But why not allow this operation at the same speed that allows C++? If you pass it by value you'll lose polymorphism. Debatable By the way, in my example the transfer class by value is not important(!), it is important to create a temporary class on the stack. Then we can pass a reference without problem (C++ allows this through the ) That must mean that you inherit that class only to avoid duplicating code. And that is easily done with template mixins. It is possible that this polymorphism is not needed and should be prohibited for operations by value. The class is ready, why it should not be used and have to redo it? Can not think about changing when the class is ready - he could have enormous complexity and hierarchy.
Re: Old problem with performance
Bill Baxter пишет: On Sun, Feb 22, 2009 at 1:02 AM, Weed resume...@mail.ru wrote: Bill Baxter пишет: 2009/2/21 Weed resume...@mail.ru: Weed пишет: Bill Baxter пишет: Why don't you just show us the class in the way you would like to write it in C++, and we'll show you how to write it in D, or finally agree with you that it's not possible. But as long as you continue to be hand-wavy about common base classes we're at a bit of an impasse. So far everyone thinks D can do what you want it to do based on your vague descriptions. As I said, you can write everything using goto and if. ...But why you do not like the original example of this thread? Please post again. I don't seem to recall any detailed example. --bb http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.Dartnum=83506 You should use a struct there! Your code does not show you doing anything that would even remotely suggest using a class is worthwhile. You're doing value operations on value types. That's what structs are for. Why? What if I have not substantiated the fact that c1 is a class I should use there a structure? Used in D a model of placement classes only in heap have a rule if you made the class and trying to pass it by value is somewhere in your code, there is a design error?
Re: Old problem with performance
Bill Baxter пишет: Why don't you just show us the class in the way you would like to write it in C++, and we'll show you how to write it in D, or finally agree with you that it's not possible. But as long as you continue to be hand-wavy about common base classes we're at a bit of an impasse. So far everyone thinks D can do what you want it to do based on your vague descriptions. Yes, it's a good idea
Re: Old problem with performance
Weed пишет: Bill Baxter пишет: Why don't you just show us the class in the way you would like to write it in C++, and we'll show you how to write it in D, or finally agree with you that it's not possible. But as long as you continue to be hand-wavy about common base classes we're at a bit of an impasse. So far everyone thinks D can do what you want it to do based on your vague descriptions. As I said, you can write everything using goto and if. ...But why you do not like the original example of this thread? Yes, it's a good idea
Re: Old problem with performance
Bill Baxter пишет: 2009/2/21 Weed resume...@mail.ru: Weed пишет: Bill Baxter пишет: Why don't you just show us the class in the way you would like to write it in C++, and we'll show you how to write it in D, or finally agree with you that it's not possible. But as long as you continue to be hand-wavy about common base classes we're at a bit of an impasse. So far everyone thinks D can do what you want it to do based on your vague descriptions. As I said, you can write everything using goto and if. ...But why you do not like the original example of this thread? Please post again. I don't seem to recall any detailed example. --bb http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.Dartnum=83506
Re: Old problem with performance
Christopher Wright пишет: Weed wrote: Kagamin пишет: Weed Wrote: Will the language change? Hmm... You already has Walter's answer. He's the boss. I want a more specific answer (yes or no) if possible... It will not. If you come up with some really awesome use case, then it could, but nobody has yet, and the issue comes up every few months. Good (I think) use cases have been in this thread
Re: Old problem with performance
Don пишет: Weed wrote: Christopher Wright пишет: Weed wrote: Kagamin пишет: Weed Wrote: Will the language change? Hmm... You already has Walter's answer. He's the boss. I want a more specific answer (yes or no) if possible... It will not. If you come up with some really awesome use case, then it could, but nobody has yet, and the issue comes up every few months. Good (I think) use cases have been in this thread They have not. The examples have been incomplete. You've provided use cases involving classes, but haven't given _any_ details about the contents of those classes. It's possible that you have indeed found use cases, but you haven't actually shown them here. I do not understand the claims. For example, any class that implements the mathematical object (matrix, vector, number, etc.) is suitable for example. I think it is obvious. Yes, the discussion in this thread showed that almost always possible for each case to find a different approach, using additives and other scary code. But what if these perversions flaw somewhere in the idea of a reference-only type? I understand people who are against the changes of language, as they would at least explore these changes. I myself belong to those people, I do not like changes associated with cosmetic amenities, breaking the old-established solution for years. I also understand the people who came from the languages Java and C#, which is not familiar with the semantics of the class value. But just such a case, when the inertia hinders the development of language and prevents them winning at least a substantial number of positions. (Namely: the replacement of old C++. Yes, I believe, without C++ replacement functionality D will not be needed.) I think the problem is real and requires action. Not sure it will be a value semantic. Maybe we come up with something entirely new? I do not know. But the problem is that one must at least acknowledge it and not come off the common phrases that your use cases are not serious etc.
Re: Old problem with performance
Don пишет: Weed wrote: Don пишет: Weed wrote: Christopher Wright пишет: Weed wrote: Kagamin пишет: Weed Wrote: Will the language change? Hmm... You already has Walter's answer. He's the boss. I want a more specific answer (yes or no) if possible... It will not. If you come up with some really awesome use case, then it could, but nobody has yet, and the issue comes up every few months. Good (I think) use cases have been in this thread They have not. The examples have been incomplete. You've provided use cases involving classes, but haven't given _any_ details about the contents of those classes. It's possible that you have indeed found use cases, but you haven't actually shown them here. I do not understand the claims. For example, any class that implements the mathematical object (matrix, vector, number, etc.) is suitable for example. I think it is obvious. Absolutely not! Those cases involve no polymorphism! No virtual function calls. I do not understand why. They are not principally to demonstrate the problem, but certainly should be able to use them. It is possible that in the real code these opportunities are not used, but tomorrow they may need it, and a day after we again decide to remove them. This should not affect the syntax or the choice between the structures+mixins and classes, and so on! Yes, the discussion in this thread showed that almost always possible for each case to find a different approach, using additives and other scary code. But what if these perversions flaw somewhere in the idea of a reference-only type? I understand people who are against the changes of language, as they would at least explore these changes. I myself belong to those people, I do not like changes associated with cosmetic amenities, breaking the old-established solution for years. I don't think the resistance comes from intertia and committment to the long-established solution. There's plenty of C++ programmers here (including myself). All your opinion. I proceed from the assumption that the programmer should be lazy. :) This positively affects the quality of the code and its reuse I also understand the people who came from the languages Java and C#, which is not familiar with the semantics of the class value. But just such a case, when the inertia hinders the development of language and prevents them winning at least a substantial number of positions. (Namely: the replacement of old C++. Yes, I believe, without C++ replacement functionality D will not be needed.) I think the problem is real and requires action. Not sure it will be a value semantic. Maybe we come up with something entirely new? I do not know. But the problem is that one must at least acknowledge it and not come off the common phrases that your use cases are not serious etc. You really MUST start from a solid use case. I'm genuinely surprised that you've had so much trouble coming up with one; it suggests to me that you're not looking at the right problem. I design a future project. I can not spend time on his coding in advance knowing that the problem about which we speak will not allow me to achieve the desired properties of the finished product. Thus, one can expect from me detailed use cases from real life. Yes, probably each issue I will be able to circumvent by using tricks, repeatedly described here. But at what cost? There will be an unjustified waste of time, the developer and a serious increase of complexity of the program (compared to C++)
Re: Old problem with performance
Kagamin пишет: Weed Wrote: Good (I think) use cases have been in this thread They may be good, but they don't show what can be done in C++ and can't be done in D. You were advised to use structs for value semantic. We are beginning to repeat itself. Okay. :) On D you may write anything. Even without cycles! With only if and goto keywords. The question of the costs of such a code. :) An example is unnecessarily complex code here: http://www.dsource.org/projects/openmeshd/browser/trunk/LinAlg/linalg/MatrixT.d See line 227, template MultReturnType(ArgT) { This template is necessary to receive by value a structures containing the vectors and matrices as mathematical operations results. Receiving the vectors and matrices by value in structures needed to increase performance. Try to add here another 3 or 4 types of the returned object to this template? In C++ vector, matrix, and all other possible objects would have been the class derived from common base class and this problem does not occur.
Re: Old problem with performance
Kagamin пишет: Weed Wrote: Good (I think) use cases have been in this thread They may be good, but they don't show what can be done in C++ and can't be done in D. You were advised to use structs for value semantic. We are beginning to repeat itself. Okay. :) On D you may write anything. Even without cycles! With only if and goto keywords. The question of the costs of such a code. :) An example is unnecessarily complex code here: http://www.dsource.org/projects/openmeshd/browser/trunk/LinAlg/linalg/MatrixT.d See line 227, template MultReturnType(ArgT) { This template is necessary to receive by value a structures containing the vectors and matrices as mathematical operations results. Receiving the vectors and matrices by value in structures needed to increase performance. Try to add here another 3 or 4 types of the returned object to this template? In C++ vector, matrix, and all other possible objects would have been the class derived from common base class and this problem does not occur.
Re: Old problem with performance
What is the result of the discussion? Will the language change? Not once, could in 6-12 months?.. For me, the answer to that question was tantamount to answering the question whether or not to use D for new projects? Weed пишет: (Has started here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81359) To me still does not give rest performance of classes (in comparison with C++ or with D structs) I still think that it is a serious problem. Colleagues from our national D forum have asked to show it and I have written simple examples on D. I want to share with you too them. On my computer the code with structure (i.e. object by value) runs in 6 times faster than a code with a class: $ time ./struct real0m8.515s user0m7.796s sys 0m0.016s $ time ./class real0m52.185s user0m40.543s sys 0m0.076s [...]
Re: Old problem with performance
Kagamin пишет: Weed Wrote: Will the language change? Hmm... You already has Walter's answer. He's the boss. I want a more specific answer (yes or no) if possible...
Re: Old problem with performance
Michel Fortin пишет: On 2009-02-09 07:00:56 -0500, Weed resume...@mail.ru said: No. By forbiding the cases that leads to slicing, like returning a polymorphic object by value. Let's think, can there are other ways to solve problem? Here, for example my reasons: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81958 I'm not sure I'm getting what you mean in that post. It seems like you want the ability to copy classes, and thus pass them by value, but only when there would be no type conversion. Yes, this is the easiest way that came to my head I'm not getting where this can be useful though: by forcing your classes to be of a specific type, with no derived types allowed, you're losing polymorphism. Yes The only advantage you have is that your type can be derived from another so you can reuse some of its implementation. And still able to pass class instance through a stack! And I do not propose to remove the traditional class in the heap There are other ways to acheive that in D however (mixins come to mind).
Re: Old problem with performance
Christopher Wright пишет: Weed wrote: And if I need some different such combinations? For each it is necessary to write such 8-10 lines? This is terrible! You need to add those lines for every method you need virtual dispatch with for your value type. It's an overhead of three lines per method, two for the interface (declaration and member), and one extra line where you create the struct. If you're reasonable, your struct constructor will create a default instance. So, it's not that great an overhead. Do not be surprised that so many continue to write in C++! :)
Re: Old problem with performance
Daniel Keep пишет: Weed wrote: [snip] If I had to take a guess, I'd say that it's six times slower because you're performing 100 million allocations. You aren't benchmarking class/struct overhead, you're benchmarking the overhead of doing 100 million allocations. You're comparing apples and heffalumps. Yes, but problem is that D does not leave way to create a class instance without allocation
Re: Old problem with performance
Weed пишет: Daniel Keep пишет: Weed wrote: [snip] If I had to take a guess, I'd say that it's six times slower because you're performing 100 million allocations. You aren't benchmarking class/struct overhead, you're benchmarking the overhead of doing 100 million allocations. You're comparing apples and heffalumps. Yes, but problem is that D does not leave way to create a class instance without allocation I should explain that I compare not only structs and classes in D but also classes in C++, there classes work as fast as well as structures in case of usage of overload of operators.
Re: Old problem with performance
Denis Koroskin пишет: Your C objects have value semantics. For value semantics you should use value types. At present in D is not contain support of value types for objects. (I consider that it is necessary) Alternatively you may want to use the following trick (I used it for lazy string concatenation in C+): [skip] Apparently, it doesn't work at the moment because ctor can't be a template :( Is there an enhancement request in bugzilla? It prevents this pattern from working. + it is difficult and also it will be even more difficult if it will be necessary to make support for the construction like: space_ship_1.calculatePathTo(Moon).getCheckpoint(3).getCoords; In this example we create a temporary class path, create temporary class checkpoint and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary. (from http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81432)
Re: Old problem with performance
Denis Koroskin пишет: [skip] Apparently, it doesn't work at the moment because ctor can't be a template :( Is there an enhancement request in bugzilla? It prevents this pattern from working. + it is difficult and also it will be even more difficult if it will be necessary to make support for the construction like: space_ship_1.calculatePathTo(Moon).getCheckpoint(3).getCoords; In this example we create a temporary class path, create temporary class checkpoint and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary. (from http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81432) I believe you should stick with structs for that. Let's assume, polymorphism is necessary to these objects
Re: Old problem with performance
naryl пишет: Weed Wrote: Denis Koroskin яПНяПНяПНяПНяПН: And here are results (best/average of 3 runs): DMD2.023 - 12.492/12.576 ms (-O -inline) DMC8.42n - 13.941/14.131 ms (-O -inline) Try to return from value() a class instance In this case both C++ and D performance drops almost tenfold. Hmmm. Can you show code?
Re: Old problem with performance
Christopher Wright пишет: Weed wrote: (Has started here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81359) To me still does not give rest performance of classes (in comparison with C++ or with D structs) On my system, your struct example averaged 0.36 seconds, and your class example averaged 0.38 seconds. Your benchmark is flawed in three ways: 1. You're timing allocations in the class example. Use opAddAssign to avoid it. Earlier I proved that it is impossible. For example here in such expression: == space_ship_1.calculatePathTo(Moon).getCheckpoint(3).getCoords; In this example we create a temporary class path, create temporary class checkpoint and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary. == 2. You're passing large structs in the struct example. Use ref to avoid it. 3. c1 is never assigned to, so c1 + c1 + c1 is moved outside the loop. The assignment has no side effect, so the loop is optimized out. Replace c1 + c1 + c1 with c1 + c2 + c1, for instance, and the struct example takes 20 seconds rather than 0.36. Really, it has a little affected. Thanks!
Re: Old problem with performance
Rainer Deyke пишет: Michel Fortin wrote: Polymorphism doesn't work very well while passing objects by value, even in C++. This is called the slicing problem. I have heard about the slicing problem. I know what it is. But in all my years of using C++ as my primary language, I have never actually encountered it. I don't believe it actually exists. I am absolutely agree with you. Besides, slicing it is possible to detect in a compile time in many cases. It can be too grandiloquent sounds, but in D us have deprived of one degree of freedom - freedom to use a stack.
Re: Old problem with performance
Walter Bright пишет: Frits van Bommel wrote: Which helps (a bit) with the two instances allocated in main(), but is rather unhelpful with the 100_000_000 allocated in opAdd() (they're returned)... The use of classes in this example is like using a screwdriver as a hammer. It'll work in a pinch, but a hammer works a lot better. If you're allocating 100_000_000 classes in a tight loop, some refactoring looks to be in order. In particular, classes are *meant* to be used as reference types, but the program is trying to treat them as value types. But without such types the bulky code turns out (examples in this branch already presented) Virtual functions are orthogonal to what value types are - a continuing problem C++ programs have is conflating value types with reference types. The compiler cannot optimize such code? No We have virtual machine for fast allocations of memory at such heavy using of objects? No Perfectly - it is necessary to leave this question to the programmer: the class will be stored in a stack or in a heap is better will solve the programmer instead of the compiler. It is impossible to lose to an C++ in what.
Re: Old problem with performance
Radu пишет: While nor so orthodox, this improves the situation a bit: template stackAllocator(T) { new(size_t size, void* sp = alloca(T.classinfo.init.length)) { return sp; } delete(void* ptr) { } } final class C { int i; real[5] unused; // to prevent returning this object in registers C opAdd(C src) { auto ret = new C; ret.i = i + src.i; return ret; } mixin stackAllocator!(C); } Radu If the used object it is impossible to change? It is written by other person, for example? And, we all will take for a rule in each object using overload to add stackAllocator?
Re: Old problem with performance
Adam D. Ruppe пишет: On Mon, Feb 09, 2009 at 09:59:50AM +0700, Weed wrote: Perfectly - it is necessary to leave this question to the programmer: the class will be stored in a stack or in a heap is better will solve the programmer instead of the compiler. scope class does just that. No, D do not allow return scope value. You can also put a custom allocator in your class and do whatever you want. Often you add custom allocator in the classes who uses overload? You begin to do it after that talk? :)
Re: Old problem with performance
Christopher Wright пишет: Weed wrote: Christopher Wright пишет: Weed wrote: (Has started here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81359) To me still does not give rest performance of classes (in comparison with C++ or with D structs) On my system, your struct example averaged 0.36 seconds, and your class example averaged 0.38 seconds. Your benchmark is flawed in three ways: 1. You're timing allocations in the class example. Use opAddAssign to avoid it. Earlier I proved that it is impossible. For example here in such expression: == space_ship_1.calculatePathTo(Moon).getCheckpoint(3).getCoords; In this example we create a temporary class path, create temporary class checkpoint and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary. == In that example, you can use structs instead of classes. Your response to that is that structs do not participate in polymorphism. There was a suggestion elsewhere like this: interface IPathResolver { Checkpoint getCheckpoint(Path* path, int i); } struct Path { char[] path; // any other info you need IPathResolver resolver; Checkpoint getCheckpoint(int value) { return resolver.getCheckpoint(this, value); } } This way, you only allocate once for each type you need, you have polymorphism, and you can put stuff on the stack for quick access. And if I need some different such combinations? For each it is necessary to write such 8-10 lines? This is terrible!
Re: Old problem with performance
Michel Fortin пишет: On 2009-02-08 09:30:08 -0500, Weed resume...@mail.ru said: Let's assume, polymorphism is necessary to these objects Polymorphism doesn't work very well while passing objects by value, even in C++. This is called the slicing problem. http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c I think D does a good job at avoiding that problem. By performance loss :(
Re: Old problem with performance
naryl пишет: Weed Wrote: naryl яПНяПНяПНяПНяПН: Weed Wrote: Denis Koroskin яПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПНяПН: And here are results (best/average of 3 runs): DMD2.023 - 12.492/12.576 ms (-O -inline) DMC8.42n - 13.941/14.131 ms (-O -inline) Try to return from value() a class instance In this case both C++ and D performance drops almost tenfold. May be performance do not fall, it become equally high?
Old problem with performance
(Has started here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81359) To me still does not give rest performance of classes (in comparison with C++ or with D structs) I still think that it is a serious problem. Colleagues from our national D forum have asked to show it and I have written simple examples on D. I want to share with you too them. On my computer the code with structure (i.e. object by value) runs in 6 times faster than a code with a class: $ time ./struct real0m8.515s user0m7.796s sys 0m0.016s $ time ./class real0m52.185s user0m40.543s sys 0m0.076s The code on C++ is also approximately in 6 times faster a code with classes on D. (I do not give an example on C++ because classes on C++ work just as structures in D.) I think with it it is necessary to do something. Examples code: // struct C { int i; real[5] unused; // to prevent returning this object in registers C opAdd( C src ) { C ret; ret.i = i + src.i; return ret; } } int main() { C c1; C c2; // initialise i by random value to prevent compile-time calculation c1.i = cast(int)c1; c2.i = 0; for(int i = 0; i 50_000_000; ++i) c2 = c1 + c1 + c1; return c2.i; } // class C { int i; real[5] unused; // to prevent returning this object in registers C opAdd( C src ) { auto ret = new C; ret.i = i + src.i; return ret; } } int main() { auto c1 = new C; auto c2 = new C; // initialise i by random value to prevent compile-time calculation c1.i = cast(int)c1; c2.i = 0; for(int i = 0; i 50_000_000; ++i) c2 = c1 + c1 + c1; return c2.i; } //
switch off GC?
It is possible to disable GC? That it has not been included in result binary for an increasing performance of ref operations and reduction of the size of the binary I have not found the answer in google.
Re: new principle of division between structures and classes
Denis Koroskin пишет: On Sun, 11 Jan 2009 05:04:11 +0300, Weed resume...@mail.ru wrote: Bill Baxter пишет: 2009/1/11 Weed resume...@mail.ru: Bill Baxter пишет: But since classes can be polymorphic, value copying gets you into slicing problems. That's why value copying is disabled to begin with. So disabling value copies is a good thing. It is not always a good thing. Yeh, I just mean there is some merit in disabling value copies. But I don't rule out the possibility that there may be an even better way that banning them altogether. I propose to prohibit only the copying by value of the base type to derivative type Ok, this is key. How do you propose to do this? In general it requires a runtime check, I think. And I think you need to say that you prohibit copying unless typeA==typeB exactly. If you allow copying either way between base and derived you are asking for trouble. But still given Base x = get_one(); Base y = get_another(); *x = *y; // presumed value copy syntax you have no way in general to know that x and y are really both a Base at compile time. So you must have a run-time check there. Perhaps it could be omitted for -release builds, though. It can lead to a difficult and non-reproduceable errors than old C++-style splitting. It is possible to try to prohibit assignment of the dereferenced pointers? Simply to prohibit assignment too it is possible, essentially it changes nothing. Err.. I don't get what you say. The *x = *y is just one of the possible syntaxes, nothing else. (I have incorrectly expressed) If dereferencing was not used in lvalue or rvalue and is both a classes by value it is possible to assignment, except cases when the base type to the derivative is assigned. Example: class C {} class C2 : C {} C c(); C2 c2(); C* c_p = c; C2* c2_p = c2; c = c2; // ok c2 = c; // err *c_p = *c2_p; // err *c2_p = *c_p; // err c2 = *c2_p; // err and: c = c2 + *c2_p; // ok And that's also the problem with putting scope'd things inside another class or an array. Since they don't have value semantics, Yes, this is what I mean So assuming you had this, the important question is what would you do with it? The most difficult. My arguments: 1. Problem of a choice of correct type for the object. A mathematical matrix - a classical example. A class it should be or structure? My offer without serious consequences allows to move solution of this problem from a design stage to a programming stage - is it will be simple by replacement keyword class to struct. Having the same syntax for both classes and struct is a nice goal, I agree. But it should be taken as a different issue and solved separately, too. So I offer: the inheritance of structures this one of offers, which in itself it seems insignificant, but useful if to make classes by value. 2. Performance increases. It is not necessary to allocate at the slightest pretext memory in a heap. 3. I offer syntax which presumably does not break an existing code. + On how many I understand, in the existing compiler all necessary for implementation already is, a problem only in syntax addition. 4. Java and C# also uses objects by reference? But both these of language are interpreted. I assume that the interpreter generally with identical speed allocates memory in a heap and in a stack, therefore authors of these languages and used reference model. Neither of these languages are interpreted, they both are compiled into native code at runtime. Oh!:) but I suspect such classes scheme somehow correspond with JIT-compilation. D is compiled language and to borrow reference model incorrectly. In D the programmer should have possibility most to decide where to place object. You still have the problem that the current system works pretty well. And has a lot of history. So you need a very compelling use case to convince Walter that something should change. Thus, actually Java and C# systems works pretty well. And they has a lot of history. But not D. DMD 0.001 was released 7 years ago. Long enough, I think. Yes, I know. I hint at that that it seems this scheme have copied because it is popular but have not considered characteristic for C++-like compiled language nuances.
Re: new principle of division between structures and classes
Denis Koroskin пишет: Back to topic, C++ doesn't have any meaningful separation between classes and structs. D does - (one of it is that) classes are heap allocated by default whereas structs are stack allocated by default. You can override either behavior: class C {} struct S {} C c = new C(); // heap-allocated (default) S s = S(); // stack-allocated (default) scope C c = new C(); // stack-allocated This way does not approach because scope value is impossible to return from function. S* s = new S(); // heap allocated One problem I see with it is that the syntax is so much different, but that's another topic. Other one is that the following works for local variables exclusively, i.e. you can't have class instance aggregated inside another class by value. I am not understand what here a problem with class inside other class. Yes, I think there is a room for improvement but it is of little priority for me. You don't provide use cases nor examples of possible syntax, but they are crucial for understanding. I still was not sure what syntax could. While I operate with the such - probably, it don't break an existing code: class C {} struct S {} C c = new C(); // heap-allocated S s; // stack-allocated S s = S(); // stack-allocated S* s = new S(); // heap allocated C c(); // stack-allocated (added by me) Brackets () do not allow to mix object with the reference. Also, they may contain constructor parameters. Further objects are used as usually. What else? Struct inheritance - yes it is nice to have, even without polymorphism. It was proposed many times but with no success. Someone suggested to use aggregation and opDot instead and allow implicit cast of pointer to struct to pointer to struct's first element to emulate inheritance: Inheriting of structures is necessary for convenience of replacement struct to class and vice versa. Therefore possibility of replacement of struct inheritance on other constructions it is not essential. I'd suggest you to state you ideas as simple and keep your posts as small as possible (trust me, few people like reading long posts). You could also ask someone to check your post before submitting - this will increase the probability of your message to be read and understood. I agree, but the changes offered by me separately look as unreasonably, and only in the sum they yield good result. Thanks for kind words :)
Re: new principle of division between structures and classes
Bill Baxter пишет: Please, state critical remarks Your English is really hard to make sense of. That's my guess for why there are no responses. Heck, I'd *like* to respond, but I just can't tell what you're trying to say. All is absolutely poor? If not everything, can you select that demands the explanation?
Re: new principle of division between structures and classes
Denis Koroskin пишет: I'd suggest you to state you ideas as simple and keep your posts as small as possible (trust me, few people like reading long posts). The extra-short formulation of my idea: Objects should be divided on POD (struct) and non-POD (class). Instead of such division as now: POD value type (struct) and POD reference type (class).
Re: new principle of division between structures and classes
Christopher Wright пишет: Weed wrote: Denis Koroskin пишет: I'd suggest you to state you ideas as simple and keep your posts as small as possible (trust me, few people like reading long posts). The extra-short formulation of my idea: Objects should be divided on POD (struct) and non-POD (class). Instead of such division as now: POD value type (struct) and POD reference type (class). The reference versus value type difference is just a matter of defaults. Returning a class instance on the stack from a function is possible with inout parameters, though you can't use a constructor in that case: void main () { scope MyClass obj = new MyClass; foo (obj); } void foo (inout MyClass obj) { // initialize obj somehow } Problem not only with constructor calling. This way does not works for temporary objects (for example operator overloading). The case in detail was considered in this thread: division of objects into classes and structures is bad, http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81359 Also, it impossible to create an array of scope objects.
Re: new principle of division between structures and classes
Bill Baxter пишет: But since classes can be polymorphic, value copying gets you into slicing problems. That's why value copying is disabled to begin with. So disabling value copies is a good thing. It is not always a good thing. I propose to prohibit only the copying by value of the base type to derivative type And that's also the problem with putting scope'd things inside another class or an array. Since they don't have value semantics, Yes, this is what I mean
Re: new principle of division between structures and classes
Bill Baxter пишет: 2009/1/11 Weed resume...@mail.ru: Bill Baxter пишет: But since classes can be polymorphic, value copying gets you into slicing problems. That's why value copying is disabled to begin with. So disabling value copies is a good thing. It is not always a good thing. Yeh, I just mean there is some merit in disabling value copies. But I don't rule out the possibility that there may be an even better way that banning them altogether. I propose to prohibit only the copying by value of the base type to derivative type Ok, this is key. How do you propose to do this? In general it requires a runtime check, I think. And I think you need to say that you prohibit copying unless typeA==typeB exactly. If you allow copying either way between base and derived you are asking for trouble. But still given Base x = get_one(); Base y = get_another(); *x = *y; // presumed value copy syntax you have no way in general to know that x and y are really both a Base at compile time. So you must have a run-time check there. Perhaps it could be omitted for -release builds, though. It can lead to a difficult and non-reproduceable errors than old C++-style splitting. It is possible to try to prohibit assignment of the dereferenced pointers? Simply to prohibit assignment too it is possible, essentially it changes nothing. And that's also the problem with putting scope'd things inside another class or an array. Since they don't have value semantics, Yes, this is what I mean So assuming you had this, the important question is what would you do with it? The most difficult. My arguments: 1. Problem of a choice of correct type for the object. A mathematical matrix - a classical example. A class it should be or structure? My offer without serious consequences allows to move solution of this problem from a design stage to a programming stage - is it will be simple by replacement keyword class to struct. 2. Performance increases. It is not necessary to allocate at the slightest pretext memory in a heap. 3. I offer syntax which presumably does not break an existing code. + On how many I understand, in the existing compiler all necessary for implementation already is, a problem only in syntax addition. 4. Java and C# also uses objects by reference? But both these of language are interpreted. I assume that the interpreter generally with identical speed allocates memory in a heap and in a stack, therefore authors of these languages and used reference model. D is compiled language and to borrow reference model incorrectly. In D the programmer should have possibility most to decide where to place object. You still have the problem that the current system works pretty well. And has a lot of history. So you need a very compelling use case to convince Walter that something should change. Thus, actually Java and C# systems works pretty well. And they has a lot of history. But not D. This situation reminds me history with the Hungarian notation: Many years ago many developers have started to deliver interfaces and to sell books where it was used. This very correct invention affirmed as many books that and only in ~5 years there were articles with the materials specifying in groundlessness of usage of this notation. Till this time many entered it into corporate standards and suffered, though, I am assured, they were visited by thoughts about irrelevance of the given notation except for special cases.
Re: new principle of division between structures and classes
Bill Baxter пишет: 2009/1/11 Weed resume...@mail.ru: Bill Baxter пишет: But since classes can be polymorphic, value copying gets you into slicing problems. That's why value copying is disabled to begin with. So disabling value copies is a good thing. It is not always a good thing. Yeh, I just mean there is some merit in disabling value copies. But I don't rule out the possibility that there may be an even better way that banning them altogether. I propose to prohibit only the copying by value of the base type to derivative type Ok, this is key. How do you propose to do this? In general it requires a runtime check, I think. And I think you need to say that you prohibit copying unless typeA==typeB exactly. If you allow copying either way between base and derived you are asking for trouble. But still given Base x = get_one(); Base y = get_another(); *x = *y; // presumed value copy syntax you have no way in general to know that x and y are really both a Base at compile time. So you must have a run-time check there. Perhaps it could be omitted for -release builds, though. It can lead to a difficult and non-reproduceable errors than old C++-style splitting. It is possible to try to prohibit assignment of the dereferenced pointers? Simply to prohibit assignment too it is possible, essentially it changes nothing. And that's also the problem with putting scope'd things inside another class or an array. Since they don't have value semantics, Yes, this is what I mean So assuming you had this, the important question is what would you do with it? The most difficult. My arguments: 1. Problem of a choice of correct type for the object. A mathematical matrix - a classical example. A class it should be or structure? My offer without serious consequences allows to move solution of this problem from a design stage to a programming stage - is it will be simple by replacement keyword class to struct. 2. Performance increases. It is not necessary to allocate at the slightest pretext memory in a heap. 3. I offer syntax which presumably does not break an existing code. + On how many I understand, in the existing compiler all necessary for implementation already is, a problem only in syntax addition. 4. Java and C# also uses objects by reference? But both these of language are interpreted. I assume that the interpreter generally with identical speed allocates memory in a heap and in a stack, therefore authors of these languages and used reference model. D is compiled language and to borrow reference model incorrectly. In D the programmer should have possibility most to decide where to place object. You still have the problem that the current system works pretty well. And has a lot of history. So you need a very compelling use case to convince Walter that something should change. Thus, actually Java and C# systems works pretty well. And they has a lot of history. But not D. This situation reminds me history with the Hungarian notation: Many years ago many developers have started to deliver interfaces and to sell books where it was used. This very correct invention affirmed as many books that and only in ~5 years there were articles with the materials specifying in groundlessness of usage of this notation. Till this time many entered it into corporate standards and suffered, though, I am sure, they were visited by thoughts about irrelevance of the given notation except for special cases.
Re: new principle of division between structures and classes
Weed пишет: Weed пишет: (Here I generalise my sentence with supplement) The POD data and the data supporting polymorphism are necessary to us. POD the data is stored in structs and polymorphic objects is classes. Both types (class and struct) can be instanced in a heap or on a stack. (And in invariant ROM too, but there it is not important) Classes and structures support inheritance. But structures do not support polymorphism (as are POD type without vptr) - at attempt to implement virtual function in structure the compiler will give out an error: struct StructName is POD type, it is not support polymorphism, use class instead of. (And certainly structures are not inherited from classes, including from super class Object) Thus, the programmer always knows the object is POD-data or not. The problem of simple alteration of structure to a class and vice versa when necessary also solved. For an exception of splitting of objects it is necessary to check during compilation: or to forbid assignment on value for types not being to the data (how now it works for the structs objects on value) or to forbid the access to the fields added at descending inheritance (its more difficult but desirable) And similar it will not break an existing code (If for a while to keep support scope) Please, state critical remarks Tell, what it is necessary to make that discussion of this question has taken place? I in despair. I even think to wait supports 2.0 in open source compiler using LLVM and to add there this functionality (I hope, my skills will just grow for such operation.)
Re: Why isn't ++x an lvalue in D?
Bill Baxter пишет: Another thread just reminded me of something I use frequently in C++ that doesn't work in D because ++x is not an lvalue: int x,N; ... ++x %= N; So is there some deep reason for not making it an lvalue like in C++? ++x is x+=1 in D: void main() { int i =3; int N =2; (i+=1) %= N; } Error: i += 1 is not an lvalue. C++: int main() { int i = 2; int N = 3; i+1 %= N; return 0; } error: lvalue required as left operand of assignment
Re: Why isn't ++x an lvalue in D?
Bill Baxter пишет: 2009/1/9 Weed resume...@mail.ru: Bill Baxter пишет: Another thread just reminded me of something I use frequently in C++ that doesn't work in D because ++x is not an lvalue: int x,N; ... ++x %= N; So is there some deep reason for not making it an lvalue like in C++? ++x is x+=1 in D: void main() { int i =3; int N =2; (i+=1) %= N; } Error: i += 1 is not an lvalue. C++: int main() { int i = 2; int N = 3; i+1 %= N; return 0; } error: lvalue required as left operand of assignment What does C++ do if you use (i+=1) %= N instead of (i+1)? Doesn't += also return an lvalue in C++? I am a bit mixed, but the meaning has not changed: $ cat demo.cpp int main() { int i = 2; int N = 3; i+=1 %= N; return 0; } $ c++ demo.cpp demo.cpp: In function ‘int main()’: demo.cpp:5: error: lvalue required as left operand of assignment
Re: Why isn't ++x an lvalue in D?
Bill Baxter пишет: On Fri, Jan 9, 2009 at 2:22 PM, Weed resume...@mail.ru wrote: Bill Baxter пишет: 2009/1/9 Weed resume...@mail.ru: Bill Baxter пишет: Another thread just reminded me of something I use frequently in C++ that doesn't work in D because ++x is not an lvalue: int x,N; ... ++x %= N; So is there some deep reason for not making it an lvalue like in C++? ++x is x+=1 in D: void main() { int i =3; int N =2; (i+=1) %= N; } Error: i += 1 is not an lvalue. C++: int main() { int i = 2; int N = 3; i+1 %= N; return 0; } error: lvalue required as left operand of assignment What does C++ do if you use (i+=1) %= N instead of (i+1)? Doesn't += also return an lvalue in C++? I am a bit mixed, but the meaning has not changed: $ cat demo.cpp int main() { int i = 2; int N = 3; i+=1 %= N; return 0; } $ c++ demo.cpp demo.cpp: In function 'int main()': demo.cpp:5: error: lvalue required as left operand of assignment Huh. Ok, well I guess that answers it then. Thanks. Mystery solved! To summarize, In D ++x is x+=1, and in D, like in C++, x+=1 is not an lvalue. Got it. But now I wonder why it's not an lvalue in C++ or D. If x=y is an lvalue and ++x is an lvalue, why shouldn't x+=1 be one too? It is also a lvalue, it is my mistake again. (i+=1) %= N;
Re: Why isn't ++x an lvalue in D?
Bill Baxter пишет: On Fri, Jan 9, 2009 at 2:43 PM, Weed resume...@mail.ru wrote: Weed пишет: Bill Baxter пишет: 2009/1/9 Weed resume...@mail.ru: Bill Baxter пишет: Another thread just reminded me of something I use frequently in C++ that doesn't work in D because ++x is not an lvalue: int x,N; ... ++x %= N; So is there some deep reason for not making it an lvalue like in C++? ++x is x+=1 in D: void main() { int i =3; int N =2; (i+=1) %= N; } Error: i += 1 is not an lvalue. C++: int main() { int i = 2; int N = 3; i+1 %= N; return 0; } error: lvalue required as left operand of assignment What does C++ do if you use (i+=1) %= N instead of (i+1)? Doesn't += also return an lvalue in C++? I am a bit mixed, but the meaning has not changed: $ cat demo.cpp int main() { int i = 2; int N = 3; i+=1 %= N; return 0; } $ c++ demo.cpp demo.cpp: In function 'int main()': demo.cpp:5: error: lvalue required as left operand of assignment And I think it is wrong that the ++ same as += 1. The operator ++ in C uniquely compiles in CPU instruction increment. For objects it would be better to make a += 1 only if undefined overloaded operator ++. Yeh, I think that's scheduled to be changed after Andrei's repeated thrashings of Walter. Thus, once it works it is necessary to change anything if only for the real types increment will give increase for the lowest possible value. (I do not know how the CPU instruction increment works for real values)
Re: new principle of division between structures and classes
Weed пишет: (Here I generalise my sentence with supplement) The POD data and the data supporting polymorphism are necessary to us. POD the data is stored in structs and polymorphic objects is classes. Both types (class and struct) can be instanced in a heap or on a stack. (And in invariant ROM too, but there it is not important) Classes and structures support inheritance. But structures do not support polymorphism (as are POD type without vptr) - at attempt to implement virtual function in structure the compiler will give out an error: struct StructName is POD type, it is not support polymorphism, use class instead of. (And certainly structures are not inherited from classes, including from super class Object) Thus, the programmer always knows the object is POD-data or not. The problem of simple alteration of structure to a class and vice versa when necessary also solved. For an exception of splitting of objects it is necessary to check during compilation: or to forbid assignment on value for types not being to the data (how now it works for the structs objects on value) or to forbid the access to the fields added at descending inheritance (its more difficult but desirable) And similar it will not break an existing code Please, state critical remarks
Re: division of objects into classes and structures is bad
Weed пишет: Bill Baxter пишет: On Tue, Jan 6, 2009 at 1:41 PM, Christopher Wright dhase...@gmail.com wrote: Weed wrote: Who agrees with me? There are still ideas as it is possible to solve this problem and not to destroy language? When you reply to your reply to your reply to your post and nobody else replies to any of your posts, you might start thinking that nobody agrees with you, or cares enough to respond. As to your suggestion that there be compile-time checks for object slicing... well, you'd end up with almost everything with any polymorphism being done by reference for safety. In the remaining situations, scope will usually suffice. I don't think anyone sees sufficient reason to give Walter as much work as you suggest. When would you use this? - In place of the current scope keyword. - For more efficiency with object composition (though scope could be used for this, potentially). - Implementing value semantics with runtime polymorphism. The only interesting thing there is value semantics with polymorphism. If you really care, you can implement polymorphism with structs. My problem is more that I just can't understand the guy so I don't know if I agree with him or not. I think the choice between just value semantics / POD / no polymorphism / heap or stackand reference semantics / non-POD / polymorphism / heap only No, for classes I suggest to choose between: reference semantics / non-POD / polymorphism / heap only (current state) and value or reference semantics / non-POD / polymorphism / heap or stack As a matter of fact how it was in C++, but with check slicing or simply prohibition of assignment to other types by value. Syntax will demand attention before change - it is necessary to make so that there was no mixing of names of references and classes on value. Here the nonsense is written, it is not necessary to be afraid of mixing. I should sleep more:)
new principle of division between structures and classes
(Here I generalise my sentence with supplement) The POD data and the data supporting polymorphism are necessary to us. POD the data is stored in structs and polymorphic objects is classes. Both types (class and struct) can be instanced in a heap or on a stack. (And in invariant ROM too, but there it is not important) Classes and structures support inheritance. But structures do not support polymorphism (as are POD type without vptr) - at attempt to implement virtual function in structure the compiler will give out an error: struct StructName is POD type, it is not support polymorphism, use class instead of. (And certainly structures are not inherited from classes, including from super class Object) Thus, the programmer always knows the object is POD-data or not. The problem of simple alteration of structure to a class and vice versa when necessary also solved. For an exception of splitting of objects it is necessary to check during compilation: or to forbid assignment on value for types not being to the data (how now it works for the structs objects on value) or to forbid the access to the fields added at descending inheritance (its more difficult but desirable) Please, state critical remarks
Re: Operator overloading -- lets collect some use cases
Don пишет: Weed wrote: Don пишет: Weed wrote: Don пишет: Weed wrote: Don пишет: Weed wrote: Frits van Bommel пишет: Don wrote: Frits van Bommel wrote: Don wrote: A straightforward first step would be to state in the spec that the compiler is entitled to assume that X+=Y yields the same result as X=X+Y That doesn't hold for reference types, does it? I thought it does? Got any counter examples? For any class type, with += modifying the object and + returning a new one: The += operator too should return the object (usually this) ALWAYS 'this'. It's another feature of operator overloading which is redundant. Not always. Can be more convenient to create the new object and to return it. For example: if it is necessary to return the object containing the sorted data those sorting hurriedly at creation of the returned object can give a scoring in performance than if the data is sorted in the current object after their change. But then if you have y = x+=b; surely that would give you x and y being different? Wouldn't you want x to also point to the new object? (OK, as Stewart pointed out, you can't!) Otherwise, you have to perform _both_ sorts! I agree, my point of view disputable. The programmer can have a desire to return not current object: the returned and this will be equivalent but are not identical. Do not forget that this object may be not a class - it can be struct and such return can in certain to save a few resources. But if us will force to return this under the threat of a compile error I will not cry.:) And you have certainly noticed that here the solution inaccuracy again appears to divide structures and classes by a principle on value and reference. :) Yah. They're almost the same, but not quite. It's interesting that value semantics are IMPOSSIBLE with classes (I didn't know that until Stewart's post), whereas reference semantics with structs are possible (but ugly) with structs. In my experience with D, I use structs + templates far more frequently than classes + polymorphism. And I suspect that if interfaces were a bit more powerful and efficient, struct+interface might replace even more of the use cases for class-based run-time polymorphism. So I must admit, I'm quite biased against classes. I am absolutely agree with that that the interfaces too are necessary for structs. But whether you by means of templates and mixin repeat an OOP programming paradigm? I generally use compile-time polymorphism rather than run-time. What difference between them? vtable? But there's an interesting question: using opDot() and mixins, how close can you come to implementing classes? All of us have already come! :) In that example with matrices (http://www.dsource.org/projects/openmeshd/browser/trunk/LinAlg/linalg/MatrixT.d, template MultReturnType (ArgT)) the returned type of matrices needed to be altered in void (in the pointer on void). And add check by list on types to make the general for all matrices and other structs (vectors etc.) in compile time. That is to imitate a base virtual class. As a whole so, but I am did not check it. If the present support vtable that is necessary I think it too it is possible to make, I do not see any problems. But if you do not tell that it is bad design that I will be surprised. A particularly interesting case is the GoF Strategy pattern, where derived classes add no data, they only override virtual functions. The slicing problem never happens with such objects, provided that you include the vtable pointer when you copy the object. It is possible also real OOP to imitate not much more difficult Sounds like you want one struct + multiple interfaces. I not against. Really, if the structure has methods that can have and the interface (and interfaces can be inherited), it is logical. As well compile-time inheriting could be made. To write so: struct RGB { ubyte r; ubyte g; ubyte b; } struct RGBA : RGB { ubyte a; } such code is quite clear. But without them it is possible to live. Much more important old kind classes on value, without them it is impossible apparently.
Re: division of objects into classes and structures is bad
Weed пишет: Weed пишет: Weed пишет: Andrei Alexandrescu пишет: Weed wrote: [about structs vs. classes] It is very a pity. My small opinion: it is impossible to reduce performance for struggle against potential errors - such languages already are, it more high-level. It how to refuse pointers because they are dangerous, difficult for beginners and without them it is possible to make any algorithm. It's attractive to deal in absolutes, but also dangerous. When C came about, naysayers complained that it was consistently 30% slower than assembler, and generated larger code by an even higher margin. Then, some asked, what would you choose, one OS that's cool because it's written in C, or one that's one third faster? and so on. What people have forgotten by now is that C *was* high level. And it *did* incur a performance hit. It also had desirable properties that overcame that hit. Can in C# (it uses as far as I know too such sharing) such approach and it is justified - microsoft accelerates replacement of hardware for new OS. :) But we after all not blindly copy C#? After all this problem can be solved, IMHO. I suggest to make so: 1. To leave structures in that kind in which they is (POD) 2. To permit classes declaration such what they in C++ 3. To permit transfer the classes on value (for compulsory pass by reference and for declaration through new now we have ref keyword) 3. To check slicing during compilation. It is possible? For example prohibit assigning on value to the types, not being base or this type 4. scope for classes to deprecate as superfluous In that case there will be problems? Who agrees with me? There are still ideas as it is possible to solve this problem and not to destroy language? And against arguments are still necessary
Re: division of objects into classes and structures is bad
Christopher Wright пишет: Weed wrote: Who agrees with me? There are still ideas as it is possible to solve this problem and not to destroy language? When you reply to your reply to your reply to your post and nobody else replies to any of your posts, you might start thinking that nobody agrees with you, or cares enough to respond. I consoled myself that the letter has got lost in the big thread As to your suggestion that there be compile-time checks for object slicing... well, you'd end up with almost everything with any polymorphism being done by reference for safety. In the remaining situations, scope will usually suffice. I don't think anyone sees sufficient reason to give Walter as much work as you suggest. D2.0 not released, it changes supplemented. I seriously consider at it there is a chance to become the most good language, a silver bullet. :) This discussion - my small contribution. When would you use this? - In place of the current scope keyword. I consider that scope is attempt to fix bad design. Have come to that that on a stack all the same it is necessary to place classes and have added a word, but it does not solve all problems. - For more efficiency with object composition (though scope could be used for this, potentially). - Implementing value semantics with runtime polymorphism. And, probably, in the future it will help to add other possibilities. For example compile-time initialization of classes about which I here spoke too (not in this thread) The only interesting thing there is value semantics with polymorphism. If you really care, you can implement polymorphism with structs. Excellent templates, unit tests, closures, delegates, threads... And after all it is offered to the programmer most implement OOP by hands?
Re: division of objects into classes and structures is bad
Bill Baxter пишет: On Tue, Jan 6, 2009 at 1:41 PM, Christopher Wright dhase...@gmail.com wrote: Weed wrote: Who agrees with me? There are still ideas as it is possible to solve this problem and not to destroy language? When you reply to your reply to your reply to your post and nobody else replies to any of your posts, you might start thinking that nobody agrees with you, or cares enough to respond. As to your suggestion that there be compile-time checks for object slicing... well, you'd end up with almost everything with any polymorphism being done by reference for safety. In the remaining situations, scope will usually suffice. I don't think anyone sees sufficient reason to give Walter as much work as you suggest. When would you use this? - In place of the current scope keyword. - For more efficiency with object composition (though scope could be used for this, potentially). - Implementing value semantics with runtime polymorphism. The only interesting thing there is value semantics with polymorphism. If you really care, you can implement polymorphism with structs. My problem is more that I just can't understand the guy so I don't know if I agree with him or not. I think the choice between just value semantics / POD / no polymorphism / heap or stackand reference semantics / non-POD / polymorphism / heap only No, for classes I suggest to choose between: reference semantics / non-POD / polymorphism / heap only (current state) and value or reference semantics / non-POD / polymorphism / heap or stack As a matter of fact how it was in C++, but with check slicing or simply prohibition of assignment to other types by value. Syntax will demand attention before change - it is necessary to make so that there was no mixing of names of references and classes on value.
Re: Operator overloading -- lets collect some use cases
Don пишет: Weed wrote: Don пишет: Weed wrote: Don пишет: Weed wrote: Frits van Bommel пишет: Don wrote: Frits van Bommel wrote: Don wrote: A straightforward first step would be to state in the spec that the compiler is entitled to assume that X+=Y yields the same result as X=X+Y That doesn't hold for reference types, does it? I thought it does? Got any counter examples? For any class type, with += modifying the object and + returning a new one: The += operator too should return the object (usually this) ALWAYS 'this'. It's another feature of operator overloading which is redundant. Not always. Can be more convenient to create the new object and to return it. For example: if it is necessary to return the object containing the sorted data those sorting hurriedly at creation of the returned object can give a scoring in performance than if the data is sorted in the current object after their change. But then if you have y = x+=b; surely that would give you x and y being different? Wouldn't you want x to also point to the new object? (OK, as Stewart pointed out, you can't!) Otherwise, you have to perform _both_ sorts! I agree, my point of view disputable. The programmer can have a desire to return not current object: the returned and this will be equivalent but are not identical. Do not forget that this object may be not a class - it can be struct and such return can in certain to save a few resources. But if us will force to return this under the threat of a compile error I will not cry.:) And you have certainly noticed that here the solution inaccuracy again appears to divide structures and classes by a principle on value and reference. :) Yah. They're almost the same, but not quite. It's interesting that value semantics are IMPOSSIBLE with classes (I didn't know that until Stewart's post), whereas reference semantics with structs are possible (but ugly) with structs. In my experience with D, I use structs + templates far more frequently than classes + polymorphism. And I suspect that if interfaces were a bit more powerful and efficient, struct+interface might replace even more of the use cases for class-based run-time polymorphism. So I must admit, I'm quite biased against classes. I am absolutely agree with that that the interfaces too are necessary for structs. But whether you by means of templates and mixin repeat an OOP programming paradigm?
Re: division of objects into classes and structures is bad
Weed пишет: Weed пишет: Andrei Alexandrescu пишет: Weed wrote: [about structs vs. classes] It is very a pity. My small opinion: it is impossible to reduce performance for struggle against potential errors - such languages already are, it more high-level. It how to refuse pointers because they are dangerous, difficult for beginners and without them it is possible to make any algorithm. It's attractive to deal in absolutes, but also dangerous. When C came about, naysayers complained that it was consistently 30% slower than assembler, and generated larger code by an even higher margin. Then, some asked, what would you choose, one OS that's cool because it's written in C, or one that's one third faster? and so on. What people have forgotten by now is that C *was* high level. And it *did* incur a performance hit. It also had desirable properties that overcame that hit. Can in C# (it uses as far as I know too such sharing) such approach and it is justified - microsoft accelerates replacement of hardware for new OS. :) But we after all not blindly copy C#? After all this problem can be solved, IMHO. I suggest to make so: 1. To leave structures in that kind in which they is (POD) 2. To permit classes declaration such what they in C++ 3. To permit transfer the classes on value (for compulsory pass by reference and for declaration through new now we have ref keyword) 3. To check slicing during compilation. It is possible? For example prohibit assigning on value to the types, not being base or this type 4. scope for classes to deprecate as superfluous In that case there will be problems? Who agrees with me? There are still ideas as it is possible to solve this problem and not to destroy language?
Re: Operator overloading -- lets collect some use cases
Don пишет: Weed wrote: Don пишет: Weed wrote: Frits van Bommel пишет: Don wrote: Frits van Bommel wrote: Don wrote: A straightforward first step would be to state in the spec that the compiler is entitled to assume that X+=Y yields the same result as X=X+Y That doesn't hold for reference types, does it? I thought it does? Got any counter examples? For any class type, with += modifying the object and + returning a new one: The += operator too should return the object (usually this) ALWAYS 'this'. It's another feature of operator overloading which is redundant. Not always. Can be more convenient to create the new object and to return it. For example: if it is necessary to return the object containing the sorted data those sorting hurriedly at creation of the returned object can give a scoring in performance than if the data is sorted in the current object after their change. But then if you have y = x+=b; surely that would give you x and y being different? Wouldn't you want x to also point to the new object? (OK, as Stewart pointed out, you can't!) Otherwise, you have to perform _both_ sorts! I agree, my point of view disputable. The programmer can have a desire to return not current object: the returned and this will be equivalent but are not identical. Do not forget that this object may be not a class - it can be struct and such return can in certain to save a few resources. But if us will force to return this under the threat of a compile error I will not cry.:) And you have certainly noticed that here the solution inaccuracy again appears to divide structures and classes by a principle on value and reference. :)
Re: division of objects into classes and structures is bad
Weed пишет: Don пишет: Weed wrote: Denis Koroskin пишет: 80490eb: 8d 85 6c fe ff ff lea-0x194(%ebp),%eax 80490f1: 50 push %eax 80490f2: 8d 85 2c fb ff ff lea-0x4d4(%ebp),%eax 80490f8: e8 67 ff ff ff *call 8049064* 80490fd: e8 62 ff ff ff *call 8049064* return c2.i; 8049102: 8b 85 cc fc ff ff mov-0x334(%ebp),%eax ... (in 80490f8 and 80490fd simply two calls successively) If structures and classes were same that excellent optimization in any case would turn out If that's your use case, then your should seriosly reconsider using struct instead of class for your objects. Classes always give such overhead if them to use in such quality. For example, classes basically cannot be used as any mathematical objects using overload of arithmetics. But also not only arithmetics, it it is simple as a good example. Alternatively, you can use += instead. Here yes, but if I add classes of different types? Then not to escape any more from creation of the temporary object in the heap. Other than that, this is not a convincing argument. Reading many of your posts I came to a conclusion that you are shortsighted and too crazy about performance. What you care about is a premature optimization, which is a root of all the evil. You should ensure that your programm is complete and correct, first and *then* start doing profiling and optimizations. The program is already ready. It entirely consists of the various mathematics. Approximately %30 times of performance are spent for similar superfluous work. On C++ the program will work on %30 faster (I hope :)) and on D I am will turn out to do nothing with it. Going back to the topic, dividing user types into two cathegories (structs and classes) is considered modern and right. I do not accept such argument:) Some languages lack structs support at all (e.g. Java), but structs are too useful for optimization and language interoperation to drop them in a systems programming language. Some lack classes and try doing everything with structs (C). D takes the best of both worlds. Probably I have not understood something, but I do not suggest to refuse structures in general. I suggest to allow to create classes on a stack as it is made in C++. That is actually to make structures and classes same, than they and are, for example, in C++. In the initial message I have shown that for perfomance important that the class could be transferred and on value. And it not artful premature optimisation - objects on value always so are transferred, all programmers know it and use when do not wish to allocate a place in a heap, that is usually always when the object will live in {}. Besides, a class in a stack it is normal - keyword addition scope for classes too speaks about it. Rigidly having divided classes and structures D deprives of the programmer of some possibilities which give it C++-like languages. I consider that such languages should give all possibilities which allows CPU but hiding concrete architecture, otherwise I would choose less difficult in use language. Use classes if you want polymorphism. Otherwise, use structs. It's a clear distinction, which is not at all arbitrary -- there are significant implications for the generated code. And if polymorphism is necessary and such calculations are necessary as I have above described? To emulate polymorphism with the mixins? Or simply to reconcile to such obvious losses? I about that that division into classes and structures in language D automatically reduce perfomance of programs. Unlike languages where this division is not present (C++). To solve a problem it is possible having allowed to transfer classes on value (checking during compilation that has not occurred slicing)
Re: division of objects into classes and structures is bad
Andrei Alexandrescu пишет: Weed wrote: Don пишет: Weed wrote: Denis Koroskin пишет: 80490eb: 8d 85 6c fe ff ff lea-0x194(%ebp),%eax 80490f1: 50 push %eax 80490f2: 8d 85 2c fb ff ff lea-0x4d4(%ebp),%eax 80490f8: e8 67 ff ff ff *call 8049064* 80490fd: e8 62 ff ff ff *call 8049064* return c2.i; 8049102: 8b 85 cc fc ff ff mov-0x334(%ebp),%eax ... (in 80490f8 and 80490fd simply two calls successively) If structures and classes were same that excellent optimization in any case would turn out If that's your use case, then your should seriosly reconsider using struct instead of class for your objects. Classes always give such overhead if them to use in such quality. For example, classes basically cannot be used as any mathematical objects using overload of arithmetics. But also not only arithmetics, it it is simple as a good example. Alternatively, you can use += instead. Here yes, but if I add classes of different types? Then not to escape any more from creation of the temporary object in the heap. Other than that, this is not a convincing argument. Reading many of your posts I came to a conclusion that you are shortsighted and too crazy about performance. What you care about is a premature optimization, which is a root of all the evil. You should ensure that your programm is complete and correct, first and *then* start doing profiling and optimizations. The program is already ready. It entirely consists of the various mathematics. Approximately %30 times of performance are spent for similar superfluous work. On C++ the program will work on %30 faster (I hope :)) and on D I am will turn out to do nothing with it. Going back to the topic, dividing user types into two cathegories (structs and classes) is considered modern and right. I do not accept such argument:) Some languages lack structs support at all (e.g. Java), but structs are too useful for optimization and language interoperation to drop them in a systems programming language. Some lack classes and try doing everything with structs (C). D takes the best of both worlds. Probably I have not understood something, but I do not suggest to refuse structures in general. I suggest to allow to create classes on a stack as it is made in C++. That is actually to make structures and classes same, than they and are, for example, in C++. In the initial message I have shown that for perfomance important that the class could be transferred and on value. And it not artful premature optimisation - objects on value always so are transferred, all programmers know it and use when do not wish to allocate a place in a heap, that is usually always when the object will live in {}. Besides, a class in a stack it is normal - keyword addition scope for classes too speaks about it. Rigidly having divided classes and structures D deprives of the programmer of some possibilities which give it C++-like languages. I consider that such languages should give all possibilities which allows CPU but hiding concrete architecture, otherwise I would choose less difficult in use language. Use classes if you want polymorphism. Otherwise, use structs. It's a clear distinction, which is not at all arbitrary -- there are significant implications for the generated code. And if polymorphism is necessary and such calculations are necessary as I have above described? To emulate polymorphism with the mixins? Or simply to reconcile to such obvious losses? I about that that division into classes and structures in language D automatically reduce perfomance of programs. Unlike languages where this division is not present (C++). There is a niche of cases where using the C++-style duality of classes and structs is useful. I think those cases are marginal, and that the conceptual division fostered by D is the better way to go because it's clean and avoids a lot of the inherent problems of duality. It is very a pity. My small opinion: it is impossible to reduce performance for struggle against potential errors - such languages already are, it more high-level. It how to refuse pointers because they are dangerous, difficult for beginners and without them it is possible to make any algorithm. What is D? D is a general purpose systems and applications programming language. It is a higher level language than C++, but *retains* the ability to write high performance code and interface directly with the operating system API's and with hardware. http://www.digitalmars.com/d/2.0/overview.html
Re: division of objects into classes and structures is bad
Don пишет: It is possible to think up other example where there is no overload: space_ship_1.calculatePathTo(Moon).getCheckpoint(3).getCoords; In this example we create a temporary class path, create temporary class checkpoint and we take coords of checkpoint of this path. It is not expedient to us to store all this path and checkpoint because it is vary. I fail to see how D's distinction between classes and structs has any bearing on this. The optimisations you're talking about are only possible in the presence of polymorphism, in cases where you can prove that polymorphism is not being used! I suspect that if you're encountering this issue in speed-critical code, there's a problem with your design. Quite right, if polymorphism I would not be necessary to me did not use classes, it is obvious. All the rest that you have told it the common words so experts in marketing speak. :) I give concrete examples from a life where D is bad. You see a design problem in the code resulted above? If the overhead caused by using classes is unacceptable, then yes. I'd want to see the definition of checkpoint. If it's really polymorphic, how can it be stored on the stack? This doesn't make sense to me. Where a problem? By the way, one of serious problem: if necessary it is difficult enough to alter a class in structure and vice versa. Insufficiently simply to change the keyword. And it is serious, it is not necessary to me to tell about planning.
Re: division of objects into classes and structures is bad
Andrei Alexandrescu пишет: Weed wrote: [about structs vs. classes] It is very a pity. My small opinion: it is impossible to reduce performance for struggle against potential errors - such languages already are, it more high-level. It how to refuse pointers because they are dangerous, difficult for beginners and without them it is possible to make any algorithm. It's attractive to deal in absolutes, but also dangerous. When C came about, naysayers complained that it was consistently 30% slower than assembler, and generated larger code by an even higher margin. Then, some asked, what would you choose, one OS that's cool because it's written in C, or one that's one third faster? and so on. What people have forgotten by now is that C *was* high level. And it *did* incur a performance hit. It also had desirable properties that overcame that hit. Can in C# (it uses as far as I know too such sharing) such approach and it is justified - microsoft accelerates replacement of hardware for new OS. :) But we after all not blindly copy C#? After all this problem can be solved, IMHO. I suggest to make so: 1. To leave structures in that kind in which they is (POD) 2. To permit classes declaration such what they in C++ 3. To permit transfer the classes on value (for compulsory pass by reference and for declaration through new now we have ref keyword) 3. To check slicing during compilation. It is possible? 4. scope for classes to deprecate as superfluous In that case there will be problems? What is D? D is a general purpose systems and applications programming language. It is a higher level language than C++, but *retains* the ability to write high performance code and interface directly with the operating system API's and with hardware. http://www.digitalmars.com/d/2.0/overview.html Probably the worst thing that could happen to that description is it Kafka-esquely morphing into a dogma. Seriously, I trusted it
Re: division of objects into classes and structures is bad
Weed пишет: Andrei Alexandrescu пишет: Weed wrote: [about structs vs. classes] It is very a pity. My small opinion: it is impossible to reduce performance for struggle against potential errors - such languages already are, it more high-level. It how to refuse pointers because they are dangerous, difficult for beginners and without them it is possible to make any algorithm. It's attractive to deal in absolutes, but also dangerous. When C came about, naysayers complained that it was consistently 30% slower than assembler, and generated larger code by an even higher margin. Then, some asked, what would you choose, one OS that's cool because it's written in C, or one that's one third faster? and so on. What people have forgotten by now is that C *was* high level. And it *did* incur a performance hit. It also had desirable properties that overcame that hit. Can in C# (it uses as far as I know too such sharing) such approach and it is justified - microsoft accelerates replacement of hardware for new OS. :) But we after all not blindly copy C#? After all this problem can be solved, IMHO. I suggest to make so: 1. To leave structures in that kind in which they is (POD) 2. To permit classes declaration such what they in C++ 3. To permit transfer the classes on value (for compulsory pass by reference and for declaration through new now we have ref keyword) 3. To check slicing during compilation. It is possible? For example prohibit assigning on value to the types, not being base or this type 4. scope for classes to deprecate as superfluous In that case there will be problems? What is D? D is a general purpose systems and applications programming language. It is a higher level language than C++, but *retains* the ability to write high performance code and interface directly with the operating system API's and with hardware. http://www.digitalmars.com/d/2.0/overview.html Probably the worst thing that could happen to that description is it Kafka-esquely morphing into a dogma. Seriously, I trusted it
Re: dmd platform support - poll
Chad J пишет: Walter Bright wrote: What platforms for dmd would you be most interested in using? .net jvm mac osx 32 bit intel mac osx 64 bit intel linux 64 bit windows 64 bit freebsd 32 bit netbsd 32 bit other? Mac OSX 32 and 64 intel Windows 32 and 64 Linux 32 and 64 WinCE on ARM (yeah, I know it's not on the list, but it matters) Linux on ARM (ditto) Or, better yet: Cross-platform C code. Get me that and I have a lot less reason to even care about the others. And it seems to me, probably this will help to write programs on D for GPU (for CUDA-like engines)
Re: compile-time initialization of objects need?
Christopher Wright пишет: Weed wrote: In fact, the D is not contain a mechanism for compile-time initialization of objects. Maybe add? void main() { S a = S(8); // ok static S b = S(8); // error } You want syntactic sugar for two things: // example 1 void foo () { static S s; static bool s_initialized = false; if (!s_initialized) { s_initialized = true; s = S(8); } } // example 2 // module/class level S s; static this () { s = S(8); } Neither of these need to happen at compile time. It not syntactic sugar. I suggest not to waste time at all performance on run-time initialization of objects and check of side conditions on a course of performance of the program.
Re: 128 bit signed and unsigned integer types
Jason House пишет: Walter Bright Wrote: You know, the unimplemented 128 bit integer types. Does anyone have a use for these? If that means bitwise operations on them would optimize to SSE instructions, then I would love to see them. Why it is impossible to use for the description 128 bit int structure and an assembly insertion for operations over it?
Re: Operator overloading -- lets collect some use cases
Don пишет: There's been some interesting discussion about operator overloading over the past six months, but to take the next step, I think we need to ground it in reality. What are the use cases? I think that D's existing opCmp() takes care of the plethora of trivial cases where , = etc are overloaded. It's the cases where the arithmetic and logical operations are overloaded that are particularly interesting to me. The following mathematical cases immediately spring to mind: * complex numbers * quaternions (interesting since * is anti-commutative, a*b = -b*a) * vectors * matrices * tensors * bigint operations (including bigint, bigfloat,...) I think that all of those are easily defensible. But I know of very few reasonable non-mathematical uses. In C++, I've seen them used for iostreams, It looked strange and confused beginners, it seems to me regexps, and some stuff that is quite frankly bizarre. So, please post any use cases which you consider convincing.
division of objects into classes and structures is bad
(Forgive, again I will mention the patient for me a theme) About why I consider that division of objects into classes and structures is bad. If the object is a class that there will be additional overhead charge at calculation of expressions with this class because it is impossible to allocate a class instance on a stack and transfer it as result to next function. Example with usage of the overloaded function opAdd: //=== import std.stdio; class C { int i; C opAdd( C src ){ auto ret = new C; ret.i = i + src.i; return ret; } } void main() { auto c1 = new C; c1.i = 1; auto c2 = c1 + c1 + c1; writeln( c2.i ); } //=== auto c2 = c1 + c1 + c1; // calculated as: auto c2 = c1.opAdd( c1 ).opAdd( c1 ); The temporary result of opAdd in this expression is located in heap (i.e. with overhead), and only then the reference to it is transferred in the second function opAdd: assume CS:_D4test1C5opAddMFC4test1CZC4test1C L0: pushEAX pushEBX pushoffset FLAT:_D4test1C7__ClassZ callnear ptr __d_newclass mov EBX,EAX mov EAX,8[ESP] mov ECX,8[EAX] mov EDX,010h[ESP] add ECX,8[EDX] mov 8[EBX],ECX add ESP,4 mov EAX,EBX pop EBX pop ECX ret 4 _D4test1C5opAddMFC4test1CZC4test1C ends __Dmain comdat assume CS:__Dmain L0: pushEBX pushoffset FLAT:_D4test1C7__ClassZ callnear ptr __d_newclass mov EBX,EAX mov dword ptr 8[EBX],1 add ESP,4 pushEBX pushEBX mov EAX,EBX mov ECX,[EBX] calldword ptr 014h[ECX] mov EDX,[EAX] calldword ptr 014h[EDX] mov EAX,8[EAX] pop EBX ret __Dmain ends opAdd is called two times (call dword ptr 014h[ECX] and call dword ptr 014h[EDX]). Objects created in heap (call near ptr __d_newclass). There is created two objects and the first of them is temporary. Now we will consider the same example with usage of the object of structure which allows allocation on a stack: //=== struct C { int i; int[100] j; // to prevent returning this struct in registers C opAdd( C src ){ C ret; ret.i = i + src.i; return ret; } } int main() { C c1; // initialise i by random value to prevent compile-time calculation c1.i = cast(int)c1; auto c2 = c1 + c1 + c1; return c2.i; } //=== In this case the compiler easily detects that returned value is allocated in a stack and to transfer it in the following function of anything it is not necessary to do - enough to leave it in a stack (linux objdump output): struct C { int i; int[100] j; // to prevent returning this struct in register C opAdd( C src ){ ... C ret; 8049075: b9 65 00 00 00 mov$0x65,%ecx 804907a: 31 c0 xor%eax,%eax 804907c: 8b 7d 08mov0x8(%ebp),%edi 804907f: f3 ab rep stos %eax,%es:(%edi) ret.i = i + src.i; 8049081: 8b 8d 5c fe ff ff mov-0x1a4(%ebp),%ecx 8049087: 8b 11 mov(%ecx),%edx 8049089: 03 55 0cadd0xc(%ebp),%edx 804908c: 8b 5d 08mov0x8(%ebp),%ebx 804908f: 89 13 mov%edx,(%ebx) 8049091: 8b 45 08mov0x8(%ebp),%eax 8049094: 5f pop%edi 8049095: 5b pop%ebx 8049096: c9 leave 8049097: c2 98 01ret$0x198 804909a: 90 nop 804909b: 90 nop } } int main() { ... auto c2 = c1 + c1 + c1; 80490c3: 8d 9d bc fc ff ff lea-0x344(%ebp),%ebx 80490c9: b9 65 00 00 00 mov$0x65,%ecx 80490ce: ff 33 pushl (%ebx) 80490d0: 83 eb 04sub$0x4,%ebx 80490d3: e2 f9 loop 80490ce _Dmain+0x32 80490d5: 8d 95 cc fc ff ff lea-0x334(%ebp),%edx 80490db: 52 push %edx 80490dc: 8d b5 bc fc ff ff lea-0x344(%ebp),%esi 80490e2: b1 65 mov$0x65,%cl 80490e4: ff 36 pushl (%esi) 80490e6: 83 ee 04sub$0x4,%esi 80490e9: e2 f9 loop 80490e4 _Dmain+0x48 80490eb: 8d 85 6c
trouble with dmd + obj2asm under linux
I wrote and compile program: $ dmd demo.d And I need disassembly it: $ obj2asm ./demo ./demo.d -cdemo.cod And I see asm file demo.cod without names of functions: == .init segment assume CS:.init pushEBP mov EBP,ESP pushEBX sub ESP,4 callnear ptr LC LC: pop EBX add EBX,01056Ch mov EDX,-8[EBX] testEDX,EDX je L22 callnear ptr LC0 L22:callnear ptr L3F8 callnear ptr LD338 pop EAX pop EBX leave ret .init ends .pltsegment assume CS:.plt L0: pushdword ptr [080591A4h] jmp dword ptr [080591A8h] == From other person I have received such listing with names: == assume CS:_D4test1C5opAddMFC4test1CZC4test1C L0: pushEAX pushEBX pushoffset FLAT:_D4test1C7__ClassZ callnear ptr __d_newclass mov EBX,EAX mov EAX,8[ESP] mov ECX,8[EAX] mov EDX,010h[ESP] == What it is necessary to make such listing? $ obj2asm Digital Mars .OBJ file disassembler Version 8.51.3 Copyright (C) Digital Mars 2000-2007. All Rights Reserved. Written by Walter Bright http://www.digitalmars.com/ctg/obj2asm.html Use: obj2asm [-l] [-o] objfile[.obj] [srcfile] [-c[outfile[.cod]]] -c Specify output filename -l Omit generated code labels -o Output object code for each assembly instruction. -x Emit code offsets
Re: compile time method check
Bill Baxter пишет: 2008/12/27 Weed resume...@mail.ru: Simen Kjaeraas пишет: On Fri, 26 Dec 2008 20:15:30 +0100, Weed resume...@mail.ru wrote: Can I at compile time check whether there is a facility method (toString(), for example)? Today I wrote: static if ( __traits(isArithmetic, Element) ) { ret ~= toString(this[i,j]) ~ \t; } else { ret ~= this[i,j].toString ~ \t; } It works but it is wrong I believe this works: static if (is(typeof(this[i,j].toString))) { ret ~= this[i,j].toString; } else { ret ~= toString(this[i,j]); } No, this cause error: toString () does not match parameter types (float) ( condition is always resolved to else {...} ) That's because float's don't have a toString method. So it should be picking the else{} case. If you try it with something where this[i,j] returns an Object or struct with a toString, then it should pick the 'if' branch. There was confusion between this.toString () and std.stdio.toString () Fixed, thanks!
compile-time initialization of objects need?
In fact, the D is not contain a mechanism for compile-time initialization of objects. Maybe add? For example, that would be very usable for any objects which have mathematical primitives. Example: struct S { float[10] array; this( float f ) { array[0] = f; } } void main() { S a = S(8); // ok static S b = S(8); // error }
Re: Big integrals, opApply autoindex, safer integrals
bearophile пишет: Recently we have discussed a lot about the balance of putting things inside the language or outside of it. It's a subtle balance and it's dynamic too, with time it can change (for example the removal of complex numbers from D2?). Surely it will need more discussions in the future too. In the past I have discussed about the uses of multi-precision integral numbers. They can be put inside the std lib (std.bigint) or inside the compiler (many other languages, etc). But there's another intermediate solution regarding those multi-precision numbers: keep them outside the language but allow the language to manage them with a transparent syntax. So even if the compiler doesn't know how to add two of such numbers (and you have to load such operations from a module), the syntax of the language allows you to write: import bigints: Bigint; ... Bigint x = 71_459_266_416_693_160_362_545_788_781_600; Instead of: BigInt x = 71459266416693160362545788781600; This keeps the implementation of the operations outside the compiler, keeping it simpler and allowing different implementations, for example using bindings to the GNU multiprecision, and allows the user to manage such numbers in a transparent way, as (or almost as) they were built-in in the language. It is not enough to make Bigint the object?
Re: dmd platform support - poll
Nick Sabalausky пишет: Chad J gamerc...@__spam.is.bad__gmail.com wrote in message news:gj1uou$1ct...@digitalmars.com... Walter Bright wrote: Chad J wrote: Or, better yet: Cross-platform C code. Get me that and I have a lot less reason to even care about the others. The problem with generating C code is: exception handling At any rate, please don't just give up on this! GAME CONSOLES Walter! GAME CONSOLES! ;) Yea, I've always seen videogames as one of the biggest and best applictions for D, and the main one that originally got me excited for it. But without the ability to use it on game-consoles/embedded-cpus/microcontrollers, it'll never be worthwhile for most developers. They'd be forced into just one platform, the PC (In this case, I'm including Mac as a Personal Computer). It seems to me it is necessary to reconsider it: Support for 16 bit computers. No consideration is given in D for mixed near/far pointers and all the machinations necessary to generate good 16 bit code. The D language design assumes at least a 32 bit flat memory space. D will fit smoothly into 64 bit architectures. (http://www.digitalmars.com/d/2.0/overview.html)
Re: Big integrals, opApply autoindex, safer integrals
bearophile пишет: Weed: It is not enough to make Bigint the object? I think I have already answered your question (and at the moment BigInt is a struct, I think). I did not understand the problem. You can make an object Bigint. You can add, deduct the value BigInt. You can declare them as follows: Bigint x = 71_459_266_416_693_160_362_545_788_781_600; or even so (to avoid confusion with strings): Bigint x = Bigint(71_459_266_416_693_160_362_545_788_781_600); Only that it will be impossible to do so to declare x static :) And another: where else can I apply it?
Re: Big integrals, opApply autoindex, safer integrals
Yigal Chripun пишет: Weed wrote: Yigal Chripun пишет: Weed wrote: bearophile пишет: Weed: where else can I use that thing? I was talking about a built-in syntax for multi-precision integral numbers. I presume you can use it only when you want to use multi-precision integral number :-) Do you feel the need to use it in other situations too? I thought proposes a more advanced method for operators overloading :) It seems to me, all operators working with values should correspond to processor instructions. Instruction like Sum int [80] with int [30] does not exist and it is not necessary to do for it the built-in-like syntax. I disagree. Programing languages are for programmers, i.e Humans, not CPUs. if you want to work with a programming language that corressponds to a CPU, go learn Assemby language. It makes perferct sense to use operators that do not corespond to cpu instructions, for example: auto m1 = new Matrix(10, 30); auto m2 = new Matrix(30, 20); ... fill m1, m2 with data... auto res = m1 * m2; Ohhh! Matrices! Mmmm... :) The point of programming languages is to provide abstarctions to the underlying machine, without the overhead! so that we humans can express complex problems to the CPU more easily. Yes. But language without the overhead costs almost get what I said. also, another reason for allowing: Sum int [80] with int [30] is due to vectorization. modern CPUs can perform operations on vectors so instead of doing: for (int i = 0; i 80; ++i) { sum[i] = a[i] + b[i] } the CPU can process those in chunks of 4 ints at a time or something like that. This is already implemented in DMD. int[80] there is not an array of type int, it very big 80 bit int value So initialization of mathematical types at compile time would be more interesting:) sorry, I don't understand your english. You are in the majority:) int[80] is an array. see: No! int [80] is not an array here! It 80bit int value: 01010010010101001001010100100101010010010101001001010100100101010010010101001001 I just accidentally used the D syntax to describe it. Sorry. auto a = int[80]; personally I'm against your idea of using static data as this is thread unsafe. What is my idea? D2 will have shared to deal with multi-threading issues like that. still, I'd say that static should be limited to invariant data. it makes sense to do: static invariant m = IdentityMatrix(3,5); for instance, but what's the benefits of doing the same for mutable data? I don't see it..