digitalmars.D.learn - Module-based programming
- Land (30/30) Jul 26 2013 I'm confused when it comes to modules.
- Jacob Carlborg (15/45) Jul 26 2013 Modules are not singleton classes. They haven't much to do with classes
- JS (4/35) Jul 26 2013 Non-member methods require you to pass the object you want to
- John Colvin (5/50) Jul 26 2013 Is it really extra typing? Depending on how you format your code,
- JS (3/54) Jul 26 2013 But what about protection semantics? Access to this? Properties?
- John Colvin (5/62) Jul 26 2013 There are lots of good reasons to use methods instead of free
- Dicebot (6/8) Jul 26 2013 Non-public methods should not be free functions. Same goes for
- Dicebot (7/17) Jul 26 2013 I personally favor this approach whenever possible, it fits
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (29/46) Jul 26 2013 +1
- Land (5/5) Jul 26 2013 Thanks for all the replies. What about inheritance and
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (13/17) Jul 26 2013 At least technically, yes. There is no other way for interfaces and
- Rikki Cattermole (15/46) Jul 26 2013 Personally I have a few rules with deciding between a class and a
I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class. But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answers
Jul 26 2013
On 2013-07-26 11:12, Land wrote:I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class.Modules are not singleton classes. They haven't much to do with classes at all. I mean, you cannot inherit modules.But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answersIn general I would say go with a class, but since you mentioned OpenGL it probably needs to go very fast and minimize allocations. In that case a struct would probably be better, if you're going to use a lot of these Shaders. It also depends on if you need value semantics or reference semantics for Shader. Classes always have reference semantics, structs have value semantics by default, and if you use a pointers you'll get reference semantics. Note that you can have methods in a struct too. So in any case, I would say, don't put the functions at module scope. -- /Jacob Carlborg
Jul 26 2013
On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class. But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answersNon-member methods require you to pass the object you want to modify... do you really want to do all that extra typing? It's your choice... you wanna program in C or C++?
Jul 26 2013
On Friday, 26 July 2013 at 11:42:25 UTC, JS wrote:On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:Is it really extra typing? Depending on how you format your code, you might just be swapping a '.' for a ',' Also, we have UFCS (universal function call syntax): "foo(x, y, z)" can be written as "x.foo(y, z)"I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class. But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answersNon-member methods require you to pass the object you want to modify... do you really want to do all that extra typing? It's your choice... you wanna program in C or C++?
Jul 26 2013
On Friday, 26 July 2013 at 11:58:13 UTC, John Colvin wrote:On Friday, 26 July 2013 at 11:42:25 UTC, JS wrote:But what about protection semantics? Access to this? Properties? Virtual functions?On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:Is it really extra typing? Depending on how you format your code, you might just be swapping a '.' for a ',' Also, we have UFCS (universal function call syntax): "foo(x, y, z)" can be written as "x.foo(y, z)"I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class. But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answersNon-member methods require you to pass the object you want to modify... do you really want to do all that extra typing? It's your choice... you wanna program in C or C++?
Jul 26 2013
On Friday, 26 July 2013 at 13:11:33 UTC, JS wrote:On Friday, 26 July 2013 at 11:58:13 UTC, John Colvin wrote:There are lots of good reasons to use methods instead of free functions, I'm just saying that having to explicitly pass the object to the function isn't a particularly big one, especially in D.On Friday, 26 July 2013 at 11:42:25 UTC, JS wrote:But what about protection semantics? Access to this? Properties? Virtual functions?On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:Is it really extra typing? Depending on how you format your code, you might just be swapping a '.' for a ',' Also, we have UFCS (universal function call syntax): "foo(x, y, z)" can be written as "x.foo(y, z)"I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class. But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answersNon-member methods require you to pass the object you want to modify... do you really want to do all that extra typing? It's your choice... you wanna program in C or C++?
Jul 26 2013
On Friday, 26 July 2013 at 13:11:33 UTC, JS wrote:But what about protection semantics? Access to this? Properties? Virtual functions?Non-public methods should not be free functions. Same goes for virtual ones. Access to this is no different from access to first parameter of function. That still leaves tons of utility stuff people usually implement as methods despite the fact they don't really need to be ones.
Jul 26 2013
On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:struct Shader { // Field // Field // Field } // Method // Method // Method // MethodI personally favor this approach whenever possible, it fits nicely with UFCS and allows to keep data type signature clean from unrelated stuff. My guideline is "If something simply operates on an aggregate, make it a free function. If it requires some knowledge about private aggregate state and/or is something done by aggregate, make it a method".
Jul 26 2013
On 07/26/2013 05:13 AM, Dicebot wrote:On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:+1 I apply the same idea in C++ as well. Of course, the decision of whether it is a struct or class is based on other factors. (This is not an issue in C++ because structs and classes are semantically same there.) And yes, UFCS helps with this in D. I had come up with a quick example: Once a Car class provides basic functionality, functions like canTravel() should not be members: [1] class Car { enum economy = 12.5; // kilometers per liter (average) private double fuelAmount; // liters this(double fuelAmount) { this.fuelAmount = fuelAmount; } double fuel() const { return fuelAmount; } // ... } bool canTravel(Car car, double distance) { return (car.fuel() * car.economy) >= distance; } Ali [1] http://ddili.org/ders/d.en/ufcs.htmlstruct Shader { // Field // Field // Field } // Method // Method // Method // MethodI personally favor this approach whenever possible, it fits nicely with UFCS and allows to keep data type signature clean from unrelated stuff. My guideline is "If something simply operates on an aggregate, make it a free function. If it requires some knowledge about private aggregate state and/or is something done by aggregate, make it a method".
Jul 26 2013
Thanks for all the replies. What about inheritance and interfaces, though? Am I supposed to put all the interface/inherited methods into the object and all the other, utility methods, as free functions? Do I understand that correctly?
Jul 26 2013
On 07/26/2013 08:33 AM, Land wrote:What about inheritance and interfaces, though? Am I supposed to put all the interface/inherited methods into the objectAt least technically, yes. There is no other way for interfaces and function overriding.and all the other, utility methods, as free functions?Some people think that as long as a function can be implemented as a free-standing function, then it should be a free-standing function. My earlier canTravel() is a good example. (Aside: In D, there is no free-standing function, they are all at least parts of modules.) Others think that any function closely related to a type should be a member function. Interestingly, canTravel() is good example here as well. :) Since most modern cars do report estimated distance the car can go with the remaining fuel, canTravel() can also be designed to be a member function. Ali
Jul 26 2013
On Friday, 26 July 2013 at 09:12:27 UTC, Land wrote:I'm confused when it comes to modules. I've read somewhere that modules are basically 'singleton classes' and that anything that doesn't need its own state should not needlessly be put inside a class. But what if I want to create a simple OpenGL shader object. Do I create a class like this: class Shader { // Method // Method // Method // Method // Field // Field // Field } Or do I have a structure that I operate on via module methods? (C-style, basically) struct Shader { // Field // Field // Field } // Method // Method // Method // Method It's probably clear to you guys, but I'm stumped. Thanks for any answersPersonally I have a few rules with deciding between a class and a struct. A struct contains either data or functions (for global grouping them) although I'm sure somebody will say performance wise that could be bad. A class contains both data and methods to manipulate it. With regards to free functions for classes I look at it this way. If it needs the internal state it should probably be a method. If not probably external. All required methods also should be on the class. These should be not creating new instances of said class as well. Oh and a nice syntax for those free functions is with. with(instance) { } So instead of typing instance.m, m will suffice.
Jul 26 2013