Re: Immutable separator to join() doesn't work

2011-07-12 Thread Jonathan M Davis
On Tuesday 12 July 2011 15:46:41 Daniel Murphy wrote:
 Jonathan M Davis jmdavisp...@gmx.com wrote in message
 news:mailman.1552.1310429761.14074.digitalmar...@puremagic.com...
 
  This enhancement request would make the situation with immutable and
  const arrays so that they're much more in line with mutable container
  types and static arrays:
  
  http://d.puremagic.com/issues/show_bug.cgi?id=6289
  
  - Jonathan M Davis
 
 WAIT WHAT?  That doesn't work?!?

Nope. It works for static arrays but not for const or immutable arrays. Try 
it. It'll fail. I don't know _why_ it doesn't work, but it doesn't. If it did, 
this would be a much smaller issue. It would be nice if templates were 
improved such that they instantiated range-based functions in a manner which 
worked for static arrays and const or immutable arrays, but if you could solve 
the problem by slicing a const or immutable array, it would make the situation 
far less problematic.

- Jonathan M Davis


Re: Immutable separator to join() doesn't work

2011-07-12 Thread Daniel Murphy
Jonathan M Davis jmdavisp...@gmx.com wrote in message 
news:mailman.1554.1310450510.14074.digitalmar...@puremagic.com...
 Nope. It works for static arrays but not for const or immutable arrays. 
 Try
 it. It'll fail. I don't know _why_ it doesn't work, but it doesn't. If it 
 did,
 this would be a much smaller issue. It would be nice if templates were
 improved such that they instantiated range-based functions in a manner 
 which
 worked for static arrays and const or immutable arrays, but if you could 
 solve
 the problem by slicing a const or immutable array, it would make the 
 situation
 far less problematic.

 - Jonathan M Davis

Yeah, looking at the implementation and the test cases that rely on this, it 
seems to have been done to allow slicing typedefs to yeild the same type.  I 
really doubt this is something we need to support any more.
Every time this issue came up, I've always assumed this was how it worked!
Honestly, template deduction with implicit conversions is very unlikely to 
ever happen.  While it looks nice for one parameter, it quickly turns into a 
huge mess for multiple parameters.

There is a fairly easy workaround that could be used throughout phobos:
Accept T when isXXXRange!T || isXXXRange!(T[]), and use a static if to slice 
it when necessary.  This would solve the problem for containers, static 
arrays, immutable arrays, and other immutable ranges. 




Re: Immutable separator to join() doesn't work

2011-07-12 Thread Jonathan M Davis
On Tuesday 12 July 2011 16:16:59 Daniel Murphy wrote:
 There is a fairly easy workaround that could be used throughout phobos:
 Accept T when isXXXRange!T || isXXXRange!(T[]), and use a static if to slice
 it when necessary.  This would solve the problem for containers, static
 arrays, immutable arrays, and other immutable ranges.

I don't know whether that's a good idea for containers or const/immutable 
arrays, but it _definitely_ is a bad idea for static arrays. It would end up 
copying the entire array just because you forgot to slice it. Personally, I'm 
_far_ more inclined to say that you should just expect to have to slice 
something when you pass it to a range-based function. I think that the fact 
that the container that gets most used at this point is the dynamic array 
has gotten people used to not having to use slices much when proper containers 
would require them. Since arrays are really slices, it errodes the line 
between container and range, and I think that as proper containers are 
completed in std.container and enter mainstream use, it's going to throw a lot 
of people off, because they aren't going to function the quite same as arrays 
(primarily due to the fact that a container and a range are not the same thing 
with actual containers).

But regardless, while your suggestion might be a good idea in some cases, it's 
definitely not a good solution for static arrays. And I'm skeptical that it's a 
good idea in any case, but it would allow for immutable arrays to be used with 
range-based functions. It would likely be better, however, to simply make it 
so that slices of them can be used with range-based functions such as is the 
case with static arrays.

- Jonathan M Davis


Re: Immutable separator to join() doesn't work

2011-07-12 Thread Daniel Murphy
Jonathan M Davis jmdavisp...@gmx.com wrote in message 
news:mailman.1557.1310461819.14074.digitalmar...@puremagic.com...
 Personally, I'm
 _far_ more inclined to say that you should just expect to have to slice
 something when you pass it to a range-based function.

That's my thinking too.

 It would likely be better, however, to simply make it
 so that slices of them can be used with range-based functions such as is 
 the
 case with static arrays.

I really think this was always supposed to work, but the compiler was 
modified to allow slicing typedefs to result in typedefs.  Hopefully my 
patch for this will get pulled soon. 




Re: Immutable separator to join() doesn't work

2011-07-11 Thread Timon Gehr
Jonathan M Davis wrote:
 On Sunday 10 July 2011 21:09:27 Mehrdad wrote:
 I noticed that the code below doesn't work, and I was wondering if it's
 by design (hopefully not):

  immutable SEP = , ;
  [a, b].join(SEP);

 The fact that SEP is immutable(char[]) instead of immutable(char)[]
 shouldn't break the function.

 It most definitely breaks the function, and it's a limitation of templates.
 Templates are instantiated with the exact type that they're given, so the
 compiler tries to instantiate join with immutable(char[]), but join _can't_
 work with immutable(char[]), because it needs a mutable range. immutable
 ranges are worthless. If the compiler were smart enough to realize that it
 could instantiate join with immutable(char)[] and it would work, then you
 could use immutable(char[]), but since it isn't that smart, it doesn't work.
 The same problem happens with static arrays. They can't be used as ranges, so
 even though they'd work if the compiler picked a dynamic range as the type for
 the function, they don't work, because the compiler isn't that smart.

 The problem may be fixed at some point, but as it stands, it just doesn't work
 to use immutable arrays with range-based functions.

 - Jonathan M Davis

There is no such thing as an immutable range because the range abstraction is
based on mutation.
This does not make sense, because intuitively, immutable(char[]) is a range type
just as immutable(char)[] or char[] is a range type.
It is quite odd that a data structure can only be a D range if it may be 
modified...

It is not really a compiler issue, but one of library design. Maybe adding a
wrapper range to Phobos to iterate over immutable 'ranges' would be an 
improvement
to the current situation.

Cheers,
-Timon




Re: Immutable separator to join() doesn't work

2011-07-11 Thread Jonathan M Davis
On 2011-07-11 09:06, Timon Gehr wrote:
 Jonathan M Davis wrote:
  On Sunday 10 July 2011 21:09:27 Mehrdad wrote:
  I noticed that the code below doesn't work, and I was wondering if it's
  
  by design (hopefully not):
  immutable SEP = , ;
  [a, b].join(SEP);
  
  The fact that SEP is immutable(char[]) instead of immutable(char)[]
  shouldn't break the function.
  
  It most definitely breaks the function, and it's a limitation of
  templates. Templates are instantiated with the exact type that they're
  given, so the compiler tries to instantiate join with immutable(char[]),
  but join _can't_ work with immutable(char[]), because it needs a mutable
  range. immutable ranges are worthless. If the compiler were smart enough
  to realize that it could instantiate join with immutable(char)[] and it
  would work, then you could use immutable(char[]), but since it isn't
  that smart, it doesn't work. The same problem happens with static
  arrays. They can't be used as ranges, so even though they'd work if the
  compiler picked a dynamic range as the type for the function, they don't
  work, because the compiler isn't that smart.
  
  The problem may be fixed at some point, but as it stands, it just doesn't
  work to use immutable arrays with range-based functions.
  
  - Jonathan M Davis
 
 There is no such thing as an immutable range because the range abstraction
 is based on mutation.
 This does not make sense, because intuitively, immutable(char[]) is a range
 type just as immutable(char)[] or char[] is a range type.
 It is quite odd that a data structure can only be a D range if it may be
 modified...
 
 It is not really a compiler issue, but one of library design. Maybe adding
 a wrapper range to Phobos to iterate over immutable 'ranges' would be an
 improvement to the current situation.

??? A range is only of any value if you can process it. That generally 
requires calling popFront on it. That mutates it. So, sure, you can an 
immutable range, but it's useless, because you can't process it. And why 
should that be surprising? There are plenty of things that are essentially 
useless if they're immutable. Take a stream for instance. Like a range, it's 
altered as you use. So, you can't have an immutable stream - or if you did, it 
would be useless. Immutability can be very useful, but not being able to 
mutate something can really get in the way of doing anything with it. The same 
goes for const.

There has been some discussion in the past of trying to find a way to convert 
an immutable or const range to a tail-immutable or tail-const range (similar 
to how you can pass immutable(char[]) to a function which takes 
immutable(char)[] and have it work), but the language doesn't currently 
provide any way to do that, and it wouldn't necessarily make sense for all 
range types anyway. It's highly dependent on how their implemented and what 
they're actually iterating over.

It's definitely true that the template situation could use some improvement to 
better deal with immutable arrays, and an improvement to the type system to 
better handle tail-const for ranges where applicable would be desirable, but 
the fact remains that not everything can be fully const or immutable and be 
useful. It's just a fact of how const and immutable work. There's stuff that 
needs to be mutable, and when you make it so that you can't mutate them, 
they're useless.

- Jonathan M Davis


Re: Immutable separator to join() doesn't work

2011-07-11 Thread Timon Gehr
Jonathan M Davis wrote:
 On 2011-07-11 09:06, Timon Gehr wrote:
  Jonathan M Davis wrote:
   On Sunday 10 July 2011 21:09:27 Mehrdad wrote:
   I noticed that the code below doesn't work, and I was wondering if it's
  
   by design (hopefully not):
   immutable SEP = , ;
   [a, b].join(SEP);
  
   The fact that SEP is immutable(char[]) instead of immutable(char)[]
   shouldn't break the function.
  
   It most definitely breaks the function, and it's a limitation of
   templates. Templates are instantiated with the exact type that they're
   given, so the compiler tries to instantiate join with immutable(char[]),
   but join _can't_ work with immutable(char[]), because it needs a mutable
   range. immutable ranges are worthless. If the compiler were smart enough
   to realize that it could instantiate join with immutable(char)[] and it
   would work, then you could use immutable(char[]), but since it isn't
   that smart, it doesn't work. The same problem happens with static
   arrays. They can't be used as ranges, so even though they'd work if the
   compiler picked a dynamic range as the type for the function, they don't
   work, because the compiler isn't that smart.
  
   The problem may be fixed at some point, but as it stands, it just doesn't
   work to use immutable arrays with range-based functions.
  
   - Jonathan M Davis
 
  There is no such thing as an immutable range because the range abstraction
  is based on mutation.
  This does not make sense, because intuitively, immutable(char[]) is a range
  type just as immutable(char)[] or char[] is a range type.
  It is quite odd that a data structure can only be a D range if it may be
  modified...
 
  It is not really a compiler issue, but one of library design. Maybe adding
  a wrapper range to Phobos to iterate over immutable 'ranges' would be an
  improvement to the current situation.

 ??? A range is only of any value if you can process it. That generally
 requires calling popFront on it. That mutates it. So, sure, you can an
 immutable range, but it's useless, because you can't process it.

import std.range;
void main(){
int[] arr;
auto a=cast(immutable)map!a(arr);
assert(!isInputRange!(typeof(a))); // this passes

}

So no, you cannot have an immutable range because it cannot fulfill the range
interface.

 And why should that be surprising?

This is surprising:
immutable SEP = , ;

[a,b].join(SEP);
// -- nope! Guess what? That is because your array is not a range! Why? Easy! It
cannot be changed! See?
// -- I don't care, but this should work... I'll implement the function myself!

immutable SEP = , ;
string sep=SEP;
[a,b].join(sep); //sure thing

 There are plenty of things that are essentially
 useless if they're immutable. Take a stream for instance. Like a range, it's
 altered as you use. So, you can't have an immutable stream - or if you did, it
 would be useless.

You can. You can even have immutable IO if you choose the right abstractions ;).

 Immutability can be very useful, but not being able to
 mutate something can really get in the way of doing anything with it. The same
 goes for const.

You can always use it's value to create others.


 There has been some discussion in the past of trying to find a way to convert
 an immutable or const range to a tail-immutable or tail-const range (similar
 to how you can pass immutable(char[]) to a function which takes
 immutable(char)[] and have it work),
 but the language doesn't currently
 provide any way to do that, and it wouldn't necessarily make sense for all
 range types anyway. It's highly dependent on how their implemented and what
 they're actually iterating over.

I completely agree. It would be unnecessarily complicated (impossible?) to make
all ranges work as immutable that would meaningfully be able to. Also it would
give almost no benefit.

But immutable(T[]) should clearly be accepted where immutable(T)[] would be. 
I've
run across that problem myself
It is just annoying, even more so if you do not actually need the generosity
provided by those functions at all.


 It's definitely true that the template situation could use some improvement to
 better deal with immutable arrays, and an improvement to the type system to
 better handle tail-const for ranges where applicable would be desirable, but
 the fact remains that not everything can be fully const or immutable and be
 useful. It's just a fact of how const and immutable work. There's stuff that
 needs to be mutable, and when you make it so that you can't mutate them,
 they're useless.

 - Jonathan M Davis

Nothing needs to be mutable. It is possible to work with immutable values only,
but it is no always efficient.
Having an immutable range interface would be quite easy. popFront would just 
have
to return the next range instead of changing the current one.


Cheers,
-Timon


Re: Immutable separator to join() doesn't work

2011-07-11 Thread Jonathan M Davis
On 2011-07-11 13:30, Timon Gehr wrote:
 Jonathan M Davis wrote:
  On 2011-07-11 09:06, Timon Gehr wrote:
   Jonathan M Davis wrote:
On Sunday 10 July 2011 21:09:27 Mehrdad wrote:
I noticed that the code below doesn't work, and I was wondering if
it's

by design (hopefully not):
immutable SEP = , ;
[a, b].join(SEP);

The fact that SEP is immutable(char[]) instead of immutable(char)[]
shouldn't break the function.

It most definitely breaks the function, and it's a limitation of
templates. Templates are instantiated with the exact type that
they're given, so the compiler tries to instantiate join with
immutable(char[]), but join _can't_ work with immutable(char[]),
because it needs a mutable range. immutable ranges are worthless. If
the compiler were smart enough to realize that it could instantiate
join with immutable(char)[] and it would work, then you could use
immutable(char[]), but since it isn't that smart, it doesn't work.
The same problem happens with static arrays. They can't be used as
ranges, so even though they'd work if the compiler picked a dynamic
range as the type for the function, they don't work, because the
compiler isn't that smart.

The problem may be fixed at some point, but as it stands, it just
doesn't work to use immutable arrays with range-based functions.

- Jonathan M Davis
   
   There is no such thing as an immutable range because the range
   abstraction is based on mutation.
   This does not make sense, because intuitively, immutable(char[]) is a
   range type just as immutable(char)[] or char[] is a range type.
   It is quite odd that a data structure can only be a D range if it may
   be modified...
   
   It is not really a compiler issue, but one of library design. Maybe
   adding a wrapper range to Phobos to iterate over immutable 'ranges'
   would be an improvement to the current situation.
  
  ??? A range is only of any value if you can process it. That generally
  requires calling popFront on it. That mutates it. So, sure, you can an
  immutable range, but it's useless, because you can't process it.
 
 import std.range;
 void main(){
 int[] arr;
 auto a=cast(immutable)map!a(arr);
 assert(!isInputRange!(typeof(a))); // this passes
 
 }
 
 So no, you cannot have an immutable range because it cannot fulfill the
 range interface.
 
  And why should that be surprising?
 
 This is surprising:
 immutable SEP = , ;
 
 [a,b].join(SEP);
 // -- nope! Guess what? That is because your array is not a range! Why?
 Easy! It cannot be changed! See?
 // -- I don't care, but this should work... I'll implement the function
 myself!
 
 immutable SEP = , ;
 string sep=SEP;
 [a,b].join(sep); //sure thing
 
  There are plenty of things that are essentially
  useless if they're immutable. Take a stream for instance. Like a range,
  it's altered as you use. So, you can't have an immutable stream - or if
  you did, it would be useless.
 
 You can. You can even have immutable IO if you choose the right
 abstractions ;).
 
  Immutability can be very useful, but not being able to
  mutate something can really get in the way of doing anything with it. The
  same goes for const.
 
 You can always use it's value to create others.
 
  There has been some discussion in the past of trying to find a way to
  convert an immutable or const range to a tail-immutable or tail-const
  range (similar to how you can pass immutable(char[]) to a function which
  takes
  immutable(char)[] and have it work),
  but the language doesn't currently
  provide any way to do that, and it wouldn't necessarily make sense for
  all range types anyway. It's highly dependent on how their implemented
  and what they're actually iterating over.
 
 I completely agree. It would be unnecessarily complicated (impossible?) to
 make all ranges work as immutable that would meaningfully be able to. Also
 it would give almost no benefit.
 
 But immutable(T[]) should clearly be accepted where immutable(T)[] would
 be. I've run across that problem myself
 It is just annoying, even more so if you do not actually need the
 generosity provided by those functions at all.
 
  It's definitely true that the template situation could use some
  improvement to better deal with immutable arrays, and an improvement to
  the type system to better handle tail-const for ranges where applicable
  would be desirable, but the fact remains that not everything can be
  fully const or immutable and be useful. It's just a fact of how const
  and immutable work. There's stuff that needs to be mutable, and when you
  make it so that you can't mutate them, they're useless.
  
  - Jonathan M Davis
 
 Nothing needs to be mutable. It is possible to work with immutable values
 only, but it is no always efficient.
 Having an immutable range interface would be quite easy. popFront would
 just have to return the next range instead of changing the current one.


Re: Immutable separator to join() doesn't work

2011-07-11 Thread so

On Tue, 12 Jul 2011 00:37:04 +0300, so s...@so.so wrote:

Good thing is because the original range is mutable we don't need to  
worry about anything else.


Typo, original range is immutable


Re: Immutable separator to join() doesn't work

2011-07-11 Thread so
On Tue, 12 Jul 2011 00:01:55 +0300, Jonathan M Davis jmdavisp...@gmx.com  
wrote:



The solution is to fix template instantiation so that it's smarter when
dealing with static arrays and const or immutable arrays:
http://d.puremagic.com/issues/show_bug.cgi?id=6148

It's a language issue, not a design issue. Making ranges function like  
slists

(with head and tail or car and cdr) would be almost certainly be too
inefficient (particularly for ranges where save is not super cheap,  
though
it's at least supposed to be fairly cheap). Immutability might be nice,  
but it
does have its costs, and in this case, D's templates aren't currenly  
smart

enough to use immutable(E)[] instead of immutable(E[]). And it's not like
immutable ranges are going to work with non-array ranges anyway, so it's
arguably a good idea to just expect immutable and const ranges to not  
work

anyway.


There is a simple workaround for this type of ranges that are like  
iterators, which we know the beginning and the end.
We can improve isForwardRange!R by adding a line hasForwardRange!R. If it  
does have, we return an adaptor which gives us a mutable range.
Good thing is because the original range is mutable we don't need to worry  
about anything else.


Re: Immutable separator to join() doesn't work

2011-07-11 Thread Timon Gehr
so wrote:
 There is a simple workaround for this type of ranges that are like
 iterators, which we know the beginning and the end.
 We can improve isForwardRange!R by adding a line hasForwardRange!R. If it
 does have, we return an adaptor which gives us a mutable range.
 Good thing is because the original range is mutable we don't need to worry
 about anything else.

Wouldn't that be quite invasive? I imagine every function that would want to 
work
on ranges would then have to provide two versions, one that does the work and 
one
that calls the other version after having applied the adaptor(s)?

Cheers,
-Timon


Re: Immutable separator to join() doesn't work

2011-07-11 Thread so

On Tue, 12 Jul 2011 00:58:04 +0300, Timon Gehr timon.g...@gmx.ch wrote:

Wouldn't that be quite invasive? I imagine every function that would  
want to work
on ranges would then have to provide two versions, one that does the  
work and one

that calls the other version after having applied the adaptor(s)?

Cheers,
-Timon


Right, we probably need to change functions but no we don't need to  
overload any of them.


Re: Immutable separator to join() doesn't work

2011-07-11 Thread so

On Tue, 12 Jul 2011 00:58:04 +0300, Timon Gehr timon.g...@gmx.ch wrote:


so wrote:

There is a simple workaround for this type of ranges that are like
iterators, which we know the beginning and the end.
We can improve isForwardRange!R by adding a line hasForwardRange!R. If  
it

does have, we return an adaptor which gives us a mutable range.
Good thing is because the original range is mutable we don't need to  
worry

about anything else.


Wouldn't that be quite invasive? I imagine every function that would  
want to work
on ranges would then have to provide two versions, one that does the  
work and one

that calls the other version after having applied the adaptor(s)?

Cheers,
-Timon


In this case, not necessarily.
hasForwardRange could just be a global function that checks if its  
argument is an array and this i think would solve all our current problems.


Re: Immutable separator to join() doesn't work

2011-07-11 Thread Jonathan M Davis
On 2011-07-11 14:45, Timon Gehr wrote:
 Jonathan M Davis wrote:
  The solution is to fix template instantiation so that it's smarter when
  dealing with static arrays and const or immutable arrays:
  http://d.puremagic.com/issues/show_bug.cgi?id=6148
 
 Unless I am missing something essential, supporting this would turn the
 complexity of failing template function instantiations to Omega((time for
 matching)*2^(number of const/immutable arrays in the input)). I don't
 think this is too great.
 
  It's a language issue, not a design issue. Making ranges function like
  slists (with head and tail or car and cdr) would be almost certainly be
  too inefficient (particularly for ranges where save is not super cheap,
  though it's at least supposed to be fairly cheap).
 
 That Eg. join cannot take an immutable(char[]) is certainly a design issue.
 I think what you find to be a language issue are limitations inherent to
 templates that are very hard (NP hard in the general case) to overcome.
 
  Immutability might be nice, but it
  does have its costs, and in this case, D's templates aren't currenly
  smart enough to use immutable(E)[] instead of immutable(E[]).
 
 I claim they cannot get that smart. If I'm right, this turns it into a
 complete design issue.

I think that they can, but regardless, I don't think that it makes sense to 
redesign ranges at this point. The loss of immutable and const arrays is 
annoying but not all that big a deal. Worst case, casting immutable(E[]) to 
immutable(E)[] solves the problem.

  And it's not like
  immutable ranges are going to work with non-array ranges anyway, so it's
  arguably a good idea to just expect immutable and const ranges to not
  work anyway.
  
  - Jonathan M Davis
 
 immutable ranges don't exist in D. immutable arrays do. The issue is that
 many Phobos functions can only take ranges, what excludes immutable
 arrays. That is bad as immutable arrays share many properties with ranges
 and could be used as input to similar algorithms.
 
 This does not have top priority (at least for me), as it is just a mild
 annoyance that can be worked around. But it needs some thinking.

This enhancement request would make the situation with immutable and const 
arrays so that they're much more in line with mutable container types and 
static arrays:

http://d.puremagic.com/issues/show_bug.cgi?id=6289

- Jonathan M Davis


Re: Immutable separator to join() doesn't work

2011-07-11 Thread Daniel Murphy
Jonathan M Davis jmdavisp...@gmx.com wrote in message 
news:mailman.1552.1310429761.14074.digitalmar...@puremagic.com...
 This enhancement request would make the situation with immutable and const
 arrays so that they're much more in line with mutable container types and
 static arrays:

 http://d.puremagic.com/issues/show_bug.cgi?id=6289

 - Jonathan M Davis

WAIT WHAT?  That doesn't work?!? 




Immutable separator to join() doesn't work

2011-07-10 Thread Mehrdad
I noticed that the code below doesn't work, and I was wondering if it's 
by design (hopefully not):


immutable SEP = , ;
[a, b].join(SEP);

The fact that SEP is immutable(char[]) instead of immutable(char)[] 
shouldn't break the function.


Re: Immutable separator to join() doesn't work

2011-07-10 Thread Jonathan M Davis
On Sunday 10 July 2011 21:09:27 Mehrdad wrote:
 I noticed that the code below doesn't work, and I was wondering if it's
 by design (hopefully not):
 
  immutable SEP = , ;
  [a, b].join(SEP);
 
 The fact that SEP is immutable(char[]) instead of immutable(char)[]
 shouldn't break the function.

It most definitely breaks the function, and it's a limitation of templates. 
Templates are instantiated with the exact type that they're given, so the 
compiler tries to instantiate join with immutable(char[]), but join _can't_ 
work with immutable(char[]), because it needs a mutable range. immutable 
ranges are worthless. If the compiler were smart enough to realize that it 
could instantiate join with immutable(char)[] and it would work, then you 
could use immutable(char[]), but since it isn't that smart, it doesn't work. 
The same problem happens with static arrays. They can't be used as ranges, so 
even though they'd work if the compiler picked a dynamic range as the type for 
the function, they don't work, because the compiler isn't that smart.

The problem may be fixed at some point, but as it stands, it just doesn't work 
to use immutable arrays with range-based functions.

- Jonathan M Davis


Re: Immutable separator to join() doesn't work

2011-07-10 Thread Mehrdad

On 7/10/2011 9:17 PM, Jonathan M Davis wrote:

On Sunday 10 July 2011 21:09:27 Mehrdad wrote:

I noticed that the code below doesn't work, and I was wondering if it's
by design (hopefully not):

  immutable SEP = , ;
  [a, b].join(SEP);

The fact that SEP is immutable(char[]) instead of immutable(char)[]
shouldn't break the function.

It most definitely breaks the function, and it's a limitation of templates.
Templates are instantiated with the exact type that they're given, so the
compiler tries to instantiate join with immutable(char[]), but join _can't_
work with immutable(char[]), because it needs a mutable range. immutable
ranges are worthless. If the compiler were smart enough to realize that it
could instantiate join with immutable(char)[] and it would work, then you
could use immutable(char[]), but since it isn't that smart, it doesn't work.
The same problem happens with static arrays. They can't be used as ranges, so
even though they'd work if the compiler picked a dynamic range as the type for
the function, they don't work, because the compiler isn't that smart.

The problem may be fixed at some point, but as it stands, it just doesn't work
to use immutable arrays with range-based functions.

- Jonathan M Davis

Hm... interesting, I hope it's fixed sometime then. :)
Thanks for the info!