www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Using map instead of iteration

reply Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I have a code fragment:

  auto threads =3D new Thread[numberOfThreads] ; =20
  foreach ( i ; 0 .. numberOfThreads ) {
    void delegate ( ) closedPartialSum ( ) {
      immutable id =3D i ;
      return ( ) { partialSum ( id , sliceSize , delta ) ; } ;
    }
    threads[i] =3D new Thread ( closedPartialSum ) ;
  }

which clearly should be doable using map from std.algorithm.  So I
tried:

  auto threads =3D map ! ( function Thread ( int i ) {
      void delegate ( ) closedPartialSum ( ) {
        immutable id =3D i ;
        return ( ) { partialSum ( id , sliceSize , delta ) ; } ;
      }
      return new Thread ( closedPartialSum ) ;
    } ) ( 0 .. numberOfThreads )

which fails:

pi_d2_threadsGlobalState.d(41): found '..' when expecting ','
pi_d2_threadsGlobalState.d(57): semicolon expected following auto
declaration, not 'foreach'

So clearly 0 .. numberOfThreads only means a range of integers in a
foreach or array index only and not everywhere as it does in all
sensible languages :-((

I am clearly missing something, anyone any ideas?

Thanks.


--=20
Russel.
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D
Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder ekiga.n=
et
41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel russel.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder
Mar 06 2011
next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Russel Winder <russel russel.org.uk> wrote:

 I have a code fragment:

   auto threads = new Thread[numberOfThreads] ;
   foreach ( i ; 0 .. numberOfThreads ) {
     void delegate ( ) closedPartialSum ( ) {
       immutable id = i ;
       return ( ) { partialSum ( id , sliceSize , delta ) ; } ;
     }
     threads[i] = new Thread ( closedPartialSum ) ;
   }

 which clearly should be doable using map from std.algorithm.  So I
 tried:

   auto threads = map ! ( function Thread ( int i ) {
       void delegate ( ) closedPartialSum ( ) {
         immutable id = i ;
         return ( ) { partialSum ( id , sliceSize , delta ) ; } ;
       }
       return new Thread ( closedPartialSum ) ;
     } ) ( 0 .. numberOfThreads )

 which fails:

 pi_d2_threadsGlobalState.d(41): found '..' when expecting ','
 pi_d2_threadsGlobalState.d(57): semicolon expected following auto
 declaration, not 'foreach'

 So clearly 0 .. numberOfThreads only means a range of integers in a
 foreach or array index only and not everywhere as it does in all
 sensible languages :-((

 I am clearly missing something, anyone any ideas?

You should use std.range.iota(0,numberOfThreads) instead of 0..numberOfThreads. Having a..b return a general interval range has been proposed numerous times, but nothing has been implemented as of yet. If you like syntactic sugar, this is likely the closest you'll get at this point: import std.range; struct _ { auto opSlice(B,E)(B begin, E end) { return iota(begin, end); } } // Example: map!foo( _[0..numberOfThreads] ); -- Simen
Mar 06 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 I'm sure that part of the problem is the fact that a .. b is also used in 
 slicing, where it does not mean the same thing

It means the same thing, with a interval literal.
 - that and iota works just fine, 

Currently it has a design bug that I've underlined.
 and increasingly, Andrei and Walter seem to prefer having stuff in the library 
 rather than the language itself when there's no significant gain to be had by 
 putting it in the language.

The gain is simplifying the language, removing the special cased syntax of foreach and switch and opSlice, and more, and replacing them with something more general, more polished and generic, that allows more usages and more runtime efficiency. This makes D look less like a pile of special cases and more like a designed language. So you are quite off-mark. See my recent answer: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=131378 Bye, bearophile
Mar 06 2011
prev sibling next sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sun, 2011-03-06 at 14:57 +0100, Simen kjaeraas wrote:
[ . . . ]
 You should use std.range.iota(0,numberOfThreads) instead of
 0..numberOfThreads. Having a..b return a general interval range
 has been proposed numerous times, but nothing has been implemented as
 of yet.

Thanks for this pointer.
 If you like syntactic sugar, this is likely the closest you'll get at
 this point:
=20
 import std.range;
=20
 struct _ {
      auto opSlice(B,E)(B begin, E end) {
          return iota(begin, end);
      }
 }
=20
 // Example:
 map!foo( _[0..numberOfThreads] );

Interesting. I am not sure I would do this, instead just going with the explicit iota. It would be better though if x..y (and x..<y) were standard parts of the syntax.=20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Mar 06 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 06 March 2011 05:57:12 Simen kjaeraas wrote:
 You should use std.range.iota(0,numberOfThreads) instead of
 0..numberOfThreads. Having a..b return a general interval range
 has been proposed numerous times, but nothing has been implemented as
 of yet.

I'm sure that part of the problem is the fact that a .. b is also used in slicing, where it does not mean the same thing - that and iota works just fine, and increasingly, Andrei and Walter seem to prefer having stuff in the library rather than the language itself when there's no significant gain to be had by putting it in the language. - Jonathan M Davis
Mar 06 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 06 March 2011 17:20:33 bearophile wrote:
 Jonathan M Davis:
 I'm sure that part of the problem is the fact that a .. b is also used in
 slicing, where it does not mean the same thing

It means the same thing, with a interval literal.
 - that and iota works just fine,

Currently it has a design bug that I've underlined.
 and increasingly, Andrei and Walter seem to prefer having stuff in the
 library rather than the language itself when there's no significant gain
 to be had by putting it in the language.

The gain is simplifying the language, removing the special cased syntax of foreach and switch and opSlice, and more, and replacing them with something more general, more polished and generic, that allows more usages and more runtime efficiency. This makes D look less like a pile of special cases and more like a designed language. So you are quite off-mark. See my recent answer: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&a rticle_id=131378

If anything, I'd argue to simply remove .. from foreach and have iota be the way to do it. The only other inconsistency is with case statements, but making them have an open right end would likely be problematic (not to mention break tons of code), whereas an open right end is exactly what it should be in the general case. I really don't see the problem other than the fact that using .. in foreach is completely redundant at this point, since we have iota. - Jonathan M Davis
Mar 06 2011
prev sibling parent Russel Winder <russel russel.org.uk> writes:
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

On Sun, 2011-03-06 at 17:41 -0800, Jonathan M Davis wrote:
[ . . . ]
 If anything, I'd argue to simply remove .. from foreach and have iota be =

 to do it. The only other inconsistency is with case statements, but makin=

 have an open right end would likely be problematic (not to mention break =

 code), whereas an open right end is exactly what it should be in the gene=

 case. I really don't see the problem other than the fact that using .. in=

 foreach is completely redundant at this point, since we have iota.

If .. is not going to mean a range of values everywhere then it should be allowed nowhere. This includes array slicing as well as foreach. Having a special case that leads people to try and use it as the general case is the worst of all worlds. Case labels will be the problem. range in Python is a range that is inclusive at the beginning and exclusive at the end, there are no special cases. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Mar 07 2011