www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3474] New: PATCH: Implement opDollar for struct and class indexing operations

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474

           Summary: PATCH: Implement opDollar for struct and class
                    indexing operations
           Product: D
           Version: 2.036
          Platform: Other
        OS/Version: All
            Status: NEW
          Keywords: patch
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: clugdbug yahoo.com.au



Created an attachment (id=491)
Patch against DMD2 svn 240.

The attached patch allows usage of $ inside opIndex and opIndexAssign in
structs and classes.
Any usage of $ becomes a call to an opDollar function.
If multi-dimensional indexing is possible, the $ symbol instantiates a template
called opDollar(int dim)().

x[ $-3, $-5, $-6] becomes  x.opIndex(x.opDollar!(0)() - 3, x.opDollar!(1)() -
5, x.opDollar!(2)() -6);

Note that since opDollar is a template, it may return different types for
different indices...

As a convenience, if a class or struct ONLY supports single-dimension indexing,
a non-templated opDollar() can be used instead.

x[ $-5 ]  can become   x.opIndex( x.opDollar() - 5 );

(If a opDollar!(int n)() is available, it will be used instead. There's no
ambiguity: the compiler won't let you define both template and function
opDollar, since they both have no arguments).

Some implementation notes:
(1) $ is evaluated lazily for each dimension.  x[4,  $+3*$ - foo($), 6] will
only make one call to opDollar.
(2) BUG 3326: "$ in delegate literal causes Access Violation" does NOT apply to
this code. You can do all kinds of nasty stuff with $ and it seems to work.
(3) It is possible to nest multi-dimensional indexing. x[$-2, y[$-6, $-9], $-2]
works.
(4) I have NOT implemented $ inside opSlice(), opSliceAssign().
It could be done, but I believe those language features need work. They don't
permit multi-dimensional slicing. I think they should be removed, and the
functionality folded into opIndex.
(5) How it works:
x[ $-3, 5, $-6]= "abc" actually becomes:
x.opIndexAssign("abc", (auto __dollar = x.opDollar!(0)();, __dollar - 3), 5,
(auto __dollar = x.opDollar!(2)(); _dollar - 6)).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 05 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei metalanguage.com



08:13:37 PST ---
Great!

Any chance we can use "length" instead of "opDollar" throughout? It would
instantly match what arrays are currently doing and it would be a closer
description of the semantics of the operation.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 05 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474





 Great!
 
 Any chance we can use "length" instead of "opDollar" throughout? It would
 instantly match what arrays are currently doing and it would be a closer
 description of the semantics of the operation.
Yes, the name doesn't make any difference. Although length() looks natural, I think length!(1)() looks a bit clumsy? The one-dimensional case is a degenerate form of the multi-dimensional case. Moreover, I suspect the template is not the interface you want in most cases: you often want to iterate over the dimensions. Probably in most cases, it'd be defined like: int opDollar(int n)() { return dim[n]; } Also there may be problems if you want to be able to use .length to change the dimensions. BTW you can use aliases. This works: struct Foo { int x; int length() { return x; } alias length opDollar; int opIndex(int k) { return x*k; } } void main() { Foo f = Foo(7); int x = foo[$-5]; assert(x== 2*7); } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 05 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474




09:18:44 PST ---


 Great!
 
 Any chance we can use "length" instead of "opDollar" throughout? It would
 instantly match what arrays are currently doing and it would be a closer
 description of the semantics of the operation.
Yes, the name doesn't make any difference. Although length() looks natural, I think length!(1)() looks a bit clumsy? The one-dimensional case is a degenerate form of the multi-dimensional case. Moreover, I suspect the template is not the interface you want in most cases: you often want to iterate over the dimensions. Probably in most cases, it'd be defined like: int opDollar(int n)() { return dim[n]; } Also there may be problems if you want to be able to use .length to change the dimensions. BTW you can use aliases. This works: struct Foo { int x; int length() { return x; } alias length opDollar; int opIndex(int k) { return x*k; } } void main() { Foo f = Foo(7); int x = foo[$-5]; assert(x== 2*7); }
I understand and have no further comments. Let's go with opDollar. (One suggestion if I may :o). In the 1-dimensional case, of a type defines no opDollar but does define length... you may want to rewrite $ to length. But probably that's too complicated a rule already.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 05 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com




 Great!
 
 Any chance we can use "length" instead of "opDollar" throughout? It would
 instantly match what arrays are currently doing and it would be a closer
 description of the semantics of the operation.
I agree that "opDollar" is a bad choice of name, but so is "length". AIUI the point is for it to represent the end (or one past the end) of the array, rather than length. They correspond only in the case of 0-based arrays. This has come up before: http://www.digitalmars.com/d/archives/digitalmars/D/announce/Re_opDollar_12939.html -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 05 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474




02:24:30 PST ---
 I agree that "opDollar" is a bad choice of name, but so is "length".  AIUI the
 point is for it to represent the end (or one past the end) of the array, rather
 than length.  They correspond only in the case of 0-based arrays.
It's elready defined semantics. $ means length. If you want different semantics, use different means to express it. Objects in container can be numbered from 1, numbering can have gaps, so $-1 can be meaningless, or entire collection can be unordered like hashtable, so the last element can be meaningless, or keytype can be of complex type, having nothing in common with numbers, you just use different means to work with it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474





 I agree that "opDollar" is a bad choice of name, but so is 
 "length".  AIUI the point is for it to represent the end (or one 
 past the end) of the array, rather than length.  They correspond 
 only in the case of 0-based arrays.
It's elready defined semantics. $ means length.
It's defined only on built-in linear arrays: http://www.digitalmars.com/d/2.0/arrays.html "Within the [ ] of a static or a dynamic array, the variable length is implicitly declared and set to the length of the array. The symbol $ can also be so used." Try it on AAs and see for yourself. (Sidenote: I thought the implicitly declared length was deprecated.) Moreover, FAIK, it may have been described this way only for simplicity, as Walter never expected to make it overloadable for custom types where "length" and "index one after the end" are distinct.
 If you want different semantics, use different means to express it.  
 Objects in container can be numbered from 1, numbering can have 
 gaps, so $-1 can be meaningless,
You're giving me exactly the already-known reasons $ ought to be defined along the lines of "end" rather than "length". It's probably how most D programmers think of it, because the main use for $ is to index relative to the end of an array. And so, if we start encouraging programmers to make $ mean the number of elements in a non-0-based array, sparse array or whatever, it'll get confusing. I certainly can't see any reason for keeping it as "length". And it would break 0% of existing code to change it now. As for "numbering can have gaps", there are at least two cases to consider: - indexes are spaced by a constant interval k, IWC [$-k] feels a natural way of referring to the final element analogous to [$-1] for standard arrays - indexes are (or may be) irregularly spaced, IWC what $ should mean, if anything, is harder to define
 or entire collection can be unordered like hashtable, so the last 
 element can be meaningless, or keytype can be of complex type, 
 having nothing in common with numbers, you just use different means 
 to work with it.
IWC you would probably not define $ at all. If there's any problem with that, I can't see it.... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474


Adrian Matoga <epi atari8.info> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |epi atari8.info



Any solution of this? Currently (DMD 2.047) both length and opDollar give
"undefined identifier __dollar".

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 08 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc



Have you created a pull request for this, Don?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 03 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474




Applied Don's patch into git master.
https://github.com/9rnsr/dmd/branches/opDollar

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 09 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474




---
Posted pull request.
https://github.com/D-Programming-Language/dmd/pull/442

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 10 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474




With the recent patch this doesn't compile, is this expected?


struct Foo {
    int x;
    alias x opDollar;
    int opIndex(int k) { return x * k; }
}
void main() {
    Foo f = Foo(7);
    int x = f[$ - 5]; // Error: undefined identifier __dollar
    assert(x == 2 * 7);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 22 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474





 With the recent patch this doesn't compile, is this expected?
 
 
 struct Foo {
     int x;
     alias x opDollar;
     int opIndex(int k) { return x * k; }
 }
 void main() {
     Foo f = Foo(7);
     int x = f[$ - 5]; // Error: undefined identifier __dollar
     assert(x == 2 * 7);
 }
Yes, it checks that opDollar is either a function or a template function. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 22 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474




Poor error message though. All the overloaded operators have bad errors:

struct S {
   void x() {}
   alias x opUnary;
}

void main() {
    S a;
    a = -a;
}

test.d(9): Error: a.x isn't a template

struct S {
   int x;
   alias x opUnary;
}

void main() {
    S a;
    a = -a;
}
test.d(9): Error: 'a' is not of arithmetic type, it is a S

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 22 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3474


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |bugzilla digitalmars.com
         Resolution|                            |FIXED



02:56:58 PST ---
https://github.com/D-Programming-Language/dmd/commit/aba0f773416e1d45d227159cb22ad0e26bb980c0

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 22 2011