August 30, 2007
Alexander Panek wrote:
> Chris Nicholson-Sauls wrote:
>> I reiterate what I've said about three times now: I watch as D slowly turns into Ruby.  :)
> Hehe. They indeed have similarities - maybe not in language theory or overall concept, but in innovation. Having (part of) Ruby's expressiveness in D would be a very neat thing, as long as it doesn't affect other concepts and goals of D.

I'm sure we'll never, ever, see something quite like:
$db.commit @transaction unless @transaction.flag_set? :Simulate

But other than that... ;)

>> (Although I actually like pseudo-members.  ColdC has this as well, but by modifying a type-lib object; $String.foo() callable as "abc".foo() for example.)
> 
> That's actually possible already in D (D1, even):
> 
> //
> import tango.io.Stdout;
> 
> void print (char[] s) {
>     Stdout(s);
> }
> 
> void main () {
>     "Hello world!".print(); // omitting () is not possible, though
> }
> //

Oh yes, I know.  :)  (See Cashew.)  But unlike D/1.x, ColdC supports this for all types (in its own weird way).  Right now it only works for arrays, and was originally just a fluke side-effect that got popular.

It looks like D/2.x is going to open up that Pandora's Box though.  Here's hoping it goes a lot better than the referenced myth.

-- Chris Nicholson-Sauls
August 30, 2007
Brad Roberts wrote:
> On Fri, 31 Aug 2007, Bill Baxter wrote:
> 
>> Namespace issues are why I don't currently find much use for the array trick.
>> If you put your array trick functions in a module, they're mostly going to
>> have short names like "find" and "index".  So if you import that module
>> normally it will clobber a valuable chunk of your namespace with little words
>> like that.  But doing a static or renamed import causes the things not to
>> work.  "arrayfn.find" can't be used as a property.  Ok so you can static
>> import and then alias just the ones you want to use in the current module,
>> possibly down at function scope to limit the namespace clashing.  But that's
>> kind of a pain.
>>
>> The error messages are also not very intuitive currently.  You type
>> foo.bar(x,y) and get the error message "bar does not match types (int, int,
>> int)"    Wait -- I'm not even calling bar with three args!?  Oh yeh that
>> member syntax thing.  And if there really *is* a member with that name in the
>> current context then it will shadow the external one even though it *looks*
>> like foo.bar should be unambiguously scoped by foo.
>>
>> These are from recent experience trying to emulate C++ iterators on top of D
>> arrays.  For instance I wanted to be able to say  darray.begin() to get an
>> iterator to an array.  Forget it.  Most classes in which I want to use that
>> trick already have their own 'begin()' member which shadows the external
>> begin(T)(T[]) function.
>>
>> So my feeling is that for this to be more useful:
>> 1) Extension members should be marked as such and *only* be allowed to be
>> called with member syntax.  Those not marked as such will not be allowed to be
>> called with member syntax.  (if you need both then it's easy enough to write a
>> trivial forwarding function.)
>>
>> 2) Inside a class/struct scope, lookup of foo.bar should ignore methods of the
>> local class.  (this would be a natural side effect of #1 though.  it already
>> means extension members would do lookup differently than normal function
>> lookup)
>>
>> --bb
> 
> Don't overlook the changes upcoming in 2.0 to the overload resolution logic.  They'll greatly reduce (if not eliminate) the problem.  Many of the changes in 2.0 in isolation might introduce problems, but together make for a more powerful whole.

Yeh, that should help some.  But that doesn't seem to do anything about foo.bar() inside a class being treated as this.bar(foo).  I think that just shouldn't happen ever.  Maybe that's just a bug, though.  In fact I think I'll go file it as one right now.

--bb
August 30, 2007
Chris Nicholson-Sauls wrote:
> Bill Baxter wrote:
>> kris wrote:
>>> Lutger wrote:
>>>> kris wrote:
>>

>> So my feeling is that for this to be more useful:
>> 1) Extension members should be marked as such and *only* be allowed to be called with member syntax.  Those not marked as such will not be allowed to be called with member syntax.  (if you need both then it's easy enough to write a trivial forwarding function.)
> 
> Its not a bad idea.  The "trivial forwarding function" should be inlineable anyhow.  Maybe a "context" parameter?  Something like:
> size_t indexOf : T[] array (T) (T elem) { ... }
> 
> Where the (':' param) after the function name creates the context-param.  Other examples:
> 
> ulong area : IShape shp () { ... }
> 
> void unique : inout T[] array (T) () { ... }
> 
> 
> Its just a random on-the-spot idea.
> 

Maybe even just use a semi-colon instead of comma in the arg list?
  size_t indexOf(T)(T[] array; T elem) { ... }
  ulong area (IShape shp;) { ... }
  void unique (ref T[] array; T) () { ... }

--bb
August 30, 2007
Bill Baxter wrote:
> Chris Nicholson-Sauls wrote:
>> Bill Baxter wrote:
>>> kris wrote:
>>> So my feeling is that for this to be more useful:
>>> 1) Extension members should be marked as such and *only* be allowed to be called with member syntax.  Those not marked as such will not be allowed to be called with member syntax.  (if you need both then it's easy enough to write a trivial forwarding function.)
>>
>> Its not a bad idea.  The "trivial forwarding function" should be inlineable anyhow.  Maybe a "context" parameter?  Something like:
>> size_t indexOf : T[] array (T) (T elem) { ... }
>>
>> Where the (':' param) after the function name creates the context-param.  Other examples:
>>
>> ulong area : IShape shp () { ... }
>>
>> void unique : inout T[] array (T) () { ... }
>>
>>
>> Its just a random on-the-spot idea.
>>
> 
> Maybe even just use a semi-colon instead of comma in the arg list?
>   size_t indexOf(T)(T[] array; T elem) { ... }
>   ulong area (IShape shp;) { ... }
>   void unique (ref T[] array; T) () { ... }
> 
> --bb

I like that syntax; something similiar is used in mathematics on occasion.  Simple and elegant.

Thanks,
Nathan Reed
August 31, 2007
Nathan Reed wrote:
> Bill Baxter wrote:
>> Chris Nicholson-Sauls wrote:
>>> Bill Baxter wrote:
>>>> kris wrote:
>>>> So my feeling is that for this to be more useful:
>>>> 1) Extension members should be marked as such and *only* be allowed to be called with member syntax.  Those not marked as such will not be allowed to be called with member syntax.  (if you need both then it's easy enough to write a trivial forwarding function.)
>>>
>>> Its not a bad idea.  The "trivial forwarding function" should be inlineable anyhow.  Maybe a "context" parameter?  Something like:
>>> size_t indexOf : T[] array (T) (T elem) { ... }
>>>
>>> Where the (':' param) after the function name creates the context-param.  Other examples:
>>>
>>> ulong area : IShape shp () { ... }
>>>
>>> void unique : inout T[] array (T) () { ... }
>>>
>>>
>>> Its just a random on-the-spot idea.
>>>
>>
>> Maybe even just use a semi-colon instead of comma in the arg list?
>>   size_t indexOf(T)(T[] array; T elem) { ... }
>>   ulong area (IShape shp;) { ... }
>>   void unique (ref T[] array; T) () { ... }
>>
>> --bb
> 
> I like that syntax; something similiar is used in mathematics on occasion.  Simple and elegant.
> 
> Thanks,
> Nathan Reed

Agreed.  I believe the use of semicolons within params was once suggested for another purpose, ages ago, and (obviously) went nowhere.  Maybe this suggestion will be a bit more lucky.

-- Chris Nicholson-Sauls
August 31, 2007
Alexander Panek wrote:
> Alexander Panek wrote:
>> Lars Ivar Igesund wrote:
>>> [...]
>>> It will also be directly detrimental to maintainability when used for user
>>> defined types, as you no longer will be able to decide where a function is
>>> implemented by only looking at the call site (given inheritance and
>>> polymorphism this can in cases be difficult enough, but at least you have a
>>> type hierarchy to look to).
>>
>> Well, usually a simple change to the import list will reveal where each functions are defined. I wouldn't see that as an argument against this feature.
>>
>> Apart from that, in an ideal world, the code is well documented enough to not have to determine the location of a function/method implementation yourself, anyways. Of course, this is the *ideal*, but maybe this encourages some to document better.
> 
> On the other hand, the ambiguity problem:
> 
> class A {
>     int foo (int);
> }
> 
> int foo (A, int);
> 
> ..leads or at least may lead to maintenance problems, anyways.
> 
> (Yes, I might have missed the point in the other post :P)

Perhaps, but even without interchangeability warning signs go up for me if you have a method and a function that have the same signature.
1 2 3
Next ›   Last »