www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 8463] New: Nested template static struct should work as like module level ones

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

           Summary: Nested template static struct should work as like
                    module level ones
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: k.hara.pg gmail.com



Voldemort type is fine idiom, but which cannot control the *nested-ness* of
inner struct completely, with current dmd.

I think 'static nested template struct' should work.

template map(alias pred) {
  auto map(Range)(Range input) {
    static struct Result(alias pred) {
      Range input = r;
      this(Range r) { input = r; }
      auto empty() { return r.empty; }
      auto front() { return pred(r.front); }
      void popFront() { r.popFront(); }
    }
    return Result!pred(input);
  }
}

In above code:
1. the struct Result should not require the context of map function.
2. If pred requires a context, Result is implicitly treated as nested struct.
3. And Result can access the type 'Range' in accordance with lexical scope
rule.

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


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au



Do you mean, that the context pointer would be the frame pointer of the
function which made the call? (rather than the frame pointer of 'map')?

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





 Do you mean, that the context pointer would be the frame pointer of the
 function which made the call? (rather than the frame pointer of 'map')?
I mean: with current dmd, Result always requires the frame pointer of map, and we cannot kill it. and if pred is a function that requires a frame pointer (e.g. member function, nested function), Result shall have two frame pointers, but it's disallowed. This issue is a proposal which provides the way to kill the former (== the frame pointer of map). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8463


klickverbot <code klickverbot.at> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code klickverbot.at



---
Shouldn't it be possible to automatically use the »outermost« context possible,
only creating and allocating new nested ones if they are really required?

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


Andrei Alexandrescu <andrei metalanguage.com> changed:

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



09:18:24 PDT ---
I'm a bit confused by the example because it uses the symbol "pred" twice.
Kenji, could you please change?

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




09:22:57 PDT ---
I'd personally prefer more explicit handling by the programmer instead of more
powerful built-in frame pointer management. At this point I'm unclear on what
exactly that would look like.

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


Kenji Hara <k.hara.pg gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |http://d.puremagic.com/issu
                   |                            |es/show_bug.cgi?id=5710




 I'd personally prefer more explicit handling by the programmer instead of more
 powerful built-in frame pointer management. At this point I'm unclear on what
 exactly that would look like.
See also issue 5710. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8463




Module level template struct *is inferred* whether it's really nested or not.

struct Map(alias pred, Range) {
  Range input;
  this(Range r) { input = r; }
   property empty(){ return input.empty; }
   property front(){ return pred(input.front); }
  void popFront() { input.popFront(); }
}
auto map(alias pred, Range)(Range r) { return Map!(pred, Range)(r); }

void main() {
  int n = 2;
         int addN(int x) { return x + n; }
  static int add1(int x) { return x + 1; }

  auto r1 = map!addN([1,2,3]);
  // typeof(r1) is a nested struct, because pred has a frame pointer(FP).

  auto r2 = map!add1([1,2,3]);
  // typeof(r2) is not a nested struct, because pred doesn't have a FP.
}

But nested struct (declared in function body) cannot receive such treatment.

auto mapN(alias pred, Range)(Range r) {
  struct MapN { ... same as above Map ... }
  // MapN have always a FP, then if pred has another one, they conflict.
}

auto mapS(alias pred, Range)(Range r) {
  static struct MapS { ... same as above Map ... }
  // MapS cannot have any FP, then if pred has a FP, MapS cannot access it.
}

My proposal is:

auto mapTS(alias pred, Range)(Range r) {
  static struct MapTS(alias pred) { ... same as above Map ... }
  // MapTS can infer its actual nest-ness based on the pred2, as like Map.
  // But MapTS cannot access mapTS function's FP, because it's static struct.
}


 I'm a bit confused by the example because it uses the symbol "pred" twice.
 Kenji, could you please change?
To ignite such nest-ness inference for MapTS, mapTS should pass the pred to inner struct. ---- But, maybe, this proposal is a little complicated than the rule that you think in your head. We might be able to be simplify the rule. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8463




---

 But nested struct (declared in function body) cannot receive such treatment.
Why can't it? The nested struct simply gets as many context pointers as it needs, this can be zero if it accesses neither the local or the pred context, one, or two. In the latter case, the context pointer is really a pointer to a struct reps. an array containing the two context pointers, so that it has still the same ABI. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8463






 But nested struct (declared in function body) cannot receive such treatment.
Why can't it? The nested struct simply gets as many context pointers as it needs, this can be zero if it accesses neither the local or the pred context, one, or two. In the latter case, the context pointer is really a pointer to a struct reps. an array containing the two context pointers, so that it has still the same ABI.
Are you talking about issue 5710? This enhancement doesn't cover it (I think it requires ABI level changing, and this doesn't). --- If you talking about this, the reason is template instantiation mechanism problem. To implement this enhancement, the nested struct should be instantiated depends on the enclosing scope of template declaration. But current dmd doesn't consider it. Last weekend, I had tried to implement this, but It was not easy. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8463





 But nested struct (declared in function body) cannot receive such treatment.
Why can't it? The nested struct simply gets as many context pointers as it needs, this can be zero if it accesses neither the local or the pred context, one, or two. In the latter case, the context pointer is really a pointer to a struct reps. an array containing the two context pointers, so that it has still the same ABI.
Are we certain that you can never get more than two context pointers? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8463




---


 But nested struct (declared in function body) cannot receive such treatment.
Why can't it? The nested struct simply gets as many context pointers as it needs, this can be zero if it accesses neither the local or the pred context, one, or two. In the latter case, the context pointer is really a pointer to a struct reps. an array containing the two context pointers, so that it has still the same ABI.
Are we certain that you can never get more than two context pointers?
I was referring to the specific example mentioned by Kenji. The array could hold arbitrarily many pointers. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 30 2012