May 08, 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 08, 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
Java/C#.

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.

Java/C# was a Classpath/.NET-like class library.  This, I believe, needs to be a
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 08, 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 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.

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 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
> 
> Matthew
> 
> 
I 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 08, 2004
Walter wrote:

>"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>.)
>  
>
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/
May 08, 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
> Java/C#.
>
> 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.
>
> Java/C# was a Classpath/.NET-like class library.  This, I believe, needs to be
a
> separate 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...
> >
> >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 08, 2004
resistor AT nospam DOT mac DOT com wrote:

> 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
> 
> 
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...

BA
May 08, 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 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...
>> 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.
>
>Are you arguing for you, or for Walter?

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.

>
>> 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?
>

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.






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.