Phango - questions

Sean Kelly sean at f4.ca
Sun Nov 18 18:13:26 PST 2007


Bill Baxter wrote:
> Sean Kelly wrote:
> 
>> I suppose one could argue that following the Java approach in Tango 
>> results in unneeded redundancies, such as the DeviceConduit module 
>> containing a DeviceConduit class, but again, I would argue that 
>> choosing an arbitrary name to avoid these redundancies would reduce 
>> clarity.  As it is, I know that if I want to use a DeviceConduit in my 
>> app, I just have to import tango.io.DeviceConduit.  There is no need 
>> to remember that the class actually lives in tango.io.blah instead.
> 
> That does seem useful.  But is that true for every public class?  It may 
> be working in Tango, but generally D doesn't really lend itself to 
> Java's one-file==one-class.  (because D's only way to achieve 'friends' 
> is to put two classes in the same file).  Also in Tango I see you have 
> tango.math.Math which doesn't contain any class called "Math".

It's not true of every module, because as you say, not every module 
contains any classes at all.  But for the classes that do exist in 
Tango, in the vast majority of cases they live in a module of the same 
name.  The most obvious exception being modules with one 'primary' class 
and a number of related classes.  tango.core.Thread, for example, 
contains Thread, ThreadLocal, and ThreadGroup.

I'll admit that I find this correspondence most useful when dealing with 
Tango's IO package however, because it is so heavily modular.  In fact, 
this modularity is the reason there are few aggregate modules.  Tango is 
designed in a manner that largely avoids unused code being linked into 
an application by spreading it across multiple modules.  One may argue 
that block-level linking would mostly solve this problem as well, but it 
currently does not work with D, and things like static data, module 
ctors, etc, would not be omitted even with this feature.

>> Finally, I'll admit to being a bit baffled about what the big deal is 
>> anyway.  The C/C++ standard library uses lowercase for /everything/, 
>> type names included, and I've yet to see someone complain to the 
>> various committees about this, even when third party libraries for the 
>> same language follow a different convention.  And things are even 
>> worse in C++ because the library relies on specifically named typedefs 
>> to operate, so the convention there is viral by necessity.
> 
> I've heard complaining.  I've even been a complainer (before I started 
> liking lower_case names :-P).  But I never felt there was any hope in my 
> complaints leading to a change.  That's where D and Tango are different. 
>  :-)

Touche. :-)

>> Regarding D, Phobos, and Tango, I think the differences between the 
>> Phobos and the Tango convention are small potatoes.  Import lines may 
>> look a bit different, but /that's it/.  The only other difference in 
>> style concerns global objects, of which Tango has perhaps 3-4, all of 
>> which could be aliased to something else or wrapped in about ten 
>> seconds.  How can such an issue possibly be enough to discuss so much, 
>> let alone to use as grounds to reject a library entirely?  Frankly, if 
>> this is the worst thing that people have to say about Tango then I 
>> think the project has succeeded beyond my wildest expectations.
> 
> I agree with you there.  I find that as long as something is consistent, 
> you can get used to it, and maybe even like it after you get past your 
> initial revulsion.  But I don't actually find Tangos module naming 
> disagreeable.  I'd prefer coarser granularity than one-file-one-class, 
> but that can be fixed easily with a few public import modules.

In my experience, nearly every project has slightly different demands 
and it is impossible for a single library to exactly meet all of those 
demands.  However, I feel that it is the mark of a good library if it 
can be adapted to every project with little effort, little undesired 
overhead, and by not imposing design restrictions on the application by 
virtue of the library's own design.

Tango is intended to provide a framework and style guide for application 
programming more than to include a tool for every job.  This is the true 
reason for all the interface modules--they allow the user to build upon 
the library in a way which will most likely be portable to other 
applications.  At the same time, Tango avoids hidden costs wherever 
possible.  Almost no memory allocations are performed behind the scenes, 
exceptions are not used as a means of flow control, and so on.  And 
finally, the library is divided into a very granular set of modules to 
allow the user to link only the code she actually intends to use.

However, this aim towards customizability does increase the learning 
curve associated with Tango.  Often it is not obvious just what to 
import to perform simple operations, and it is often necessary to import 
quite a few modules for an average task.  Also, some users find the lack 
of convenience functions somewhat daunting.  These are all areas where 
we are trying to improve Tango, but I personally feel that such an 
effort can only ever be moderately successful.  This is because, as I 
said earlier, every application has slightly different requirements, and 
such convenience functions must necessarily assume a specific set of 
requirements.  So I would expect such functions to be most useful to a 
novice programmer and for one-off projects rather than for 
industrial-grade applications.

Sorry for being so long winded, but this is the basic rationale behind 
Tango's current design.  Given this, I think our greatest challenge is 
probably making the library more accessible to new users.  If you or 
anyone else has suggestions for this or anything else, then please let 
us know either here or in the Tango forums.  I deal almost exclusively 
with rather obscure parts of the library, so I tend to forget about the 
high-level issues people face with Tango.

> Here's an example from my porting of OpenMesh from C++ to D.  OpenMesh 
> has a class OpenMesh::IO::Options defined in the file 
> OpenMesh/Core/IO/Options.hh.  Trying to make as few changes as possible, 
> I named the module OpenMesh.Core.IO.Options.  But it's been annoying me 
> to no end because "Options" is such a generic name I never want to 
> import that into my main namespace.  But I think that as an FQN it's a 
> great name, except that the actual class is called ...IO.Options.Options.

I'll admit that the double name "Options.Options" thing drives me crazy 
sometimes.  But I haven't come up with any language feature to improve 
on that.  So far, I just use selective imports, aliasing, etc, to make 
my code more compact.


Sean



More information about the Digitalmars-d mailing list