digitalmars.D - Function APIs and/or classes
- Matthew (50/50) May 07 2004 Walter and I are having a little friendly disagreement which is holding ...
- J Anderson (6/8) May 07 2004 We're only hearing one side of the story but 3 is the obvious choice for...
- Ant (10/11) May 07 2004 I'm pissed off now!
-
Derek
(21/39)
May 07 2004
- Ant (6/7) May 07 2004 You're right.
- Unknown W. Brackets (17/19) May 07 2004 Ant, I'm sorry, but why do yuo really care that much? Do you feel that
- Mike Wynn (18/37) May 07 2004 its not a problem its a principle.
-
Walter
(12/20)
May 07 2004
I haven't made any money whatsoever off of D itself
. The idea is to ... - Mike Wynn (29/49) May 07 2004 and anyone who does not buy your book when it comes out deserves
- resistor AT nospam DOT mac DOT com (7/12) May 07 2004 I'd like to add a suggestion 3: bugzilla. If this language is going to ...
- Brad Anderson (7/26) May 07 2004 I would add that in deference to Bugzilla, I've been investigating
- Unknown W. Brackets (15/23) May 07 2004 Yes, the priniciple of paranoid slashdot-reading, cave-living bats who
- Mike Wynn (26/49) May 07 2004 Oh, you have me so wrong,
- Blandger (4/5) May 07 2004 +1
- Blandger (4/5) May 07 2004 +1
- Blandger (4/5) May 07 2004 +1
- Norbert Nemec (19/20) May 07 2004 I agree with that. Anyhow, I believe it can be made more specific:
- Derek (13/27) May 07 2004 Option 4 (as it can be seen as a superset of option 3).
- Bruno A. Costa (12/17) May 07 2004 Matthew,
- Ben Hinkle (8/14) May 07 2004 Without seeing the actual declarations I vote for 1. If there is an obvi...
- Matthew (15/28) May 07 2004 http://www.amazon.com/exec/obidos/tg/detail/-/0060005688/102-3661341-204...
- Andy Friesen (9/19) May 07 2004 There's something to be said for unity, I think. I say 1 or 2,
- Matthew (22/39) May 07 2004 functions)
- fred (1/3) May 07 2004
- Ilya Minkov (4/10) May 07 2004 For this library, probably no. 1, else probably no. 2. There should be
- mike parker (6/14) May 07 2004 My vote goes for #1. I'll happily use #2 without complaints though, if
- C (8/24) May 07 2004 I agree, i honestly think the base library needs to be free functions
- Benji Smith (12/13) May 07 2004 I think I'd probably prefer to see the free functions implemented as
- Unknown W. Brackets (4/7) May 07 2004 I must say, this is a lovely idea. Unless I'm mistaken, these could be
- Matthew (8/14) May 07 2004 In that case, what the user would have is effectively option 3, so I see...
- Unknown W. Brackets (30/35) May 07 2004 This is a difficult issue, because it involves both inconsistency and
- Kevin Bealer (28/39) May 07 2004 Actually, it would be more like:
- Unknown W. Brackets (28/61) May 07 2004 Yes, but you still have formatted_output in the sumbol table. Before
- Kevin Bealer (13/23) May 09 2004 .
- Unknown W. Brackets (14/20) May 11 2004 I've always thought of this as a possible function for with. That's
- Eric Anderton (12/19) May 07 2004 My vote is for 2, with some suggestions to make free functions work (opt...
- Matthew (12/32) May 07 2004 Unfortunately, because Walter and I've been arguing about the implementa...
- Walter (32/36) May 07 2004 Yes.
- Derek (14/42) May 07 2004 As I was getting ready for bed last night, I was thinking exactly the sa...
- Chris Lawson (5/16) May 11 2004 Although if there's enough people who want to do this, it's going to be
- Matthew (84/120) May 07 2004 I don't have a problem with any of that, but I am also a pragmatist, and
- Walter (9/26) May 07 2004 own free
- Regan Heath (24/48) May 09 2004 Have you considered the 'singleton' approach for your alternate API, eg.
- J Anderson (8/51) May 07 2004 This sounds reasonable. I assumed from Mathews original post that he
-
DemmeGod
(8/11)
May 12 2004
- Jeroen van Bemmel (11/19) May 07 2004 Exactly how many functions are we talking about? Are there complex
- Matthew (44/65) May 07 2004 The basic API is
- resistor AT nospam DOT mac DOT com (19/69) May 07 2004 I've talked about this some in other posts, but I'm of the opinion that ...
- Matthew (59/145) May 07 2004 It's an interesting point that you make.
- mike parker (15/19) May 08 2004 If you're speaking of supporting something like:
- Mike Wynn (6/8) May 08 2004 can you post some code that shows this, as from my experiance (see bug
- Robert Jones (6/72) May 07 2004 I perfer number 4, however it seems to me that Walter is against it for
Walter and I are having a little friendly disagreement which is holding up the inclusion of the std.loader module into Phobos. Basically, it goes like this: Walter believes that every module should have a single, unambiguous API. He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things. I believe that what Walter believes is a good thing, except for the fact that I see that it limits the choices of developers. Some people want to use free functions, others a class-based approach, others to mix and match as they deem appropriate. (I'm in the last camp.) I don't ascribe to the free function-only approach because object-orientation has a lot going for it. If people want that exclusively, then C is the language for them, methinks. I don't ascribe to the class-only model for the converse reasons - i.e. sometimes free functions are more convenient/appropriate - in general, and for the specific reason that I don't believe that exceptions represent the "one true error-handling mechanism", and I don't want to be forced to use them when _I_ deem that it's not appropriate to my requirements. Sometimes I want to write small utilities and simply get a success/rail result from a function. I certainly want this facility with std.loader, as I plan to write version/COM-server trawling utilities and I don't see it as appropriate to be using exceptions (since exceptions are for exceptional circumstances, not for testing things, IMO at least). Hence, the way I've written loader.d (and some other modules), is that there is a free function API, and a thin class (+ exceptions) wrapper over that API. This affords the flexibility to suit all tastes. I won't bang on about the advantages of this approach further, as those that agree already agree, and it's my experience that those who want only a class-only approach cannot be persuaded to look at the virtues of the other side. (Walter asserts that the dual approach makes the code harder to maintain. I assert the contrary. After much debate, we're both still seeing it our own way. Must be one of those things, I guess ...) What I'm interested in is getting a feeling for the general level of support for the following options. Before I enumerate those options, let me make it clear that I don't believe this approach is valid for all modules, far from it. The std.windows.registry, std.mmfile and the std.perf (not yet included) modules are entirely class-based. The std.recls module has both, and I have written std.loader as both. It is this latter that is the sticking point, as Walter does not want to release it in such a guise. The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughts Cheers Matthew
May 07 2004
Matthew wrote:3. combined approach, in same moduleWe're only hearing one side of the story but 3 is the obvious choice for me. Some times it nicer to deal with classes others, free-functions. You've gotta strike the right balance. -- -Anderson: http://badmama.com.au/~anderson/
May 07 2004
In article <c7fhhj$2gtc$1 digitaldaemon.com>, Matthew says...Please let me know your thoughtsI'm pissed off now! Please state clearly if our analises and conclusins are going to by included on a product that is the sole property of Synesis before asking for contributions. What Synesis decides to do with that product is irrelevant for the fact the our work might be beeing donated to Synesis. Thanks. Respectifully (how ever it's spelled) Ant
May 07 2004
On Fri, 7 May 2004 09:19:35 +0000 (UTC), Ant wrote:In article <c7fhhj$2gtc$1 digitaldaemon.com>, Matthew says...<soapbox> There is a distinction between a software specification and the implementation of that specification. It is (mostly) reasonable that the sponsor of an implementation (not necessarily its author) have ownership of the implementation. However, any original ideas that are contained in a specification, are always owned by the author of the idea until ownership is explicitly assigned away by the author. Thus I feel that discussions like these go in to maintaining the specification. It then up to the implementation team to convert the changes into real code. To summarize, Synesis will continue to own the Digital Mars D compiler code but our original ideas that are incorporated into the D specification are not automatically owned by Synesis. You are quite free to write your own D compiler and thus own that implementation. </soapbox> -- Derek Melbourne, AustraliaPlease let me know your thoughtsI'm pissed off now! Please state clearly if our analises and conclusins are going to by included on a product that is the sole property of Synesis before asking for contributions. What Synesis decides to do with that product is irrelevant for the fact the our work might be beeing donated to Synesis. Thanks. Respectifully (how ever it's spelled)
May 07 2004
In article <ki1h4w8lihf7.7epxl2sd0ogo.dlg 40tude.net>, Derek says...<soapbox>You're right. and Seems nobody cares. Probably is not as important as I thought. Ant
May 07 2004
Ant wrote:What Synesis decides to do with that product is irrelevant for the fact the our work might be beeing donated to Synesis.Ant, I'm sorry, but why do yuo really care that much? Do you feel that your suggestions in this area are worth - what, $50, $100 dollars? So you're donating them to Synesis. Pah... this is a problem because? It's not like anyone's going to claim your suggestions were not written by you. It's not like anyone's going to sell your suggestions. It's not even like anyone is going to horde them. If you don't want to offer your opinions or suggestions, hey - that's your call. But blaming it on a license seems a bit wishy washy, because really what does it matter who owns your comment? If it were even that my comment would suddenly be owned by Synesis, I would still comment. If I thought I could give a comment to Microsoft that would improve things in a way, even if they would own my comment... I'd do it. Who cares who owns it? I mean, I'm a capitalist too, and I can and have sold just my opinion before, but this is really a bit much, isn't it? -[Unknown]
May 07 2004
On Fri, 07 May 2004 11:42:08 -0700, "Unknown W. Brackets" <unknown at.simplemachines.dot.org> wrote:Ant wrote:its not a problem its a principle.What Synesis decides to do with that product is irrelevant for the fact the our work might be beeing donated to Synesis.Ant, I'm sorry, but why do yuo really care that much? Do you feel that your suggestions in this area are worth - what, $50, $100 dollars? So you're donating them to Synesis. Pah... this is a problem because?It's not like anyone's going to claim your suggestions were not written by you. It's not like anyone's going to sell your suggestions. It's not even like anyone is going to horde them.it is exactly that, we all accept (I assume) that D is owned by Walter/Digital mars, and any money Walter makes from our sugestions is just payment for giving us the D compiler for free. however with Synesis it is not so clear, why loader.d for instance, instead of improving the dynloader.d I posted feb 2003 http://www.digitalmars.com/drn-bin/wwwnews?D/11102 which was free for everyone to use and modify and give back to the community without charge or restriction, Walter/synesis chose to give similar functionality but with restriction.If you don't want to offer your opinions or suggestions, hey - that's your call. But blaming it on a license seems a bit wishy washy, because really what does it matter who owns your comment?I think he's very justified in blaming the license, he's put in a lot of effort for little/no reward only to find that someone (other than Walter) may be rewarded for his efforts.If it were even that my comment would suddenly be owned by Synesis, I would still comment. If I thought I could give a comment to Microsoft that would improve things in a way, even if they would own my comment... I'd do it. Who cares who owns it? I mean, I'm a capitalist too, and I can and have sold just my opinion before, but this is really a bit much, isn't it? -[Unknown]that is you opinion, and your choice, do not expect everyone to wish to follow your example, which is uncorroborated. Mike
May 07 2004
"Mike Wynn" <one_mad_alien hotmail.com> wrote in message news:fmon90dcch9sqi36uqnv33q6vj8s7hf5i7 4ax.com...Walter/Digital mars, and any money Walter makes from our sugestions is just payment for giving us the D compiler for free.I haven't made any money whatsoever off of D itself <g>. The idea is to make money doing presentations on D and producing books, articles, training materials, etc.however with Synesis it is not so clear, why loader.d for instance, instead of improving the dynloader.d I posted feb 2003 http://www.digitalmars.com/drn-bin/wwwnews?D/11102 which was free for everyone to use and modify and give back to the community without charge or restriction, Walter/synesis chose to give similar functionality but with restriction.Matthew has promised to change the license, but it's moot at the moment because we don't agree on the design of loader.d. Be that as it may, there is an ongoing problem here of people posting code like yours - it gets lost in the blizzard of postings. We must do better. I propose one of the two: 1) make a newsgroup digitalmars.D.sourcecode for contributions. 2) add it to the D wiki.
May 07 2004
On Fri, 7 May 2004 13:46:42 -0700, "Walter" <newshound digitalmars.com> wrote:"Mike Wynn" <one_mad_alien hotmail.com> wrote in message news:fmon90dcch9sqi36uqnv33q6vj8s7hf5i7 4ax.com...and anyone who does not buy your book when it comes out deserves cast(FieryPit)Walter/Digital mars, and any money Walter makes from our sugestions is just payment for giving us the D compiler for free.I haven't made any money whatsoever off of D itself <g>. The idea is to make money doing presentations on D and producing books, articles, training materials, etc.I've put some of my code onto www.dsource.org so its public, and under source control, with the intention that leading by example, others who have open source D projects will do the same and in doing so create a central location for D source so things don't get duplicated (at present there is not a great deal of duplication) I think a D open source projects anouncements news group, ideally moderated so it only has relivant posts would be a fantastic idea, I get the impression that the D community has grown to in the last year, and if it keeps expanding the signal to noise ratio on the news groups will make the situation even worse. to go back over old posts I like the Perl6 approach with requests for comment http://dev.perl.org/perl6/rfc/ apocalypses, exegeses and synopses it may slow development, but when realy pushed I think most ppl would prefer 1 good release to 6 wrong ones. apart from bug releases (and I know a few ppl are waiting for mixins) I think the change from instance Foo(X) Foo_x; to Foo!(X) and allowing class/struct templates was my last major gripe with D. may be now a good time to start getting ppl to design and produce phobos 1.0 ideally LGPL/BSD taking full advantage of D (i.e. classes,templates, buildin types (assoc+growable array) and function which ever gives the most effective solution). Mike.however with Synesis it is not so clear, why loader.d for instance, instead of improving the dynloader.d I posted feb 2003 http://www.digitalmars.com/drn-bin/wwwnews?D/11102 which was free for everyone to use and modify and give back to the community without charge or restriction, Walter/synesis chose to give similar functionality but with restriction.Matthew has promised to change the license, but it's moot at the moment because we don't agree on the design of loader.d. Be that as it may, there is an ongoing problem here of people posting code like yours - it gets lost in the blizzard of postings. We must do better. I propose one of the two: 1) make a newsgroup digitalmars.D.sourcecode for contributions. 2) add it to the D wiki.
May 07 2004
In article <c7gt47$1i46$1 digitaldaemon.com>, Walter says...Be that as it may, there is an ongoing problem here of people posting code like yours - it gets lost in the blizzard of postings. We must do better. I propose one of the two: 1) make a newsgroup digitalmars.D.sourcecode for contributions. 2) add it to the D wiki.I'd like to add a suggestion 3: bugzilla. If this language is going to take off, it'd really pay off to have the scalability bugzilla offers, and even if it doesn't it works wonders in terms of keeping everything organized. Owen
May 07 2004
resistor AT nospam DOT mac DOT com wrote:In article <c7gt47$1i46$1 digitaldaemon.com>, Walter says...I would add that in deference to Bugzilla, I've been investigating Scarab (http://scarab.tigris.org) and it looks promising. I'd like to get a copy up and running as a test for a project on dsource. Wanna throw some code in for docoa? We could kick the tires on Scarab at the same time... BABe that as it may, there is an ongoing problem here of people posting code like yours - it gets lost in the blizzard of postings. We must do better. I propose one of the two: 1) make a newsgroup digitalmars.D.sourcecode for contributions. 2) add it to the D wiki.I'd like to add a suggestion 3: bugzilla. If this language is going to take off, it'd really pay off to have the scalability bugzilla offers, and even if it doesn't it works wonders in terms of keeping everything organized. Owen
May 07 2004
Mike Wynn wrote:On Fri, 07 May 2004 11:42:08 -0700, "Unknown W. Brackets" <unknown at.simplemachines.dot.org> wrote:Yes, the priniciple of paranoid slashdot-reading, cave-living bats who suspect everything is a conspiracy against them and open source. I'm more scared of them (in the way you're scared of a rabid dog or a lock-away in an asylum) than I am of Synesis owning my code. I bet I could make you have an "episode" by saying that I believe the GPL is... GASP!! not perfect for everyone. Please don't kill too many people before they get you chained down. Don't get me wrong though - I'm a strong supporter of open source and I've contributed code and other things to many open source projects (Mozilla, IE7, PHP, YaBB/YaBB SE, etc. just to name some of the more prolific ones off the top of my head.) and always release my software under a free license (although not always GPL) - but that doesn't mean I'm a paranoid conspiracy theorist. -[Unknown]Ant, I'm sorry, but why do yuo really care that much? Do you feel that your suggestions in this area are worth - what, $50, $100 dollars? So you're donating them to Synesis. Pah... this is a problem because?its not a problem its a principle.
May 07 2004
On Fri, 07 May 2004 14:51:20 -0700, "Unknown W. Brackets" <unknown at.simplemachines.dot.org> wrote:Mike Wynn wrote:Oh, you have me so wrong, I'm not fan of the GPL (prefer the BSD license) I object to companies such as RedHat who have taken GPL'd code and made profit from it, infact I read a report last year that Linux servers cost more to administer than NT4 servers (of course the survey neglected to mention FreeBSD [my OS of chose, XP being the OS I have to use to feed myself]) I'm no paranoid conspiracy theorist, but I've seen enough good intentions corrupted by greed and infighting to stand up for my own beliefs. if you truely believe that open source should be open and free (not just open which is a totally meaning less term,not that free can't have its semantics "adjusted") then you should understand why Ant feels the way he does, and respect his (and my) view rather than resorting to exagersted descriptions of ppl who I would imagine most ppl here also have little time for, unlike ANt who has earned respect for the work he has done. Mike. P.S. I don't read slash-dot (came to D via Dr Dobbs) I'd like to be a bat, you get to fly, and scare women in the shower (without ending up in prison). and the only thing that scares me is politicians! Mike.On Fri, 07 May 2004 11:42:08 -0700, "Unknown W. Brackets" <unknown at.simplemachines.dot.org> wrote:Yes, the priniciple of paranoid slashdot-reading, cave-living bats who suspect everything is a conspiracy against them and open source. I'm more scared of them (in the way you're scared of a rabid dog or a lock-away in an asylum) than I am of Synesis owning my code. I bet I could make you have an "episode" by saying that I believe the GPL is... GASP!! not perfect for everyone. Please don't kill too many people before they get you chained down. Don't get me wrong though - I'm a strong supporter of open source and I've contributed code and other things to many open source projects (Mozilla, IE7, PHP, YaBB/YaBB SE, etc. just to name some of the more prolific ones off the top of my head.) and always release my software under a free license (although not always GPL) - but that doesn't mean I'm a paranoid conspiracy theorist. -[Unknown]Ant, I'm sorry, but why do yuo really care that much? Do you feel that your suggestions in this area are worth - what, $50, $100 dollars? So you're donating them to Synesis. Pah... this is a problem because?its not a problem its a principle.
May 07 2004
Hi Matthew. My coin into can.3. combined approach, in same module+1 Regards.
May 07 2004
Hi Matthew. My coin into can.3. combined approach, in same module+1 Regards.
May 07 2004
Hi Matthew. My coin into can.3. combined approach, in same module+1 Regards.
May 07 2004
3. combined approach, in same moduleI agree with that. Anyhow, I believe it can be made more specific: The core of the concept of classes is, that they encapsulate data. A class that has only static members should really be considered a module instead. Purely object-oriented languages like Java don't have the concept of free functions, so you are forced to create such module-like classes. In D, it should be avoided, unless there is a good reason to do so. So, up to this point we have one rule: use a class interface, if you encapsulate data, use a free-function-interface, if you don't. The remaining question: if you have a class, which functions should be defined inside as members, which ones outside, as external free functions. For this, one can give a simple ruleto start with: any function that has to access private internals of the class should be defined inside the class. (friend access is, of course, possible inside of modules, but should be avoided unless there is good reason to do so) any other functions, that access the class only via its public interface, should be considered to be moved out of the class as free functions. Of course, there are plenty exceptions to these rules, but at least, these are a first guideline to stick to, unless you see a good reason to do it differently.
May 07 2004
On Fri, 7 May 2004 18:31:51 +1000, Matthew wrote:Walter and I are having a little friendly disagreement which is holding up the inclusion of the std.loader module into Phobos. Basically, it goes like this:[SNIP]The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughtsOption 4 (as it can be seen as a superset of option 3). A computer programing language is a toolkit. How the coder uses those tools is their decision. If they choose to use a hammer to drive a screw in, so be it on their heads. But remember that a screwdriver makes a very handy paint-tin opener too. A *major* goal for a general-purpose computer language is to make the act of coding easier for people, according to their needs. The designers of such a language ought to facilitate this goal. -- Derek Melbourne, Australia
May 07 2004
Matthew wrote:3. combined approach, in same module Cheers MatthewMatthew, I like the combined approach. But I have to say that Ant is right. Free software developers would be trapped with the Synesis Licence. This is very annoying to us. In fact, Synesis Licence, AFAIK, is incompatible with some widely used free licences (such as GPL). I know you have the right to maintain your code with your licence, and I fully respect it. The problem is that Phobos is to much tied with Synesis code and it would bring trouble to free software projects that use D. Cheers, Bruno.
May 07 2004
1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the freefunctions)and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestWithout seeing the actual declarations I vote for 1. If there is an obvious "object" mental model then go with 2 - and assuming this module is for loading DLLs and such I don't think an object model works very well. For instance, if I hold onto a reference to a DLL object does it keep the dll loaded in memory? More is less: http://www.amazon.com/exec/obidos/tg/detail/-/0060005688/102-3661341-2044918?v=glance
May 07 2004
"Ben Hinkle" <bhinkle4 juno.com> wrote in message news:c7g4tc$dak$1 digitaldaemon.com...http://www.amazon.com/exec/obidos/tg/detail/-/0060005688/102-3661341-2044918?v=glance It's an interesting dilemma. I like the quote "In sum, this book stretches cause and effect in order to sell books to those who want to avoid responsibility for their own decisions", although only, I suppose, because it suits my position in the current debate. In general I'm for orthogonality. For example, the STLSoft string classes don't follow std::basic_string<> and provide a gazillion kitchen sink methods that can be easily emulated with the standard algorithms. I find it interesting to look at the scripting languages. Perl has many ways of doing things; IMO it's overly complex and arbitrary. Python has just one way of doing each thing; IMO it's a complete doddle to use, and is great. Ruby is kind of halfway between the two; IMO it's the best of the three. Go figure!1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the freefunctions)and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestWithout seeing the actual declarations I vote for 1. If there is an obvious "object" mental model then go with 2 - and assuming this module is for loading DLLs and such I don't think an object model works very well. For instance, if I hold onto a reference to a DLL object does it keep the dll loaded in memory? More is less:
May 07 2004
Matthew wrote:The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughtsThere's something to be said for unity, I think. I say 1 or 2, depending on how OOPy the library wants to be. If every API had two complete implementations, Phobos would quickly snowball into some freaky monstrosity reminiscent of Perl. :) That being said, I don't think the world would come crashing down if both were there, provided that the semantics of one was clearly defined in terms of the other. (ie two interfaces for one API) -- andy
May 07 2004
"Andy Friesen" <andy ikagames.com> wrote in message news:c7g80s$iap$1 digitaldaemon.com...Matthew wrote:functions)The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the freeTo be sure, in most cases I agree. But I think that enforced unity in all cases is against the spirit of C (http://www.comeaucomputing.com/faqs/genfaq.html#betterCgeneral) - which is a good spirit! - and is too reminiscent of the way of Java, which is, IMO, too much of a nannying approach.and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughtsThere's something to be said for unity, I think.If every API had two complete implementations, Phobos would quickly snowball into some freaky monstrosity reminiscent of Perl. :)Absolutely true. I only believe that this joint approach is appropriate in a minority of cases. For example, the std.windows.registry module is entirely class-based, as to do otherwise would be an incredible unusable mess, and little better than using the Win32 Reg* API directly.That being said, I don't think the world would come crashing down if both were there, provided that the semantics of one was clearly defined in terms of the other. (ie two interfaces for one API)For std.loader, the class and free functions share the exact same implementation, except that the former throw exceptions on errors, and the latter return false/null/etc. Hence, there are virtually no additional maintenance considerations. This is, in fact, one of my criteria for determining whether something is suitable for a dual approach. If the combined approach cannot be only, say, 110% or less of the effort of one alone, then I think long and hard about whether the benefits of the freedom of choice is worth the costs of the additional coding/maintenance. It is only such similar modules that I'm advocating for option 3.
May 07 2004
I'm for number 4 !4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class)
May 07 2004
Matthew schrieb:1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestFor this library, probably no. 1, else probably no. 2. There should be *one* obvious way to accomplish a task. -eye
May 07 2004
Matthew wrote:The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestthat's the way things fall. But the combined approach is wrong, IMO - adds uneeded clutter to Phobos. My feeling is that by using free functions, those who really must have a class can roll their own to wrap the free functions, while those who don't can just get on with it.
May 07 2004
I agree, i honestly think the base library needs to be free functions only, then a supllemental library that wraps all the base in OO. Write now its all sorts of mixed up, with seemingly no structure. Maybe its time to start a phobos alternative. C On Sat, 08 May 2004 03:04:18 +0000, mike parker <mike aldacron.com> wrote:Matthew wrote:-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestthat's the way things fall. But the combined approach is wrong, IMO - adds uneeded clutter to Phobos. My feeling is that by using free functions, those who really must have a class can roll their own to wrap the free functions, while those who don't can just get on with it.
May 07 2004
On Fri, 7 May 2004 18:31:51 +1000, "Matthew" <matthew.hat stlsoft.dot.org> wrote:5. Some other combined approach that I've not anticipated. Please suggestI think I'd probably prefer to see the free functions implemented as static methods in the class. Of course, that's a 100% class-based approach, isn't it??? Well...not really. And, I suppose they're not really free functions if they're implemented as static methods inside of a class, are they? Well....kind of. Anyhow, that's what I'd like to see. But, my runner-up vote is for a mixed approach, all in the same module. --Benji Smith
May 07 2004
Benji Smith wrote:I think I'd probably prefer to see the free functions implemented as static methods in the class. Of course, that's a 100% class-based approach, isn't it??? Well...not really.I must say, this is a lovely idea. Unless I'm mistaken, these could be aliased even to have exactly the affect of free functions, am I wrong? -[Unknown]
May 07 2004
"Unknown W. Brackets" <unknown at.simplemachines.dot.org> wrote in message news:c7gnu6$1a03$3 digitaldaemon.com...Benji Smith wrote:In that case, what the user would have is effectively option 3, so I see no effective difference. It is, after all, the user's experience that's largely at issue here. For my part, I don't see any conceptual difference whatsoever between a static method of a class, and a free static function in that class. I have no preference for either, and it would ease the naming issue.I think I'd probably prefer to see the free functions implemented as static methods in the class. Of course, that's a 100% class-based approach, isn't it??? Well...not really.I must say, this is a lovely idea. Unless I'm mistaken, these could be aliased even to have exactly the affect of free functions, am I wrong?
May 07 2004
Matthew wrote:Please let me know your thoughts Cheers MatthewThis is a difficult issue, because it involves both inconsistency and usability. Consider this.... what if printf were a class member? This code: if (number == 0) printf("The number is 0!"); Would then be changed to this in OOP style: if (number == 0) { wannabePrintf printer = new wannabePrintf; printer.data = "The number is 0!"; printer.print(); } (I realize I'm overdoing it a bit, but it's just an example...) Personally, I see this as what I call "OOP overusage". In some cases, I see OOP used just so you can say, "I'm cool because I am using OOP for everything!" But, in some cases this just makes the code more confusing and long.... I see the purpose of OOP to be that of maintainability and abstraction. If functions are strongly linked and have nothing to do with other functions, they should be linked. If, on the other hand, they have only meaning to do with each other, and have no shared variables, and no real reason to be OOP... I don't believe they should be. But then, many will disagree with me. To some, a drawn out example is much more desirable because, well, basically they like OOP. making it so there are too many ways to do things seems like a bad idea. Then again, PHP does it with mysqli - and people like that, and it's not going to make things all that confusing or inconsistent at all. -[Unknown]
May 07 2004
In article <c7gmg4$189a$1 digitaldaemon.com>, Unknown W. Brackets says...if (number == 0) { wannabePrintf printer = new wannabePrintf; printer.data = "The number is 0!"; printer.print(); } (I realize I'm overdoing it a bit, but it's just an example...) Personally, I see this as what I call "OOP overusage". In some cases, I see OOP used just so you can say, "I'm cool because I am using OOP for everything!" But, in some cases this just makes the code more confusing and long....Actually, it would be more like: formatted_output::printf("the number is 0!"); I don't like this ... but it does have the advantage that the only symbol that get dumped into the table is "formatted_output". Remember, OOP is intended to solve "large program" maintainability problems. It's a weapon designed to go after "mega-fauna" programming problems. In a program with 100,000 functions, this is a real boon. If you are doing a lot of output, you could even do this: class mod_printf { static P(int x) {...} static P(double x) {...} static P(char[] x) {...} // Print in hexadecimal static X(int x) {...} // 0x1234 static X(double x) {...} // not used much static X(char[] x) {...} //"\AA \BC" }; foo(int snum, char[] name) { with(mod_printf) { P("Name ");P(name);P(" in hex [");X(name);P("]\n"); } } Now, P() doesn't clutter the symbol table, but you can write concise code when you want to. (A non-static version could do faster, buffered, output.) Kevin
May 07 2004
Kevin Bealer wrote:Actually, it would be more like: formatted_output::printf("the number is 0!");I did say I was overdoing it - an example still.I don't like this ... but it does have the advantage that the only symbol that get dumped into the table is "formatted_output". Remember, OOP is intended to solve "large program" maintainability problems. It's a weapon designed to go after "mega-fauna" programming problems. In a program with 100,000 functions, this is a real boon.Yes, but you still have formatted_output in the sumbol table. Before you had printf. Big difference. Yes, in many cases using classes can clean stuff up when you're too, frankly, lazy to establish a clean naming convention. And again, classes have most certainly their place, but using them for no reason is like buying a new truck to transport a single piece of paper.If you are doing a lot of output, you could even do this: class mod_printf { static P(int x) {...} static P(double x) {...} static P(char[] x) {...} // Print in hexadecimal static X(int x) {...} // 0x1234 static X(double x) {...} // not used much static X(char[] x) {...} //"\AA \BC" }; foo(int snum, char[] name) { with(mod_printf) { P("Name ");P(name);P(" in hex [");X(name);P("]\n"); } } Now, P() doesn't clutter the symbol table, but you can write concise code when you want to. (A non-static version could do faster, buffered, output.)Perhaps so, but this only makes for more confusing code. Which reads easier? with (mod_printf) { P("some text.\n"); P("more test.\n"); P("even more."); } Or... printf("some text.\n"); printf("more test.\n"); printf("even more."); While the hexadecimal functionality is a nice feature, classes can introduce unneccessary complication into simple things. Basically, I agree with Walter's opinion on this. (news://news.digitalmars.com:119/c7gqop$1eoi$1 digitaldaemon.com) The difference for me is that I've always seen OOP as a method to address issues that are caused by deeper problems anyway. But I'm not arguing OOP here, just saying that there are clean reasons for using either. -[Unknown]
May 07 2004
In article <c7gvgv$1log$1 digitaldaemon.com>, Unknown W. Brackets says...Yes, but you still have formatted_output in the sumbol table. Before you had printf. Big difference.Well, printf, sprintf, snprintf, vsprintf, puts, etc.Yes, in many cases using classes can clean stuff up when you're too, frankly, lazy to establish a clean naming convention. And again, classes have most certainly their place, but using them for no reason is like buying a new truck to transport a single piece of paper..The difference for me is that I've always seen OOP as a method to address issues that are caused by deeper problems anyway. But I'm not arguing OOP here, just saying that there are clean reasons for using either. -[Unknown]I agree - putting all those in one object, which contains no state, is not all that great. You can solve the problem better with modules or some other namespace like mechanism, etc. But if all a language has is classes, they get used as modules and namespaces and delegates (ie operator() in C++), and a hundred other things. It's important to solve the namespace crowding problem, but most of the techniques will look similar: provide a grouping mechanism (classes with no non-static methods, or modules, or namespaces), then provide a "uses" mechanism so they don't have to type the wrapper name. Kevin
May 09 2004
Kevin Bealer wrote:It's important to solve the namespace crowding problem, but most of the techniques will look similar: provide a grouping mechanism (classes with no non-static methods, or modules, or namespaces), then provide a "uses" mechanism so they don't have to type the wrapper name. KevinI've always thought of this as a possible function for with. That's basically how it's used in JavaScript, and it does make some amount of sense - assuming your class names, namespaces, and variable names are all separate. Then you could also change it to something like: with (varName): Just like with version, etc. I like it better, personally, than the way .NET/etc. handles it where, at least to my recollection, you import namespaces per-file or something. (okay, again, I don't really like OOP generally so I may not be remembering properly.) But this could get ugly... so I'm not going to argue for or against this syntax either. But, yes, I agree with what you said entirely. -[Unknown]
May 11 2004
The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestMy vote is for 2, with some suggestions to make free functions work (option 5) My $0.02: A class-only loader can still be made to work with 'free function' dll's, if the dll is simply thought to expose a reference to a 'default' interface of static functions alongside anything else that std.loader wants to add for D classes. It would be good design since the functions are grouped as a unit, as they exist in the library, yet still maintains compatibility with existing dll/dso's. This also avoids duplication of effort when writing an application that may need to use a multitude of different libraries with the same interface: its code you'd have to write anyway. Also, its the most straight-forward approach since everything is grouped in one place, under a single architecture.
May 07 2004
Unfortunately, because Walter and I've been arguing about the implementation of this, it may have been misunderstood by the community. *All* it is is a platform-independent layer over LoadLibrary/GetProcAddress (Win32) / dlopen/dlsym (Linux). There is certainly a need for a class loader that builds upon this basic module, and I'd be happy to participate in that with others later on, but that's not what's addressed in this module. "Eric Anderton" <ericanderton at yahoo dot comEric_member pathlink.com> wrote in message news:c7gn61$1969$1 digitaldaemon.com...theThe options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestMy vote is for 2, with some suggestions to make free functions work (option 5) My $0.02: A class-only loader can still be made to work with 'free function' dll's, ifdll is simply thought to expose a reference to a 'default' interface of static functions alongside anything else that std.loader wants to add for D classes. It would be good design since the functions are grouped as a unit, as theyexistin the library, yet still maintains compatibility with existing dll/dso's.Thisalso avoids duplication of effort when writing an application that may need to use a multitude of different libraries with the same interface: its code you'd have to write anyway. Also, its the most straight-forward approach since everything is grouped in one place, under a single architecture.
May 07 2004
On Sat, 8 May 2004 07:23:57 +1000, "Matthew" <matthew.hat stlsoft.dot.org> wrote:Unfortunately, because Walter and I've been arguing about the implementation of this, it may have been misunderstood by the community. *All* it is is a platform-independent layer over LoadLibrary/GetProcAddress (Win32) / dlopen/dlsym (Linux).Why ? as I see it (an I may be wrong) Walter is no great fan of extra wrapper for the sake of crossplatform dev when a version(The_OS_I_use) will do. for loading a lib we have the OS dependant operations the ideal approad is to have; alias OS_HANDLE SharedLibHandle; SharedLibHandle loadExtLibrary( TCHAR[] name ); // no '.dll/.so' searches LD_LBRARY_PATH/PATH (os depandant) SharedLibHandle loadExtLibrary( TCHAR[] name, TCHAR[] path ); // no '.dll/.so' just looks in path for the library if you want os dependancy use the OS call! void * getSymbolName( SharedLibHandle lib, TCHAR[] name ); all in a module say vosi (virtual OS interface) every thing else can the use that interface to allow say template loader(T) { T getSymbol( TCHAR[] name, SharedLibHandle lib ) { void * rv = getSymbolname( lib, name ); if ( !rv) throw new NoSuchSymbolException( name ); return cast(T)rv; } T getSymbol(TCHAR[] name, TCHAR[] libname ) { SharedLibHandle lib = loadExtLibrary( libname ); if ( !lib ) throw new NoSuchLibrary( libname ); return getSymbol( lib, name ); } T getSymbol(TCHAR[] name, TCHAR[] libname, TCHAR[] path ) { SharedLibHandle lib = loadExtLibrary( libname, path); if ( !lib ) throw new NoSuchLibrary( libname ); return getSymbol( lib, name ); } }There is certainly a need for a class loader that builds upon this basic module, and I'd be happy to participate in that with others later on, but that's not what's addressed in this module.now what you want to do with elaborate classes etc is up to you 90% of the uses of dll/so's has been covered above, you will notice that I've not added any calls to unload the libraries, this is simply because without extensive interaction with the GC and/or overloaded return type that behave as proxy items, you can not determine which loaded libraries are still referenced, so load and keep until the process exits and the OS should (will) cleanup for you. Kiss Mike.
May 07 2004
"Mike Wynn" <one_mad_alien hotmail.com> wrote in message news:lm4o90h50rojbn6tjh7rh2ns49pf2b80hj 4ax.com...On Sat, 8 May 2004 07:23:57 +1000, "Matthew" <matthew.hat stlsoft.dot.org> wrote:ofUnfortunately, because Walter and I've been arguing about the implementationAre you arguing for you, or for Walter?this, it may have been misunderstood by the community. *All* it is is a platform-independent layer over LoadLibrary/GetProcAddress (Win32) / dlopen/dlsym (Linux).Why ? as I see it (an I may be wrong) Walter is no great fan of extra wrapper for the sake of crossplatform dev when a version(The_OS_I_use) will do.for loading a lib we have the OS dependant operations the ideal approad is to have; alias OS_HANDLE SharedLibHandle; SharedLibHandle loadExtLibrary( TCHAR[] name ); // no '.dll/.so' searches LD_LBRARY_PATH/PATH (os depandant) SharedLibHandle loadExtLibrary( TCHAR[] name, TCHAR[] path ); // no '.dll/.so' just looks in path for the library if you want os dependancy use the OS call! void * getSymbolName( SharedLibHandle lib, TCHAR[] name ); all in a module say vosi (virtual OS interface) every thing else can the use that interface to allow say template loader(T) { T getSymbol( TCHAR[] name, SharedLibHandle lib ) { void * rv = getSymbolname( lib, name ); if ( !rv) throw new NoSuchSymbolException( name ); return cast(T)rv; } T getSymbol(TCHAR[] name, TCHAR[] libname ) { SharedLibHandle lib = loadExtLibrary( libname ); if ( !lib ) throw new NoSuchLibrary( libname ); return getSymbol( lib, name ); } T getSymbol(TCHAR[] name, TCHAR[] libname, TCHAR[] path ) { SharedLibHandle lib = loadExtLibrary( libname, path); if ( !lib ) throw new NoSuchLibrary( libname ); return getSymbol( lib, name ); } }module,There is certainly a need for a class loader that builds upon this basicI'm sorry, maybe it's me? - I just turned over another year yesterday - but this is just so far beyond anything that I can consider sensible, that I don't see how I can even address your perspective. So I give up. Perhaps it's time for a DSLG?and I'd be happy to participate in that with others later on, but that's not what's addressed in this module.now what you want to do with elaborate classes etc is up to you 90% of the uses of dll/so's has been covered above, you will notice that I've not added any calls to unload the libraries, this is simply because without extensive interaction with the GC and/or overloaded return type that behave as proxy items, you can not determine which loaded libraries are still referenced, so load and keep until the process exits and the OS should (will) cleanup for you. Kiss
May 07 2004
On Sat, 8 May 2004 11:12:23 +1000, "Matthew" <matthew.hat stlsoft.dot.org> wrote:"Mike Wynn" <one_mad_alien hotmail.com> wrote in message news:lm4o90h50rojbn6tjh7rh2ns49pf2b80hj 4ax.com...neither, I'm asking you why the need for a cross platform LoadLibrary/GetProcAddress wrapper when there is version(Linux) etc or you can implement the linux dlopen/dlsym with the win32 API or win32 API with dlopen/dlsym.On Sat, 8 May 2004 07:23:57 +1000, "Matthew" <matthew.hat stlsoft.dot.org> wrote:ofUnfortunately, because Walter and I've been arguing about the implementationAre you arguing for you, or for Walter?this, it may have been misunderstood by the community. *All* it is is a platform-independent layer over LoadLibrary/GetProcAddress (Win32) / dlopen/dlsym (Linux).Why ? as I see it (an I may be wrong) Walter is no great fan of extra wrapper for the sake of crossplatform dev when a version(The_OS_I_use) will do.why ? 90% of the times I've used a dll I want to load it, get symbols and use it for the life time of the app, the only time I've every considered unloading a dll was to have upgrade whilst live functionality. what can be simpler than extern (C) { alias int function(int, int) myfunc; } myfunc getPlugin() { return loader( myfunc ).getSymbol( "myfunction", "mydll" ); } main () { //call what ever or myfunc func = getPlugin(); return func( 3, 2 ); } as opposed to extern (C) { alias int function(int, int) myfunc; } myfunc getPlugin(ExeModule mylib ) { return loader( myfunc ).getSymbol( "myfunction", "mydll" ); } main() { auto ExeModule mylib = new ExeModule( "mydll.dll" ); // call what every passing mylib if needed myfunc func = cast(myfunc)mylib.getSymbol( "myfunction" ); } in loader.d I can see a module info classes, but the ref count appears to be module static, and unused by ExeModule, a simple struct ModInfo { HModule lib; int refcount } // where HModule is an OS dependant alias. ModInfo[char[]] loadedlibs; would do (wouldn't it?) to just cache the handles of loaded libs. plz explain why this is beyond what you would consider sencible. Mike.for loading a lib we have the OS dependant operations the ideal approad is to have; alias OS_HANDLE SharedLibHandle; SharedLibHandle loadExtLibrary( TCHAR[] name ); // no '.dll/.so' searches LD_LBRARY_PATH/PATH (os depandant) SharedLibHandle loadExtLibrary( TCHAR[] name, TCHAR[] path ); // no '.dll/.so' just looks in path for the library if you want os dependancy use the OS call! void * getSymbolName( SharedLibHandle lib, TCHAR[] name ); all in a module say vosi (virtual OS interface) every thing else can the use that interface to allow say template loader(T) { T getSymbol( TCHAR[] name, SharedLibHandle lib ) { void * rv = getSymbolname( lib, name ); if ( !rv) throw new NoSuchSymbolException( name ); return cast(T)rv; } T getSymbol(TCHAR[] name, TCHAR[] libname ) { SharedLibHandle lib = loadExtLibrary( libname ); if ( !lib ) throw new NoSuchLibrary( libname ); return getSymbol( lib, name ); } T getSymbol(TCHAR[] name, TCHAR[] libname, TCHAR[] path ) { SharedLibHandle lib = loadExtLibrary( libname, path); if ( !lib ) throw new NoSuchLibrary( libname ); return getSymbol( lib, name ); } }I'm sorry, maybe it's me? - I just turned over another year yesterday - but this is just so far beyond anything that I can consider sensible, that I don't see how I can even address your perspective. So I give up. Perhaps it's time for a DSLG?
May 08 2004
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c7fhhj$2gtc$1 digitaldaemon.com...Walter believes that every module should have a single, unambiguous API.Yes.He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things.I feel that a class should be used where there is some 'state' to be set and preserved across the function calls, and that free functions should be used when the functionality is stateless. For example, std.regexp has state, and so is a class. std.file functions are all atomic, and so is a collection of free functions. State is a problem that classes are an ideal solution for. Otherwise, your free functions wind up needing state pointers (i.e. 'this' for classes), and organizational control over the construction, destruction, invariants, resource management and exception safety is lost. Furthermore, if the state consists of static data, the free function must also deal with thread safety and synchronization of it. I don't agree with the "everything must be in a class" approach, either, as a function that tests to see if a file exists is atomic and has no state. Why instantiate a class for it? There's a place for both free functions and classes, but I strongly disagree with Matthew's point of view that each module should provide both to access the same functionality. I disagree because: 1) either the free function or the class version is going to be an unfortunate kludge, for the aforementioned reasons. 2) dual interfaces mean double the documentation. 3) dual interfaces mean double the bugs. 4) dual interfaces mean twice as much code to maintain. 5) dual interfaces leads the programmer to wonder why there are two and which he should use. He's got twice as much to learn, for no incremental utility. 6) library bloat. (Matthew points out that 3 and 4 may be mitigated by having the two versions be shells over a lower layer that does the implementation. I counter with another layer being just another source of bugs <g>.)
May 07 2004
On Fri, 7 May 2004 12:46:46 -0700, Walter wrote:"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c7fhhj$2gtc$1 digitaldaemon.com...So do I. The opposite is multiple, ambiguous APIs.Walter believes that every module should have a single, unambiguous API.Yes.As I was getting ready for bed last night, I was thinking exactly the same thing as this. In fact, the 'state' issue is probably the basis I would use for deciding if a class or free functions would be needed.He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things.I feel that a class should be used where there is some 'state' to be set and preserved across the function calls, and that free functions should be used when the functionality is stateless. For example, std.regexp has state, and so is a class. std.file functions are all atomic, and so is a collection of free functions. State is a problem that classes are an ideal solution for. Otherwise, your free functions wind up needing state pointers (i.e. 'this' for classes), and organizational control over the construction, destruction, invariants, resource management and exception safety is lost. Furthermore, if the state consists of static data, the free function must also deal with thread safety and synchronization of it. I don't agree with the "everything must be in a class" approach, either, as a function that tests to see if a file exists is atomic and has no state. Why instantiate a class for it?There's a place for both free functions and classes, but I strongly disagree with Matthew's point of view that each module should provide both to access the same functionality. I disagree because:It seems that I totally misunderstood Matthew's approach. I agree with Walter here. Functionality should be provided in either free functions *or* a class, but not both. If a set of functionality is provided in one form, but the coder wishes to use the other form, she can write a new module that 'wraps' the supplied form to convert it's interface. -- Derek Melbourne, Australia
May 07 2004
Derek wrote:It seems that I totally misunderstood Matthew's approach. I agree with Walter here. Functionality should be provided in either free functions *or* a class, but not both. If a set of functionality is provided in one form, but the coder wishes to use the other form, she can write a new module that 'wraps' the supplied form to convert it's interface.Although if there's enough people who want to do this, it's going to be a lot more error-prone to have everyone roll their own versus having one maintained API. Chris
May 11 2004
"Walter" <newshound digitalmars.com> wrote in message news:c7gqop$1eoi$1 digitaldaemon.com..."Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c7fhhj$2gtc$1 digitaldaemon.com...I don't have a problem with any of that, but I am also a pragmatist, and sometimes the world's not that neat. And in any case, it does not help the issue of the unwelcome exceptions. This absolutist approach mandates that if I only want to "test" something that has only class access, and only use it if it exists, I am constrained to have to deal with exceptions, which, in certain application contexts, are not appropriate. The main reason I wrote this loader was that I wanted to combine it with the std.recls and std.windows.registry modules, and have a great example of succinctness in a useful COM server search and inspection tool. Such a tool would naturally want to be able to use the test-and-use approach, and is (or would have been) the exemplar of my argument.Walter believes that every module should have a single, unambiguous API.Yes.He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things.I feel that a class should be used where there is some 'state' to be set and preserved across the function calls, and that free functions should be used when the functionality is stateless. For example, std.regexp has state, and so is a class. std.file functions are all atomic, and so is a collection of free functions. State is a problem that classes are an ideal solution for. Otherwise, your free functions wind up needing state pointers (i.e. 'this' for classes), and organizational control over the construction, destruction, invariants, resource management and exception safety is lost. Furthermore, if the state consists of static data, the free function must also deal with thread safety and synchronization of it.I don't agree with the "everything must be in a class" approach, either, as a function that tests to see if a file exists is atomic and has no state. Why instantiate a class for it? There's a place for both free functions and classes, but I strongly disagree with Matthew's point of view that each module should provide both to access the same functionality. I disagree because:That's just a self-serving misrepresentation of my views. I do *not* believe that each module should provide both. I believe some some - and judging on the number I've contributed thus far, a small minority - should. That's all.1) either the free function or the class version is going to be an unfortunate kludge, for the aforementioned reasons.Not so.2) dual interfaces mean double the documentation.Again, a convenient misrepresentation. Why is it double? How have you arrived at that quantification? It is certainly >1, but that is *all* you can assert.3) dual interfaces mean double the bugs.As per point 2)4) dual interfaces mean twice as much code to maintain.Utter, utter rubbish. The module.d code that you have, and which has sparked this debate, is concrete disproof of that statement.5) dual interfaces leads the programmer to wonder why there are two and which he should use. He's got twice as much to learn, for no incremental utility.There is merit in this, to be sure. But the ultimate realisation of that argument is Java. Do you want to go there? If you don't, then there have to be some cases in which there is merit in having both options available. It may be that loader.d is not that case, but I was interested in starting this thread in the general principle rather than that specific case.6) library bloat.There certainly is a small amout of bloat. But it's not 200%. Again, it's a case of balancing the tradeoffs. Consider the free functions in loader.d. The totality of the "bloat" is the following (which is 60 / 650 lines of loader.d; that's an extra 9%): public HXModule ExeModule_Load(in char[] moduleName) { return ExeModule_Load_(moduleName, false); } public HXModule ExeModule_AddRef(in HXModule hModule) { return ExeModule_AddRef_(hModule, false); } public void ExeModule_Release(inout HXModule hModule) { ExeModule_Release_(hModule, false); } public void *ExeModule_GetSymbol(inout HXModule hModule, in char[] symbolName) { return ExeModule_GetSymbol_(hModule, symbolName, false); } public char[] ExeModule_Error() { return ExeModule_Error_(); } public char[] ExeModule_GetPath(HXModule hModule) { return ExeModule_GetPath_(hModule, false); }(Matthew points out that 3 and 4 may be mitigated by having the two versions be shells over a lower layer that does the implementation. I counter with another layer being just another source of bugs <g>.)I certainly do. Again, the implementation of the class in my later version of loader.d is far simpler than the changes that you made to the original. If I'm wrong, please show me. ... Anyway, as I've mentioned in an earlier post, I've already caved to Walter on this, purely in order to get loader.d available. It just means that to use it in the way I want, I've now got to write my own free functions which will wrap the API, e.g. HXModule MyExeModule_Load(in char[] moduleName) { try { ExeModule module = new ExeModule(moduleName); return module.handle; } catch(ExeModuleException) { return null; } } In fact - <sickening realisation>arrgh!</sickening realisation> - I can't do that, because the ExeModule instance owns the loaded module, and when it gets GC'd, the module will be freed, leaving me holding a handle to nothing. The alternative it to provide a detach() method for ExeModule, but then that just encourages mixing programming modes for a given component, something I do *not* advocate . Oh man, this sucks hard. I guess I won' be using the Phobos module that I've contributed to Phobos. How's that for code bloat irony? :(
May 07 2004
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c7hbu7$27ja$1 digitaldaemon.com...It just means that to use it in the way I want, I've now got to write myown freefunctions which will wrap the API, e.g. HXModule MyExeModule_Load(in char[] moduleName) { try { ExeModule module = new ExeModule(moduleName); return module.handle; } catch(ExeModuleException) { return null; } } In fact - <sickening realisation>arrgh!</sickening realisation> - I can'tdothat, because the ExeModule instance owns the loaded module, and when itgetsGC'd, the module will be freed, leaving me holding a handle to nothing.One solution for this is to make the ExeModule object the handle: typedef ExeModule HXModule; and the GC won't free up the module until there are no more HXModule's. HXModule is an opaque type anyway.
May 07 2004
On Sat, 8 May 2004 11:08:26 +1000, Matthew <matthew.hat stlsoft.dot.org> wrote:It just means that to use it in the way I want, I've now got to write my own free functions which will wrap the API, e.g. HXModule MyExeModule_Load(in char[] moduleName) { try { ExeModule module = new ExeModule(moduleName); return module.handle; } catch(ExeModuleException) { return null; } } In fact - <sickening realisation>arrgh!</sickening realisation> - I can't do that, because the ExeModule instance owns the loaded module, and when it gets GC'd, the module will be freed, leaving me holding a handle to nothing. The alternative it to provide a detach() method for ExeModule, but then that just encourages mixing programming modes for a given component, something I do *not* advocate . Oh man, this sucks hard. I guess I won' be using the Phobos module that I've contributed to Phobos. How's that for code bloat irony? :(Have you considered the 'singleton' approach for your alternate API, eg. ExeModule m; HXModule MyExeModule_Load(in char[] moduleName) { if(m is null) { try { m = new ExeModule(moduleName); } catch (ExeModuleException) { return null; } } return m->handle; } (I'm new to D so the above syntax may not be correct, by the idea is the important part) I know there are threading issues with the singleton approach. But it appears to me a module load *is* a singleton, you only need one per execution. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 09 2004
Walter wrote:"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c7fhhj$2gtc$1 digitaldaemon.com...This sounds reasonable. I assumed from Mathews original post that he wasn't duplicating functionality. - Sometimes duplication can be useful, if it makes something easier. That's why we have alias right? - Other times it just makes readability much harder. -- -Anderson: http://badmama.com.au/~anderson/Walter believes that every module should have a single, unambiguous API.Yes.He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things.I feel that a class should be used where there is some 'state' to be set and preserved across the function calls, and that free functions should be used when the functionality is stateless. For example, std.regexp has state, and so is a class. std.file functions are all atomic, and so is a collection of free functions. State is a problem that classes are an ideal solution for. Otherwise, your free functions wind up needing state pointers (i.e. 'this' for classes), and organizational control over the construction, destruction, invariants, resource management and exception safety is lost. Furthermore, if the state consists of static data, the free function must also deal with thread safety and synchronization of it. I don't agree with the "everything must be in a class" approach, either, as a function that tests to see if a file exists is atomic and has no state. Why instantiate a class for it? There's a place for both free functions and classes, but I strongly disagree with Matthew's point of view that each module should provide both to access the same functionality. I disagree because: 1) either the free function or the class version is going to be an unfortunate kludge, for the aforementioned reasons. 2) dual interfaces mean double the documentation. 3) dual interfaces mean double the bugs. 4) dual interfaces mean twice as much code to maintain. 5) dual interfaces leads the programmer to wonder why there are two and which he should use. He's got twice as much to learn, for no incremental utility. 6) library bloat. (Matthew points out that 3 and 4 may be mitigated by having the two versions be shells over a lower layer that does the implementation. I counter with another layer being just another source of bugs <g>.)
May 07 2004
<tangent> Actually, in an object oriented system that truely models the computer, the isFile method would be a function of some sort of filesystem object. There is really no suck thing as a truely atomic function, however, in being practical, one must sacrifice true modeling at times. </tangent> Perhaps I should change my handle to "thePurist" Walter wrote:I don't agree with the "everything must be in a class" approach, either, as a function that tests to see if a file exists is atomic and has no state. Why instantiate a class for it?
May 12 2004
The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestExactly how many functions are we talking about? Are there complex interaction patterns, or is it simply 'loadModule( string )'? If it's really trivial to write a wrapper class I'd go for 1, and perhaps make a 'wrappers' module which contains helper classes for those who feel they cannot do without (so essentially that's your option 4, but not in std.c.loader.d but rather std.wrappers) A class based approach would make most sense when there's a context needed to store some data while invoking different methods from the API. A class with only static methods makes less sense to me, since you already have a mechanism (the module) to group related functionality, using a class for that purpose seems wrong
May 07 2004
The basic API is typedef void *HXModule; public HXModule ExeModule_Load(in char[] moduleName); public HXModule ExeModule_AddRef(in HXModule hModule); public void ExeModule_Release(inout HXModule hModule); public void *ExeModule_GetSymbol(inout HXModule hModule, in char[] symbolName); public char[] ExeModule_Error(); public char[] ExeModule_GetPath(HXModule hModule); It performs the following: a. It provides a platform-independent view of dynamic loading b. It provides a platform-independent module reference-counting c. It provides thread-specific error information d. It allows the user to query the module path from a module handle The class looks like: public auto class ExeModule { /// \name Construction public: this(in HXModule hModule, boolean bTakeOwnership) this(char[] moduleName) ~this() /// \name Operations public: void close() /// \name Accessors public: void *getSymbol(in char[] symbolName) void *findSymbol(in char[] symbolName) /// \name Properties public: HXModule handle() char[] path() } It performs two services over this API: a. It provides RAII over the loaded module, by being auto. This is, of course, a very important thing, and why I would never advocate option 1 myself b. It throws exceptions in the ctor if the given module cannot be loaded The class is implemented in terms of the same underlying functions as the free functions, just that the former throw the ExeModuleException, and the latter do not. Anyway, I've caved to Walter's immovability, so we'll be getting option 2 only in the next release of Phobos. Apologies to those of you who liked 1, 3 & 4. ;( "Jeroen van Bemmel" <someone somewhere.com> wrote in message news:c7gv1m$1l1c$1 digitaldaemon.com...The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggestExactly how many functions are we talking about? Are there complex interaction patterns, or is it simply 'loadModule( string )'? If it's really trivial to write a wrapper class I'd go for 1, and perhaps make a 'wrappers' module which contains helper classes for those who feel they cannot do without (so essentially that's your option 4, but not in std.c.loader.d but rather std.wrappers) A class based approach would make most sense when there's a context needed to store some data while invoking different methods from the API. A class with only static methods makes less sense to me, since you already have a mechanism (the module) to group related functionality, using a class for that purpose seems wrong
May 07 2004
I've talked about this some in other posts, but I'm of the opinion that we need to have SEPARATE free- function and class libraries. Then people who want to write in a C-like style can just link against the one they prefer without having to add in the weight of the class library, and vice-versa. As I've said before, I think D attempts to aggregate 3 different programming styles: pure C, C++, and Pure-C programmers want a free-function LIBC equivalent. This is what I think Phobos should be. C++ programmers want an STL equivalent. This is what the DTL hopefully will be. separate but still standardly distributed library. Perhaps we can have three standard libraries: Phobos (free-function), Deimos (class library), and DTL. Owen In article <c7fhhj$2gtc$1 digitaldaemon.com>, Matthew says...Walter and I are having a little friendly disagreement which is holding up the inclusion of the std.loader module into Phobos. Basically, it goes like this: Walter believes that every module should have a single, unambiguous API. He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things. I believe that what Walter believes is a good thing, except for the fact that I see that it limits the choices of developers. Some people want to use free functions, others a class-based approach, others to mix and match as they deem appropriate. (I'm in the last camp.) I don't ascribe to the free function-only approach because object-orientation has a lot going for it. If people want that exclusively, then C is the language for them, methinks. I don't ascribe to the class-only model for the converse reasons - i.e. sometimes free functions are more convenient/appropriate - in general, and for the specific reason that I don't believe that exceptions represent the "one true error-handling mechanism", and I don't want to be forced to use them when _I_ deem that it's not appropriate to my requirements. Sometimes I want to write small utilities and simply get a success/rail result from a function. I certainly want this facility with std.loader, as I plan to write version/COM-server trawling utilities and I don't see it as appropriate to be using exceptions (since exceptions are for exceptional circumstances, not for testing things, IMO at least). Hence, the way I've written loader.d (and some other modules), is that there is a free function API, and a thin class (+ exceptions) wrapper over that API. This affords the flexibility to suit all tastes. I won't bang on about the advantages of this approach further, as those that agree already agree, and it's my experience that those who want only a class-only approach cannot be persuaded to look at the virtues of the other side. (Walter asserts that the dual approach makes the code harder to maintain. I assert the contrary. After much debate, we're both still seeing it our own way. Must be one of those things, I guess ...) What I'm interested in is getting a feeling for the general level of support for the following options. Before I enumerate those options, let me make it clear that I don't believe this approach is valid for all modules, far from it. The std.windows.registry, std.mmfile and the std.perf (not yet included) modules are entirely class-based. The std.recls module has both, and I have written std.loader as both. It is this latter that is the sticking point, as Walter does not want to release it in such a guise. The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughts Cheers Matthew
May 07 2004
I've talked about this some in other posts, but I'm of the opinion that we need to have SEPARATE free- function and class libraries. Then people who want to write in a C-like style can just link against the one they prefer without having to add in the weight of the class library, and vice-versa. As I've said before, I think D attempts to aggregate 3 different programming styles: pure C, C++, and Pure-C programmers want a free-function LIBC equivalent. This is what I think Phobos should be. C++ programmers want an STL equivalent. This is what the DTL hopefully willbe.aseparate but still standardly distributed library. Perhaps we can have three standard libraries: Phobos (free-function), Deimos (class library), and DTL.It's an interesting point that you make. I also find it interesting that the only issues on which Walter and I've experienced any serious divergence - apart from switch/default - has been on these borders between C/C++ & D and the analogous free-functions & classes. I'm not sure what to make of that at the moment, but I think it's worth some consideration. Anyway, to your point. As I demonstrate in <shameless plug>"Imperfect C++" - coming out in Sept/Oct</shameless plug> - C++ is a very poor module interface language (in fact I reckon it is a complete dead duck at that), but the best module implementation language. Hence, I only ever write dynamic libs with C-APIs. (Of course, that's not to say that I do not pass C++ objects around between such modules. In fact, in "IC++" I demonstrate a fully compiler-independent mechanism for doing just that.) So my approach in C/C++ is always to separate things into layers, somewhat akin to the breakdown you describe. Therefore, I am instincively drawn to your idea, or at least the aspects that pertain to a separation of free-function APIs and the classes that wrap them (or provide an alternate implementation to them). However, D has managed to jettison some of the problems of C++, in regards to modules. For example, D's static initialisation ordering is order-deterministic, and cyclics are banned. This answers one of C++'s big imperfections. (Yes, I also address this in "IC++", with an amusingly anachronistic solution.) So, I think those of us to whom such an approach provides appeal need to be a bit circumspect about such a notion, as it may not be necessary. There may also be practical problems. For example, let's assume that loader.d used the free-function API. It uses TSS (Thread Specific Storage) internally in order to be able to provide a thread-specific error information for failures. The problem with that is that if, say, on Win32, the TLS initialisation function TlsAlloc() fails - which is perfectly possible on some older Win OSs, which had quite tight limits on the number of slots - it needs to throw an exception. But the exception is a class, so there we have the rub. Even free func APIs can depend on classes. Anyway, as to the rest of your idea. I like the idea of a separate Deimos class lib, because many people would not need its contents. It would also mean that it could contain a wider spread of components than would be acceptable in the core library. As for DTL, I would not have a problem with it being a separate library, but I suspect that will not be desirable to the vast majority of D users. I also think it will not really be necessary: it's not going to be very big. It's worth noting that DTL is being designed to also accomodate Java/.NET style collections, without sacrificing efficiency for users who will be following the STL / freaching models of enumeration. Anyway, Deimos and the putative separate DTL would both depend on Phobos. Just my thoughts.Owen In article <c7fhhj$2gtc$1 digitaldaemon.com>, Matthew says...IWalter and I are having a little friendly disagreement which is holding up the inclusion of the std.loader module into Phobos. Basically, it goes like this: Walter believes that every module should have a single, unambiguous API. He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things. I believe that what Walter believes is a good thing, except for the fact thathassee that it limits the choices of developers. Some people want to use free functions, others a class-based approach, others to mix and match as they deem appropriate. (I'm in the last camp.) I don't ascribe to the free function-only approach because object-orientationfora lot going for it. If people want that exclusively, then C is the languagesometimesthem, methinks. I don't ascribe to the class-only model for the converse reasons - i.e.specificfree functions are more convenient/appropriate - in general, and for thecertainlyreason that I don't believe that exceptions represent the "one true error-handling mechanism", and I don't want to be forced to use them when _I_ deem that it's not appropriate to my requirements. Sometimes I want to write small utilities and simply get a success/rail result from a function. IIMOwant this facility with std.loader, as I plan to write version/COM-server trawling utilities and I don't see it as appropriate to be using exceptions (since exceptions are for exceptional circumstances, not for testing things,is aat least). Hence, the way I've written loader.d (and some other modules), is that thereclass-onlyfree function API, and a thin class (+ exceptions) wrapper over that API. This affords the flexibility to suit all tastes. I won't bang on about the advantages of this approach further, as those that agree already agree, and it's my experience that those who want only aoneapproach cannot be persuaded to look at the virtues of the other side. (Walter asserts that the dual approach makes the code harder to maintain. I assert the contrary. After much debate, we're both still seeing it our own way. Must beforof those things, I guess ...) What I'm interested in is getting a feeling for the general level of supportthisthe following options. Before I enumerate those options, let me make it clear that I don't believeclass-based.approach is valid for all modules, far from it. The std.windows.registry, std.mmfile and the std.perf (not yet included) modules are entirelythisThe std.recls module has both, and I have written std.loader as both. It issuchlatter that is the sticking point, as Walter does not want to release it ina guise. The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughts Cheers Matthew
May 07 2004
Matthew wrote:it will not really be necessary: it's not going to be very big. It's worth noting that DTL is being designed to also accomodate Java/.NET style collections, without sacrificing efficiency for users who will be following the STL / freaching models of enumeration.If you're speaking of supporting something like: Iterator it = myCollection.iterator(); while(it.hasNext()) { MyObject o = (MyObject)iterator.next(); } I'd say hang it. I've been using Java for quite some time, and I'm not in the minority when I say that syntax stinks. Having used the new 1.5 foreach syntax: for(MyObject o : myCollection) { } ... and after many discussions with other Java types, I believe you won't be hurting anyone's feelings by leaving it out.
May 08 2004
On Sat, 8 May 2004 12:51:55 +1000, "Matthew" <matthew.hat stlsoft.dot.org> wrote:For example, D's static initialisation ordering is order-deterministic, and cyclics are banned.can you post some code that shows this, as from my experiance (see bug posting about static initialisers within templated classes ) the order is not as you would expect (even order of declaration would be enough) Mike.
May 08 2004
Matthew wrote:Walter and I are having a little friendly disagreement which is holding up the inclusion of the std.loader module into Phobos. Basically, it goes like this: Walter believes that every module should have a single, unambiguous API. He is happy for that to be either free functions, or classes, although he would probably admit to a preference for classes for most things. I believe that what Walter believes is a good thing, except for the fact that I see that it limits the choices of developers. Some people want to use free functions, others a class-based approach, others to mix and match as they deem appropriate. (I'm in the last camp.) I don't ascribe to the free function-only approach because object-orientation has a lot going for it. If people want that exclusively, then C is the language for them, methinks. I don't ascribe to the class-only model for the converse reasons - i.e. sometimes free functions are more convenient/appropriate - in general, and for the specific reason that I don't believe that exceptions represent the "one true error-handling mechanism", and I don't want to be forced to use them when _I_ deem that it's not appropriate to my requirements. Sometimes I want to write small utilities and simply get a success/rail result from a function. I certainly want this facility with std.loader, as I plan to write version/COM-server trawling utilities and I don't see it as appropriate to be using exceptions (since exceptions are for exceptional circumstances, not for testing things, IMO at least). Hence, the way I've written loader.d (and some other modules), is that there is a free function API, and a thin class (+ exceptions) wrapper over that API. This affords the flexibility to suit all tastes. I won't bang on about the advantages of this approach further, as those that agree already agree, and it's my experience that those who want only a class-only approach cannot be persuaded to look at the virtues of the other side. (Walter asserts that the dual approach makes the code harder to maintain. I assert the contrary. After much debate, we're both still seeing it our own way. Must be one of those things, I guess ...) What I'm interested in is getting a feeling for the general level of support for the following options. Before I enumerate those options, let me make it clear that I don't believe this approach is valid for all modules, far from it. The std.windows.registry, std.mmfile and the std.perf (not yet included) modules are entirely class-based. The std.recls module has both, and I have written std.loader as both. It is this latter that is the sticking point, as Walter does not want to release it in such a guise. The options as I see it are: 1. free functions only 2. class-interface only 3. combined approach, in same module 4. combined approach, in (for example) std.c.loader.d (for the free functions) and std.loader.d (for the class) 5. Some other combined approach that I've not anticipated. Please suggest Please let me know your thoughts Cheers MatthewI perfer number 4, however it seems to me that Walter is against it for fear that it would get out of hand and turn Phobos into a quagmire. I have not encountered Matthew's problem personally, but I can see where he coming from. Perhaps if too many people end up in the sameplace, someone will write another runtime library(flibd - Free D library?)?
May 07 2004