www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - trivia questions

reply "Maxime Larose" <mlarose broadsoft.com> writes:
Template and mixin problems again...

*** 1 ***
I want to have this:
list!(char[]) cols;
(or something sligthly different, like: mixin list!...)
expand into this:
LinkedList!(char[]) cols = new LinkedList!(char[]);

Is it at all possible in D?

Note that I also want
list!(LinkedList!(char[])) cols;
to expand into
LinkedList!(LinkedList!char[]) cols = new LinkedList!(LinkedList!char[]);

Which leads us to point #2:

*** 2 ***
I find the fact that alias template parameters cannot be types somewhat
annoying.
Suppose:
template temp(T) { T value; }
This works (#1):
temp!(char[]) A = new temp!(char);
This doesn't, compiler complains (#2):
temp!(LinkedList!char[]) A = new temp!(LinkedList!char[]);

Converting the template to:
template temp(alias T) { T value; }

Makes #1 not work (compiler complains). It seems alias params cannot by
types...

*** 3 ***
I have a template(T) with:
T value;

I want to print out value. T can be a char[], another primitive or an
Object. Doing this simple task requires going through a lot of hoops...
I had to define another template TemplateUtil, that specializes on its
arguments:
TemplateUtil(O : Object)  ... toString(O o) { return o.toString(); }
TemplateUtil(T)  ... toString(T t) { return .toString(t); }
TemplateUtil(S : char[])  ... toString(S s) { return s; }
(last one is because .toString(char[]) sometimes returns garbage -- bug?)

I understand the newer versions of D have static if that may eliminate the
need to create a different template. However, there should be some way to
treat primitive and objects the same way... Like the library should take
these cases into account and define a toString(Object)  -- and make sure
that toString(char[]) doesn't return garbage...

(I still use an old version of DMD because stack tracing is not implemented
yet... I am the only one who sees the value in that?  I can't believe Walter
hasn't jumped on the code I gave him... Anyhow, my project is still small
(under 50 classes) but at least *I'm* not wasting time with
"AccessViolationException" with no indication of where it occured -- with
the ensuing 15 minutes "detective work", commenting out blocks of code
trying to find out what line is the culprit and in what condition the
problem occurs...)

*** 4 ***
Suppose a class has 2 very similar opApply methods. One needs to return the
index, the other one doesn't.
#1:
int opApply(int delegate(inout uint) dg)
{   int result = 0;
  for (int i = 0; i < array.length; i++) {
    result = dg(array[i]);
    if (result)
    break;
  }
  return result;
}

#2:
int opApply(int delegate(inout int index, inout uint) dg)
{   int result = 0;
     index = 0;
     // following line is different
     for (int i = 0; i < array.length; i++) {
       result = dg(array[i]);
       if (result)
         break;
       ++index;
     }
     return result;
}

How can D mixin possibly allow one to express the commonality of such
functions?  (Yes, you can make the first method call the second one, but
that's not the point. This is just a contrived example.)
IMO, the problem with D's generic tools is that they don't go far enough. It
should be possible to specify expressions in mixin that would be simply
replaced. Boiler plate code is rarely boiler plate to the extend assumed by
D. If it is, a simple copy-paste does the job. Usually, there is some small
difference that makes mixin totally unusable. In fact, I'd be interested to
know if/how people use mixin at all and for what tasks. Anyone?

Proposal:
macrodef macro_opApply(alias PRE, alias POST) {
    int result = 0;
    PRE
    for (int i = 0; i < array.length; i++) {
      result = dg(array[i]);
      if (result)
        break;
      POST
    }
    return result;
}

With a usage like:
int opApply(int delegate(inout int index, inout uint) dg)
{
   macro macro_opApply( {index = 0;}, {++index; } );
}

I'm not asking for any intelligence in macros, just a stupid replacement
capabilities. A macro is nothing more than a function called at _compile_
time.


***

LISP macros anyone?

I really find it frustating that a language designed in the '50s (LISP)
still has more raw descriptive power than about any other language. (Ocaml +
camlp4 is, I believe, the only exception.) Damn!

To tell you the truth, I'm also a bit frustrated that a lot of suggestions
coming from the functional language world are flat out rejected by this
community and more importantly by Walter. WTF!  I know D has the very humble
goal of being a "better C++", but what a lack of vision !!!!  The replies to
the recent proposal to have multiple return values is pretty depressing in
that regard. BTW, this had already been proposed a long, long time ago...
(as I'm pretty sure macros have been proposed to death...)

Also, why do I have to type:
LinkedList!(LinkedList!char[]) cols = new LinkedList!(LinkedList!char[]);

Couldn't I just type
cols = new LinkedList!(LinkedList!char[]);
With the compiler infering the type?

Type inference is an idea that is long overdue in mainstream languages.

I for one I'm tired of playing the typing monkey for stupid languages and
stupid compilers... But hey, that's just me. As someone has said in the
multiple return value thread (don't know who, and it's not a personal
attack, just to make you think):
Why fix it if it ain't broke?  Huuhhhh... To make it better perhaps?  Doh!

On top of my head, here are a few features I'd personnaly like to see: true
macros, multiple return values, type inference, stack tracing(!), mandatory
tail-recursive optimization by compilers... Don't get me wrong, I don't
expect a D to include all these right of the box. Especially with a one-man
team, and especially with the C++ background. I'm willing to wait a bit.
However, it's the reaction that these ideas bring that really scares me
regarding D's future.

(I really hate OCaml's syntax, but I'm seriously toying the idea to port my
pet project to it... I read a few things about it, but I would have to
actually program in it to have a better idea of what it can do. It comes
very close to D in the shootout (above C). Opinions about OCaml anyone?)


Max
Jun 09 2005
parent reply "Maxime Larose" <mlarose broadsoft.com> writes:
BTW, regarding OCaml opinions, the last thing I want is to start a language
war in this newsgroup. I like D (much better than C++) and I think Walter is
doing a great job. I don't want to piss off anyone.

To make sure that doesn't happen, please send me such opinions by email:
mlarose AT broadsoft DOT com



Clarification regarding multiple return values (why it is a good thing):

Which is cleaner/clearer?
#1
int projectIn3D(int someParam, out y, out z);
...
int x, y, z;
x = projectIn3D(someParam, y, z);
// function call doesn't make it clear which params are in and which are out
// also, why give a preference to x?

#2:
void projectIn3D(int someParam, out x, out y, out z);
...
int x, y, z;
projectIn3D(someParam, x, y, z);
// function call doesn't make it clear which params are in and which are out

#3:
(int x, int y, int z) projectIn3D(int someParam);
...
int x, y, z;
(x, y, z) = projectIn3D(someParam);


I hope it is obvious to everyone that #3 is better...



"Maxime Larose" <mlarose broadsoft.com> wrote in message
news:d89k3n$1jvm$1 digitaldaemon.com...
 Template and mixin problems again...

 *** 1 ***
 I want to have this:
 list!(char[]) cols;
 (or something sligthly different, like: mixin list!...)
 expand into this:
 LinkedList!(char[]) cols = new LinkedList!(char[]);

 Is it at all possible in D?

 Note that I also want
 list!(LinkedList!(char[])) cols;
 to expand into
 LinkedList!(LinkedList!char[]) cols = new LinkedList!(LinkedList!char[]);

 Which leads us to point #2:

 *** 2 ***
 I find the fact that alias template parameters cannot be types somewhat
 annoying.
 Suppose:
 template temp(T) { T value; }
 This works (#1):
 temp!(char[]) A = new temp!(char);
 This doesn't, compiler complains (#2):
 temp!(LinkedList!char[]) A = new temp!(LinkedList!char[]);

 Converting the template to:
 template temp(alias T) { T value; }

 Makes #1 not work (compiler complains). It seems alias params cannot by
 types...

 *** 3 ***
 I have a template(T) with:
 T value;

 I want to print out value. T can be a char[], another primitive or an
 Object. Doing this simple task requires going through a lot of hoops...
 I had to define another template TemplateUtil, that specializes on its
 arguments:
 TemplateUtil(O : Object)  ... toString(O o) { return o.toString(); }
 TemplateUtil(T)  ... toString(T t) { return .toString(t); }
 TemplateUtil(S : char[])  ... toString(S s) { return s; }
 (last one is because .toString(char[]) sometimes returns garbage -- bug?)

 I understand the newer versions of D have static if that may eliminate the
 need to create a different template. However, there should be some way to
 treat primitive and objects the same way... Like the library should take
 these cases into account and define a toString(Object)  -- and make sure
 that toString(char[]) doesn't return garbage...

 (I still use an old version of DMD because stack tracing is not

 yet... I am the only one who sees the value in that?  I can't believe

 hasn't jumped on the code I gave him... Anyhow, my project is still small
 (under 50 classes) but at least *I'm* not wasting time with
 "AccessViolationException" with no indication of where it occured -- with
 the ensuing 15 minutes "detective work", commenting out blocks of code
 trying to find out what line is the culprit and in what condition the
 problem occurs...)

 *** 4 ***
 Suppose a class has 2 very similar opApply methods. One needs to return

 index, the other one doesn't.
 #1:
 int opApply(int delegate(inout uint) dg)
 {   int result = 0;
   for (int i = 0; i < array.length; i++) {
     result = dg(array[i]);
     if (result)
     break;
   }
   return result;
 }

 #2:
 int opApply(int delegate(inout int index, inout uint) dg)
 {   int result = 0;
      index = 0;
      // following line is different
      for (int i = 0; i < array.length; i++) {
        result = dg(array[i]);
        if (result)
          break;
        ++index;
      }
      return result;
 }

 How can D mixin possibly allow one to express the commonality of such
 functions?  (Yes, you can make the first method call the second one, but
 that's not the point. This is just a contrived example.)
 IMO, the problem with D's generic tools is that they don't go far enough.

 should be possible to specify expressions in mixin that would be simply
 replaced. Boiler plate code is rarely boiler plate to the extend assumed

 D. If it is, a simple copy-paste does the job. Usually, there is some

 difference that makes mixin totally unusable. In fact, I'd be interested

 know if/how people use mixin at all and for what tasks. Anyone?

 Proposal:
 macrodef macro_opApply(alias PRE, alias POST) {
     int result = 0;
     PRE
     for (int i = 0; i < array.length; i++) {
       result = dg(array[i]);
       if (result)
         break;
       POST
     }
     return result;
 }

 With a usage like:
 int opApply(int delegate(inout int index, inout uint) dg)
 {
    macro macro_opApply( {index = 0;}, {++index; } );
 }

 I'm not asking for any intelligence in macros, just a stupid replacement
 capabilities. A macro is nothing more than a function called at _compile_
 time.


 ***

 LISP macros anyone?

 I really find it frustating that a language designed in the '50s (LISP)
 still has more raw descriptive power than about any other language. (Ocaml

 camlp4 is, I believe, the only exception.) Damn!

 To tell you the truth, I'm also a bit frustrated that a lot of suggestions
 coming from the functional language world are flat out rejected by this
 community and more importantly by Walter. WTF!  I know D has the very

 goal of being a "better C++", but what a lack of vision !!!!  The replies

 the recent proposal to have multiple return values is pretty depressing in
 that regard. BTW, this had already been proposed a long, long time ago...
 (as I'm pretty sure macros have been proposed to death...)

 Also, why do I have to type:
 LinkedList!(LinkedList!char[]) cols = new LinkedList!(LinkedList!char[]);

 Couldn't I just type
 cols = new LinkedList!(LinkedList!char[]);
 With the compiler infering the type?

 Type inference is an idea that is long overdue in mainstream languages.

 I for one I'm tired of playing the typing monkey for stupid languages and
 stupid compilers... But hey, that's just me. As someone has said in the
 multiple return value thread (don't know who, and it's not a personal
 attack, just to make you think):
 Why fix it if it ain't broke?  Huuhhhh... To make it better perhaps?  Doh!

 On top of my head, here are a few features I'd personnaly like to see:

 macros, multiple return values, type inference, stack tracing(!),

 tail-recursive optimization by compilers... Don't get me wrong, I don't
 expect a D to include all these right of the box. Especially with a

 team, and especially with the C++ background. I'm willing to wait a bit.
 However, it's the reaction that these ideas bring that really scares me
 regarding D's future.

 (I really hate OCaml's syntax, but I'm seriously toying the idea to port

 pet project to it... I read a few things about it, but I would have to
 actually program in it to have a better idea of what it can do. It comes
 very close to D in the shootout (above C). Opinions about OCaml anyone?)


 Max

Jun 09 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 9 Jun 2005 10:51:42 -0400, Maxime Larose wrote:

 Clarification regarding multiple return values (why it is a good thing):
 
 Which is cleaner/clearer?
 #1
 int projectIn3D(int someParam, out y, out z);
 ...
 int x, y, z;
 x = projectIn3D(someParam, y, z);
 // function call doesn't make it clear which params are in and which are out
 // also, why give a preference to x?
 
 #2:
 void projectIn3D(int someParam, out x, out y, out z);
 ...
 int x, y, z;
 projectIn3D(someParam, x, y, z);
 // function call doesn't make it clear which params are in and which are out
 
 #3:
 (int x, int y, int z) projectIn3D(int someParam);
 ...
 int x, y, z;
 (x, y, z) = projectIn3D(someParam);
 
 
 I hope it is obvious to everyone that #3 is better...

Yes, it seems better than #1 and #2, but consider my #4. #4: The same effect as #3 with very much smaller syntax change... // No syntax change with this line. void projectIn3D(int someParam, out int x, out int y, out int z ); ... int x, y, z; // Allow (optional) 'out' qualifier to assist legibility. projectIn3D(someParam, out x, out y, out z); -- Derek Parnell Melbourne, Australia 10/06/2005 6:40:32 AM
Jun 09 2005
parent reply "Maxime Larose" <mlarose broadsoft.com> writes:
Hmmm.... I'm not sure why you would consider a change in syntax a bad
thing...

My opinion is to go with the way that makes the most sense/is the easiest to
code/etc. regardless of any syntax change. Backward compatibility is not an
issue at this point. Anyway, the proposed change doesn't break old code.


"Derek Parnell" <derek psych.ward> wrote in message
news:1e228b03xlnu8.fssoyqqxcrgh.dlg 40tude.net...
 On Thu, 9 Jun 2005 10:51:42 -0400, Maxime Larose wrote:

 Clarification regarding multiple return values (why it is a good thing):

 Which is cleaner/clearer?
 #1
 int projectIn3D(int someParam, out y, out z);
 ...
 int x, y, z;
 x = projectIn3D(someParam, y, z);
 // function call doesn't make it clear which params are in and which are


 // also, why give a preference to x?

 #2:
 void projectIn3D(int someParam, out x, out y, out z);
 ...
 int x, y, z;
 projectIn3D(someParam, x, y, z);
 // function call doesn't make it clear which params are in and which are


 #3:
 (int x, int y, int z) projectIn3D(int someParam);
 ...
 int x, y, z;
 (x, y, z) = projectIn3D(someParam);


 I hope it is obvious to everyone that #3 is better...

Yes, it seems better than #1 and #2, but consider my #4. #4: The same effect as #3 with very much smaller syntax change... // No syntax change with this line. void projectIn3D(int someParam, out int x, out int y, out int z ); ... int x, y, z; // Allow (optional) 'out' qualifier to assist legibility. projectIn3D(someParam, out x, out y, out z); -- Derek Parnell Melbourne, Australia 10/06/2005 6:40:32 AM

Jun 13 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 13 Jun 2005 15:05:31 -0400, Maxime Larose wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:1e228b03xlnu8.fssoyqqxcrgh.dlg 40tude.net...
 On Thu, 9 Jun 2005 10:51:42 -0400, Maxime Larose wrote:

 Clarification regarding multiple return values (why it is a good thing):

 Which is cleaner/clearer?
 #1
 int projectIn3D(int someParam, out y, out z);
 ...
 int x, y, z;
 x = projectIn3D(someParam, y, z);
 // function call doesn't make it clear which params are in and which are


 // also, why give a preference to x?

 #2:
 void projectIn3D(int someParam, out x, out y, out z);
 ...
 int x, y, z;
 projectIn3D(someParam, x, y, z);
 // function call doesn't make it clear which params are in and which are


 #3:
 (int x, int y, int z) projectIn3D(int someParam);
 ...
 int x, y, z;
 (x, y, z) = projectIn3D(someParam);


 I hope it is obvious to everyone that #3 is better...

Yes, it seems better than #1 and #2, but consider my #4. #4: The same effect as #3 with very much smaller syntax change... // No syntax change with this line. void projectIn3D(int someParam, out int x, out int y, out int z ); ... int x, y, z; // Allow (optional) 'out' qualifier to assist legibility. projectIn3D(someParam, out x, out y, out z); -- Derek Parnell Melbourne, Australia 10/06/2005 6:40:32 AM

thing...

Huh? Where did I say that? If you look over my posts on other issue, you can see that I am frequently championing syntax changes (not with much luck though).
 My opinion is to go with the way that makes the most sense/is the easiest to
 code/etc. regardless of any syntax change.

Yes, I agree with that. I never said otherwise.
 Backward compatibility is not an
 issue at this point. Anyway, the proposed change doesn't break old code.

Ditto. My point was that, even though you had given some examples of a new syntax, one shouldn't regard that as the only possible changes to implement the same concept. I just suggested an additional change, and in my opinion one that has even less impact on the language and still achieves the same end. -- Derek Parnell Melbourne, Australia 14/06/2005 6:55:23 AM
Jun 13 2005
parent reply James Dunne <james.jdunne gmail.com> writes:
As you may recall the subject line of that thread, it was "ditch 'out'" =D.  I
was merely searching for a way to treat out variables as what they truly are:
return values.

Both mine and your solutions to this problem(?) produce the same results; both
with no breaking of backwards compatibility in the language.

However, your solution, albeit less "breaking the language" than mine, proposes
a cleanup to the problem by adding more typing on the function call end to
explicitly specify which variables are to be returned.

My solution changes the declaration of the function to make it clear that return
values and parameters are, in fact, different.  They should not be mixed
together within the same list.  Also, the function call syntax change I proposed
makes it clearer - with less typing (easier to read?) - which values are passed
in, and which are returned.

Alas, this debate probably won't mean much in the long run as it doesn't seem
the users can agree.  Logically following, it hardly seems as if Walter would
accept such a proposal if the users were not in full agreeance on the matter.
Does Walter have opinions on this issue?



In article <164k5nq7adsaq$.8i9q8976n6qh.dlg 40tude.net>, Derek Parnell says...
On Mon, 13 Jun 2005 15:05:31 -0400, Maxime Larose wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:1e228b03xlnu8.fssoyqqxcrgh.dlg 40tude.net...
 On Thu, 9 Jun 2005 10:51:42 -0400, Maxime Larose wrote:

 Clarification regarding multiple return values (why it is a good thing):

 Which is cleaner/clearer?
 #1
 int projectIn3D(int someParam, out y, out z);
 ...
 int x, y, z;
 x = projectIn3D(someParam, y, z);
 // function call doesn't make it clear which params are in and which are


 // also, why give a preference to x?

 #2:
 void projectIn3D(int someParam, out x, out y, out z);
 ...
 int x, y, z;
 projectIn3D(someParam, x, y, z);
 // function call doesn't make it clear which params are in and which are


 #3:
 (int x, int y, int z) projectIn3D(int someParam);
 ...
 int x, y, z;
 (x, y, z) = projectIn3D(someParam);


 I hope it is obvious to everyone that #3 is better...

Yes, it seems better than #1 and #2, but consider my #4. #4: The same effect as #3 with very much smaller syntax change... // No syntax change with this line. void projectIn3D(int someParam, out int x, out int y, out int z ); ... int x, y, z; // Allow (optional) 'out' qualifier to assist legibility. projectIn3D(someParam, out x, out y, out z); -- Derek Parnell Melbourne, Australia 10/06/2005 6:40:32 AM

thing...

Huh? Where did I say that? If you look over my posts on other issue, you can see that I am frequently championing syntax changes (not with much luck though).
 My opinion is to go with the way that makes the most sense/is the easiest to
 code/etc. regardless of any syntax change.

Yes, I agree with that. I never said otherwise.
 Backward compatibility is not an
 issue at this point. Anyway, the proposed change doesn't break old code.

Ditto. My point was that, even though you had given some examples of a new syntax, one shouldn't regard that as the only possible changes to implement the same concept. I just suggested an additional change, and in my opinion one that has even less impact on the language and still achieves the same end. -- Derek Parnell Melbourne, Australia 14/06/2005 6:55:23 AM

Regards, James Dunne
Jun 13 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 13 Jun 2005 21:53:30 +0000 (UTC), James Dunne wrote:

 As you may recall the subject line of that thread, it was "ditch 'out'" =D.  I
 was merely searching for a way to treat out variables as what they truly are:
 return values.
 
 Both mine and your solutions to this problem(?) produce the same results; both
 with no breaking of backwards compatibility in the language.
 
 However, your solution, albeit less "breaking the language" than mine, proposes
 a cleanup to the problem by adding more typing on the function call end to
 explicitly specify which variables are to be returned.
 
 My solution changes the declaration of the function to make it clear that
return
 values and parameters are, in fact, different.  They should not be mixed
 together within the same list.  Also, the function call syntax change I
proposed
 makes it clearer - with less typing (easier to read?) - which values are passed
 in, and which are returned.

Okay, I admit I was playing "devil's advocate" by trying to think along what I believe are Walter's aims for D. That's why I tried to look for a 'C' like solution. Personally, I like the idea of physically separating input arguments from output arguments. I've been an advocate of this concept in other languages that I deal with too. I'm not sure how to deal with arguments that are both though. Any ideas?
 Alas, this debate probably won't mean much in the long run as it doesn't seem
 the users can agree.

I agree but for different reasons. I don't think it will mean much in the long run because it's not C therefore it's not D ;-)
  Logically following, it hardly seems as if Walter would
 accept such a proposal if the users were not in full agreeance on the matter.
 Does Walter have opinions on this issue?

Probably, but that doesn't mean we will ever hear them ;-) -- Derek Melbourne, Australia 14/06/2005 9:04:04 AM
Jun 13 2005
parent James Dunne <james.jdunne gmail.com> writes:
In article <gh1ip8x0a0j2$.1vefbvlzmmxyd$.dlg 40tude.net>, Derek Parnell says...
On Mon, 13 Jun 2005 21:53:30 +0000 (UTC), James Dunne wrote:

 As you may recall the subject line of that thread, it was "ditch 'out'" =D.  I
 was merely searching for a way to treat out variables as what they truly are:
 return values.
 
 Both mine and your solutions to this problem(?) produce the same results; both
 with no breaking of backwards compatibility in the language.
 
 However, your solution, albeit less "breaking the language" than mine, proposes
 a cleanup to the problem by adding more typing on the function call end to
 explicitly specify which variables are to be returned.
 
 My solution changes the declaration of the function to make it clear that
return
 values and parameters are, in fact, different.  They should not be mixed
 together within the same list.  Also, the function call syntax change I
proposed
 makes it clearer - with less typing (easier to read?) - which values are passed
 in, and which are returned.

Okay, I admit I was playing "devil's advocate" by trying to think along what I believe are Walter's aims for D. That's why I tried to look for a 'C' like solution. Personally, I like the idea of physically separating input arguments from output arguments. I've been an advocate of this concept in other languages that I deal with too. I'm not sure how to deal with arguments that are both though. Any ideas?

If by "both" you mean "inout" arguments, then why not specify them in both the return value list and the argument list? Then they'd be both "in" and "out" =P. Yeah, it looks quirky to me too, and has a potential to be murky. I'm actually fine with inout arguments using the inout modifier and being specified in the argument list just as they are now. The out arguments bug me though. The way I'd see it is you have one list strictly for output values, and one list for input values. The list for input values can also contain "inout" values since the out list is strictly for output-only values. Simple set theory. But the separate lists concept is just an assumption made up by myself - so it probably won't fly too far ;).
 Alas, this debate probably won't mean much in the long run as it doesn't seem
 the users can agree.

I agree but for different reasons. I don't think it will mean much in the long run because it's not C therefore it's not D ;-)

C doesn't have classes, templates, mixins, interfaces, attributes, properties, etc. I hardly see why that's a limiting factor here in discussion of possible future directions of the D language. I think of it as a whole different animal, mostly mutated from C. You can sort-of see the C roots there, but the D mutations hide it fairly well.
  Logically following, it hardly seems as if Walter would
 accept such a proposal if the users were not in full agreeance on the matter.
 Does Walter have opinions on this issue?

Probably, but that doesn't mean we will ever hear them ;-)

I don't expect much in that regard. He is a busy man and has no obligation whatsoever to answer to any of us =P. That doesn't mean that I wouldn't love to hear his opinions on the matter, however.
-- 
Derek
Melbourne, Australia
14/06/2005 9:04:04 AM

Regards, James Dunne
Jun 13 2005