immutable/mutable strings
Hey all, I am trying to get a full understanding of mutable/immutable string syntax. I understand it to be true that 'char[]' is mutable and that 'string' is immutable and is the same as invariant(char)[]. If I am incorrect on any of this, please let me know. The page: http://www.digitalmars.com/d/2.0/arrays.html gives the following example as an initialization error: char[] str1 = "abc"; // error, "abc" is not mutable I assume this is an error because of incompatible types (trying to set a mutable type to an immutable value. However, and this confuses me. The page: http://www.digitalmars.com/d/2.0/cppstrings.html char[] s1 = "hello world"; char[] s2 = "goodbye ".dup; s2[8..13] = s1[6..11]; // s2 is "goodbye world" If what I have assumed is true so far, why is the following line from above allowed?: char[] s1 = "hello world"; On a slightly different note, why does the compiler allow me to set an immutable value to a mutable type if it is an error? I am using dmd v1.033 -- Is this for v2.xx only? Thanks for any information that you can provide and sorry if these questions have already been answered. Thanks, Zane
Re: immutable/mutable strings
On Wed, Nov 19, 2008 at 8:13 PM, Zane <[EMAIL PROTECTED]> wrote: > Hey all, > > I am trying to get a full understanding of mutable/immutable string syntax. > I understand it to be true that 'char[]' is mutable and that 'string' is > immutable and is the same as invariant(char)[]. If I am incorrect on any of > this, please let me know. That's all correct. > On a slightly different note, why does the compiler allow me to set an > immutable value to a mutable type if it is an error? I am using dmd v1.033 > -- Is this for v2.xx only? Thanks for any information that you can provide > and sorry if these questions have already been answered. Yes. The whole section on const and invariant is D2 only. If you click the "D 1" link at the top left, you'll get to the D 1 specification. The Digital Mars website kind of .. "guides" you into D2 with little mention of D1.
Re: immutable/mutable strings
Jarrett Billingsley Wrote: > On Wed, Nov 19, 2008 at 8:13 PM, Zane <[EMAIL PROTECTED]> wrote: > > Hey all, > > > > I am trying to get a full understanding of mutable/immutable string syntax. > > I understand it to be true that 'char[]' is mutable and that 'string' is > > immutable and is the same as invariant(char)[]. If I am incorrect on any > > of this, please let me know. > > That's all correct. > > > On a slightly different note, why does the compiler allow me to set an > > immutable value to a mutable type if it is an error? I am using dmd v1.033 > > -- Is this for v2.xx only? Thanks for any information that you can provide > > and sorry if these questions have already been answered. > > Yes. The whole section on const and invariant is D2 only. If you > click the "D 1" link at the top left, you'll get to the D 1 > specification. The Digital Mars website kind of .. "guides" you into > D2 with little mention of D1. Thanks for your quick response. So then as in the example given, in D2, is this initialization allowed or was it a typo/mistake in the example?: char[] s1 = "hello world"; Thanks again, Zane
Re: immutable/mutable strings
On Wed, Nov 19, 2008 at 8:35 PM, Zane <[EMAIL PROTECTED]> wrote: > Jarrett Billingsley Wrote: > >> On Wed, Nov 19, 2008 at 8:13 PM, Zane <[EMAIL PROTECTED]> wrote: >> > Hey all, >> > >> > I am trying to get a full understanding of mutable/immutable string >> > syntax. I understand it to be true that 'char[]' is mutable and that >> > 'string' is immutable and is the same as invariant(char)[]. If I am >> > incorrect on any of this, please let me know. >> >> That's all correct. >> >> > On a slightly different note, why does the compiler allow me to set an >> > immutable value to a mutable type if it is an error? I am using dmd >> > v1.033 -- Is this for v2.xx only? Thanks for any information that you can >> > provide and sorry if these questions have already been answered. >> >> Yes. The whole section on const and invariant is D2 only. If you >> click the "D 1" link at the top left, you'll get to the D 1 >> specification. The Digital Mars website kind of .. "guides" you into >> D2 with little mention of D1. > > Thanks for your quick response. So then as in the example given, in D2, is > this initialization allowed or was it a typo/mistake in the example?: > > char[] s1 = "hello world"; > I'm not sure, I haven't touched D2 yet.
Re: immutable/mutable strings
Zane wrote: > Jarrett Billingsley Wrote: > >> On Wed, Nov 19, 2008 at 8:13 PM, Zane <[EMAIL PROTECTED]> wrote: >>> Hey all, >>> >>> I am trying to get a full understanding of mutable/immutable string syntax. >>> I understand it to be true that 'char[]' is mutable and that 'string' is >>> immutable and is the same as invariant(char)[]. If I am incorrect on any >>> of this, please let me know. >> That's all correct. >> >>> On a slightly different note, why does the compiler allow me to set an >>> immutable value to a mutable type if it is an error? I am using dmd v1.033 >>> -- Is this for v2.xx only? Thanks for any information that you can provide >>> and sorry if these questions have already been answered. >> Yes. The whole section on const and invariant is D2 only. If you >> click the "D 1" link at the top left, you'll get to the D 1 >> specification. The Digital Mars website kind of .. "guides" you into >> D2 with little mention of D1. > > Thanks for your quick response. So then as in the example given, in D2, is > this initialization allowed or was it a typo/mistake in the example?: > > char[] s1 = "hello world"; > > Thanks again, > Zane Please file a bug. The whole cppstrings.html page hasn't been updated to properly reflect 2.0 const semantics. Later, Brad
Aliasing immutable and mutable data
Is doing something like: auto someInstance = new immutable(SomeClass); considered to be casting, where all bets are off, or is it supposed to be safe? If it's supposed to be safe, below is an example of where it's not. If it's supposed to be like casting, then what's a safe way of creating immutable class instances? import std.stdio; uint[] array; class A { uint[] AArray; this(uint[] inArray) { AArray = inArray; } } void main() { array = new uint[10]; auto bar = new immutable(A)(array); writeln(bar.AArray); array[0] = 1; writeln(bar.AArray); }
Re: Aliasing immutable and mutable data
On Wed, 11 Mar 2009 16:18:17 +0300, dsimcha wrote: Is doing something like: auto someInstance = new immutable(SomeClass); considered to be casting, where all bets are off, or is it supposed to be safe? If it's supposed to be safe, below is an example of where it's not. If it's supposed to be like casting, then what's a safe way of creating immutable class instances? import std.stdio; uint[] array; class A { uint[] AArray; this(uint[] inArray) { AArray = inArray; } } void main() { array = new uint[10]; auto bar = new immutable(A)(array); writeln(bar.AArray); array[0] = 1; writeln(bar.AArray); } http://www.digitalmars.com/d/2.0/accu-functional.pdf IIRC, the following syntax was proposed: auto foo = new invariant Foo(arg1, arg2); class Foo { this() { // mutable version } this() invariant { // invariant version (with check and stuff, not implemented yet) } }
Logical Const using a Mutable template
This came up in discussion and I think the behavior is safe and usable when wanting to change class data in a const function. http://article.gmane.org/gmane.comp.lang.d.general/43476 One limitation is that value types declared as Mutable (Mutable!(int)) can not be changed if the encapsulating class is declared immutable. For this reason a Mutable value can not be changed inside a const function. I think this is acceptable. Another limitation appears to be an issue with alias this. It is commented as a //FIXME in the code. https://gist.github.com/721066 An example usage looks like: class Inner { int n; } class A { Mutable!(int*) n; Mutable!(int) n2; Mutable!(Inner) innerClass; this() { n = new int; innerClass = new Inner; } void foo( int num ) { n2 = num; } void bar( int num ) const { innerClass.n = num; } } auto aImmu = new immutable(A); auto aMu = new A; int i = 8; *aImmu.n = i, aImmu.bar(6), *aMu.n = i, aMu.n = &i, aMu.n2 = i, aMu.bar(6), aMu.foo(6),
const and mutable declarations in one union
Consider following definition: |class Node |{ |union |{ |protected Rect _rect; |const struct |{ |short x, y; |ushort width, height; |} |} |setRect(...) { ... } |} The point is to have a readonly view of data (x, y, width, height), protected mutable view of same data (_rect), and an interface to set it publicly (setRect). 1. Is this declaration is legal? (const and mutable definitions in one union) 2. Is there a difference between const and invariant struct? (I guess it should) The current implementation seems yielding undefined behavior in this case. If I set initial const values in constructor everything works as expected. If I set initial const values in definition, the whole union seems to be immutable, eg. setting ``_rect`` do not have an effect. -- serg.
main.d(61): Error: temp_[i_] isn't mutable
Hi there, I'm converting the following C++ function to D: void negate () { const std::size_t max_chars_ = sizeof (CharT) == 1 ? num_chars : num_wchar_ts; CharT curr_char_ = sizeof (CharT) == 1 ? -128 : 0; string temp_; const CharT *curr_ = _charset.c_str (); const CharT *chars_end_ = curr_ + _charset.size (); _negated = !_negated; temp_.resize (max_chars_ - _charset.size ()); CharT *ptr_ = const_cast (temp_.c_str ()); std::size_t i_ = 0; while (curr_ < chars_end_) { while (*curr_ > curr_char_) { *ptr_ = curr_char_; ++ptr_; ++curr_char_; ++i_; } ++curr_char_; ++curr_; ++i_; } for (; i_ < max_chars_; ++i_) { *ptr_ = curr_char_; ++ptr_; ++curr_char_; } _charset = temp_; } Here's the complete source: module main; import std.algorithm; import std.string; template regex(StringT) { struct basic_string_token { bool _negated = false; StringT _charset; typedef typeof(StringT.init[0]) CharT; enum size_t MAX_CHARS = CharT.max + 1; this(const bool negated_, ref StringT charset_) { _negated = negated_; _charset = charset_; } void remove_duplicates() { _charset.sort; _charset = squeeze(_charset); } void normalise() { if (_charset.length == MAX_CHARS) { _negated = !_negated; _charset.clear(); } else if (_charset.length > MAX_CHARS / 2) { negate(); } } void negate() { CharT curr_char_ = MAX_CHARS == 256 ? 0x80 : 0; StringT temp_; size_t curr_ = 0; size_t end_ = _charset.length; size_t i_ = 0; _negated = !_negated; temp_.length = MAX_CHARS - end_; while (curr_ < end_) { while (_charset[curr_] > curr_char_) { temp_[i_] = curr_char_; ++curr_char_; ++i_; } ++curr_char_; ++curr_; ++i_; } for (; i_ < MAX_CHARS; ++i_) { temp_ ~= curr_char_; ++curr_char_; } _charset = temp_; } }; } int main(char[][]argv) { regex!(string).basic_string_token token_; token_._charset = "cccbba"; token_.remove_duplicates(); token_.negate(); return 0; } Can anyone explain the error 'main.d(61): Error: temp_[i_] isn't mutable'? Can I use pointers instead like the C++ code? What's the best approach for maximum efficiency in D (pointers would make the conversion easier to, I guess). Thanks, Ben
Re: Logical Const using a Mutable template
On 11/30/2010 09:30 AM, Jesse Phillips wrote: This came up in discussion and I think the behavior is safe and usable when wanting to change class data in a const function. http://article.gmane.org/gmane.comp.lang.d.general/43476 One limitation is that value types declared as Mutable (Mutable!(int)) can not be changed if the encapsulating class is declared immutable. For this reason a Mutable value can not be changed inside a const function. I think this is acceptable. Another limitation appears to be an issue with alias this. It is commented as a //FIXME in the code. https://gist.github.com/721066 An example usage looks like: class Inner { int n; } class A { Mutable!(int*) n; Mutable!(int) n2; Mutable!(Inner) innerClass; this() { n = new int; innerClass = new Inner; } void foo( int num ) { n2 = num; } void bar( int num ) const { innerClass.n = num; } } auto aImmu = new immutable(A); auto aMu = new A; int i = 8; *aImmu.n = i, aImmu.bar(6), *aMu.n = i, aMu.n =&i, aMu.n2 = i, aMu.bar(6), aMu.foo(6), It is not enough to forward opAssign and opEquals. Any operator should be handled. For example, change the implementation of A.foo to n2 += 1; and you will get a segfault during compilation. You could add more kludge with operator overloads but I don't think it is worth the effort. It makes more sense to wait until "alias this" bugs are fixed. On the other hand, we may wait forever since the way "alias this" should handle operators has never been specified.
Re: Logical Const using a Mutable template
Max Samukha Wrote: > On 11/30/2010 09:30 AM, Jesse Phillips wrote: > > This came up in discussion and I think the behavior is safe and usable when > > wanting to change class data in a const function. > > > > http://article.gmane.org/gmane.comp.lang.d.general/43476 > > > > One limitation is that value types declared as Mutable (Mutable!(int)) can > > not be changed if the encapsulating class is declared immutable. For this > > reason a Mutable value can not be changed inside a const function. I think > > this is acceptable. > > > > Another limitation appears to be an issue with alias this. It is commented > > as a //FIXME in the code. > > > > https://gist.github.com/721066 > > It is not enough to forward opAssign and opEquals. Any operator should > be handled. For example, change the implementation of A.foo to > > n2 += 1; > > and you will get a segfault during compilation. > > You could add more kludge with operator overloads but I don't think it > is worth the effort. It makes more sense to wait until "alias this" bugs > are fixed. On the other hand, we may wait forever since the way "alias > this" should handle operators has never been specified. > The intent isn't to work around alias this bugs. It is to provide mutation in a const function, but with the guarantee that it will not result in undefined behavior. (I should have stated that first, but it was getting late). Concurrency shouldn't be any different from having a reference in a class you are sharing. Sharing immutable objects should be fine as they still can not have their state changed. The rules for this are: * Only mutable data can be assigned to a Mutable * Modification of referenced fields can be modified (inner class fields, pointer targets) I'll be back to finish this in a bit.
Re: Logical Const using a Mutable template
Jesse Phillips Wrote: > The rules for this are: > > * Only mutable data can be assigned to a Mutable > * Modification of referenced fields can be modified (inner class fields, > pointer targets) > > I'll be back to finish this in a bit. * Value types can be modified if the encapsulating class is not declared const/immutable And I have come up with 2 major concerns related to immutable classes. Would an inner class be placed in read-only memory in instantiating an immutable class: class A { Mutable!(Inner) innerclass; this() { innerclass = new Inner; } // Is innerclass placed in read-only memory } new immutable(A); And what about when an immutable instance is passed to a thread or network. Would the innerclass be placed in read-only memory for the new thread/machine. And looking over it again, I found that I wasn't using the opAssign const functions, they didn't meet the requirements. So I think a working alias this would allow the template to be: (The important check being that Mutables are unqualified) struct Mutable( T ) if ( is( T : Unqual!T ) ) { private T _payload; this( T t ) { _payload = t; } @trusted @property ref T get( )( ) const { T* p = cast( T* )&_payload; return *p; } alias get this; } https://gist.github.com/721066
Re: const and mutable declarations in one union
Reply to Sergey, Consider following definition: |class Node |{ |union |{ |protected Rect _rect; |const struct |{ |short x, y; |ushort width, height; |} |} |setRect(...) { ... } |} The point is to have a readonly view of data (x, y, width, height), protected mutable view of same data (_rect), and an interface to set it publicly (setRect). 1. Is this declaration is legal? (const and mutable definitions in one union) 2. Is there a difference between const and invariant struct? (I guess it cost = "you can't chnage it" invariant = "Will not change at all" should) The current implementation seems yielding undefined behavior in this case. If I set initial const values in constructor everything works as expected. If I set initial const values in definition, the whole union seems to be immutable, eg. setting ``_rect`` do not have an effect. Setting it in a decleration my put it in read only memeory or even hard code it into expressions
Re: const and mutable declarations in one union
On 1/14/2009 2:18 AM, BCS wrote: cost = "you can't chnage it" invariant = "Will not change at all" ... Setting it in a decleration my put it in read only memeory or even hard code it into expressions Well this is usually oblivious, but not in case of union. Which might be a little bit different.. I have an impression that invariant may put data to readonly section, but not const. This of course might be just an invalid usage of union from programmer's side, which righteously yeld undefined behavior. but I was hoping for a special treat of const (not invariant) in context of union. -- serg.
Re: const and mutable declarations in one union
Sergey Kovrov wrote: > On 1/14/2009 2:18 AM, BCS wrote: >> cost = "you can't chnage it" >> invariant = "Will not change at all" > >> Setting it in a decleration my put it in read only memeory or even hard >> code it into expressions > > Well this is usually oblivious, but not in case of union. Which might be > a little bit different.. I have an impression that invariant may put > data to readonly section, but not const. > > This of course might be just an invalid usage of union from programmer's > side, which righteously yeld undefined behavior. but I was hoping for a > special treat of const (not invariant) in context of union. > > > -- serg. Yeah, if this doesn't cause compilation to fail, I'm pretty sure it should. You're giving the compiler two contradictory statements regarding the mutability of that data. Rather, why not use this? > class Node > { > protected Rect _rect; > > short x() { return _rect.x; } > short y() { return _rect.y; } > ushort width() { return _rect.width; } > ushort height() { return _rect.height; } > > setRect(...) { ... } > } This will have more or less the same outward-facing interface, whilst actually working. Incidentally, I've haven't used opDot before, but this might also work: > class Node > { > protected Rect _rect; > > const Rect* opDot() { return &_rect; } > > setRect(...) { ... } > } Finally, if you have questions on how to do something, please direct them to the D.learn newsgroup in future. -- Daniel
Re: const and mutable declarations in one union
On 1/14/2009 3:18 AM, Daniel Keep wrote: Finally, if you have questions on how to do something, please direct them to the D.learn newsgroup in future. Well, this was not exactly point of my question - how to do this. There are few "valid" ways - getters/setters (properties) is one of them, to have const pointers to mutable data is other, and perhaps there could be even more. I just wanted to point if such usage of union is invalid, it will be nice to assert this in compile time or at least have note in specs. Or rather I wanted to comment on using invariant and const in this context lead to same effect - immutable declaration, which is feels wrong. If I were used invariant - this would be exactly what I expect. But for const I hope to get readonly view of any data, be it immutable or not. -- serg.
Re: main.d(61): Error: temp_[i_] isn't mutable
On 06/19/2010 12:30 PM, Ben Hanson wrote: Hi there, I'm converting the following C++ function to D: void negate () { const std::size_t max_chars_ = sizeof (CharT) == 1 ? num_chars : num_wchar_ts; CharT curr_char_ = sizeof (CharT) == 1 ? -128 : 0; string temp_; const CharT *curr_ = _charset.c_str (); const CharT *chars_end_ = curr_ + _charset.size (); _negated = !_negated; temp_.resize (max_chars_ - _charset.size ()); CharT *ptr_ = const_cast (temp_.c_str ()); std::size_t i_ = 0; while (curr_< chars_end_) { while (*curr_> curr_char_) { *ptr_ = curr_char_; ++ptr_; ++curr_char_; ++i_; } ++curr_char_; ++curr_; ++i_; } for (; i_< max_chars_; ++i_) { *ptr_ = curr_char_; ++ptr_; ++curr_char_; } _charset = temp_; } Here's the complete source: module main; import std.algorithm; import std.string; template regex(StringT) { struct basic_string_token { bool _negated = false; StringT _charset; typedef typeof(StringT.init[0]) CharT; enum size_t MAX_CHARS = CharT.max + 1; this(const bool negated_, ref StringT charset_) { _negated = negated_; _charset = charset_; } void remove_duplicates() { _charset.sort; _charset = squeeze(_charset); } void normalise() { if (_charset.length == MAX_CHARS) { _negated = !_negated; _charset.clear(); } else if (_charset.length> MAX_CHARS / 2) { negate(); } } void negate() { CharT curr_char_ = MAX_CHARS == 256 ? 0x80 : 0; StringT temp_; size_t curr_ = 0; size_t end_ = _charset.length; size_t i_ = 0; _negated = !_negated; temp_.length = MAX_CHARS - end_; while (curr_< end_) { while (_charset[curr_]> curr_char_) { temp_[i_] = curr_char_; ++curr_char_; ++i_; } ++curr_char_; ++curr_; ++i_; } for (; i_< MAX_CHARS; ++i_) { temp_ ~= curr_char_; ++curr_char_; } _charset = temp_; } }; } int main(char[][]argv) { regex!(string).basic_string_token token_; token_._charset = "cccbba"; token_.remove_duplicates(); token_.negate(); return 0; } Can anyone explain the error 'main.d(61): Error: temp_[i_] isn't mutable'? Can I use pointers instead like the C++ code? What's the best approach for maximum efficiency in D (pointers would make the conversion easier to, I guess). Thanks, Ben because strings aren't mutable. char[]'s on the other hand are, so you could just change temp_'s type to import std.traits; Unqual!(typeof(StringT.init[0]))[] temp_; or something like that.
Re: main.d(61): Error: temp_[i_] isn't mutable
On Sat, 19 Jun 2010 17:30:26 + (UTC), Ben Hanson wrote: > Here's the complete source: > > module main; > > import std.algorithm; > import std.string; > > template regex(StringT) > { > struct basic_string_token > { > bool _negated = false; > StringT _charset; > typedef typeof(StringT.init[0]) CharT; > enum size_t MAX_CHARS = CharT.max + 1; > > this(const bool negated_, ref StringT charset_) > { > _negated = negated_; > _charset = charset_; > } > > void remove_duplicates() > { > _charset.sort; > _charset = squeeze(_charset); > } > > void normalise() > { > if (_charset.length == MAX_CHARS) > { > _negated = !_negated; > _charset.clear(); > } > else if (_charset.length > MAX_CHARS / 2) > { > negate(); > } > } > > void negate() > { > CharT curr_char_ = MAX_CHARS == 256 ? 0x80 : 0; > StringT temp_; > size_t curr_ = 0; > size_t end_ = _charset.length; > size_t i_ = 0; > > _negated = !_negated; > temp_.length = MAX_CHARS - end_; > > while (curr_ < end_) > { > while (_charset[curr_] > curr_char_) > { > temp_[i_] = curr_char_; > ++curr_char_; > ++i_; > } > > ++curr_char_; > ++curr_; > ++i_; > } > > for (; i_ < MAX_CHARS; ++i_) > { > temp_ ~= curr_char_; > ++curr_char_; > } > > _charset = temp_; > } > }; > } > > int main(char[][]argv) > { > regex!(string).basic_string_token token_; > > token_._charset = "cccbba"; > token_.remove_duplicates(); > token_.negate(); > return 0; > } > > Can anyone explain the error 'main.d(61): Error: temp_[i_] isn't > mutable'? Can I use pointers instead like the C++ code? What's the > best approach for maximum efficiency in D (pointers would make the > conversion easier to, I guess). > > Thanks, > > Ben "string" is actually an alias for "immutable(char)[]" (and similarly for the other string types), so its contents are not modifiable, though its length can be adjusted and contents appended. If you need to be able to modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward.
Re: main.d(61): Error: temp_[i_] isn't mutable
> because strings aren't mutable. char[]'s on the other hand are, so you > could just change temp_'s type to > import std.traits; > Unqual!(typeof(StringT.init[0]))[] temp_; > or something like that. Thanks Ellery.
Re: main.d(61): Error: temp_[i_] isn't mutable
Hi Justin, == Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s article > "string" is actually an alias for "immutable(char)[]" (and similarly for > the other string types), so its contents are not modifiable, though its > length can be adjusted and contents appended. If you need to be able to > modify the characters, just use char[] instead. You can then use the > .idup property to get a string afterward. Thanks for the clarification! Regards, Ben
Re: main.d(61): Error: temp_[i_] isn't mutable
== Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s > "string" is actually an alias for "immutable(char)[]" (and similarly for > the other string types), so its contents are not modifiable, though its > length can be adjusted and contents appended. If you need to be able to > modify the characters, just use char[] instead. You can then use the > .idup property to get a string afterward. I'm converted temp_ to CharT[] as suggested, but the conversion back to a string is failing: _charset = temp_.idup; main.d(76): Error: cannot implicitly convert expression (_adDupT((& D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast (string)temp_)) of type immutable(CharT)[] to string
Re: main.d(61): Error: temp_[i_] isn't mutable
Ben Hanson wrote: == Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s "string" is actually an alias for "immutable(char)[]" (and similarly for the other string types), so its contents are not modifiable, though its length can be adjusted and contents appended. If you need to be able to modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward. I'm converted temp_ to CharT[] as suggested, but the conversion back to a string is failing: _charset = temp_.idup; main.d(76): Error: cannot implicitly convert expression (_adDupT((& D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast (string)temp_)) of type immutable(CharT)[] to string Would it work for you if the regex template took the character type instead of the string type? The relevant lines: template regex(CharT) { // ... alias CharT[] StringT; StringT _charset; enum size_t MAX_CHARS = CharT.max + 1; // ... _charset = squeeze(_charset.idup).dup; And then, in main: regex!(char).basic_string_token token_; Ali
Re: main.d(61): Error: temp_[i_] isn't mutable
On 06/20/2010 12:56 PM, Ali Çehreli wrote: Ben Hanson wrote: == Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s "string" is actually an alias for "immutable(char)[]" (and similarly for the other string types), so its contents are not modifiable, though its length can be adjusted and contents appended. If you need to be able to modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward. I'm converted temp_ to CharT[] as suggested, but the conversion back to a string is failing: _charset = temp_.idup; main.d(76): Error: cannot implicitly convert expression (_adDupT((& D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast (string)temp_)) of type immutable(CharT)[] to string Would it work for you if the regex template took the character type instead of the string type? The relevant lines: template regex(CharT) { // ... alias CharT[] StringT; StringT _charset; enum size_t MAX_CHARS = CharT.max + 1; // ... _charset = squeeze(_charset.idup).dup; And then, in main: regex!(char).basic_string_token token_; Ali IMHO it's more general if the regexp took the string type as a parameter. This is because later that is easier generalizable to accepting a range that's different from an array. My dream: to have a compile-time-generated regex engine that can operate on any input stream. Andrei
Re: main.d(61): Error: temp_[i_] isn't mutable
On Sun, 20 Jun 2010 12:01:31 + (UTC), Ben Hanson wrote: > > == Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s > > "string" is actually an alias for "immutable(char)[]" (and > similarly for > > the other string types), so its contents are not modifiable, though > its > > length can be adjusted and contents appended. If you need to be > able to > > modify the characters, just use char[] instead. You can then use the > > .idup property to get a string afterward. > > I'm converted temp_ to CharT[] as suggested, but the conversion back > to a string is failing: > > _charset = temp_.idup; > > main.d(76): Error: cannot implicitly convert expression (_adDupT((& > D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast > (string)temp_)) of type immutable(CharT)[] to string Sorry I missed this on the first run through. Since you're using typedef to create your CharT type, it will create a type independent from all the others, meaning no implicit casts to or from it. "alias" is the equivalent to a C/C++ "typedef", and that should fix the compilation error.
Re: main.d(61): Error: temp_[i_] isn't mutable
On 06/20/2010 07:01 AM, Ben Hanson wrote: == Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s "string" is actually an alias for "immutable(char)[]" (and similarly for the other string types), so its contents are not modifiable, though its length can be adjusted and contents appended. If you need to be able to modify the characters, just use char[] instead. You can then use the .idup property to get a string afterward. I'm converted temp_ to CharT[] as suggested, but the conversion back to a string is failing: _charset = temp_.idup; main.d(76): Error: cannot implicitly convert expression (_adDupT((& D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast (string)temp_)) of type immutable(CharT)[] to string import std.conv; ... _charset = to!(typeof(_charset))(temp_); "to" converts strings of any width and mutability to strings of any width and mutability. Andrei
Re: main.d(61): Error: temp_[i_] isn't mutable
Andrei Alexandrescu wrote: > IMHO it's more general if the regexp took the string type as a > parameter. This is because later that is easier generalizable to > accepting a range that's different from an array. Agreed. Given T which may be an immutable type, what is the cleanest way of creating a mutable copy of that type? typeof(array.dup) works on arrays but what if T is a value type or any type where .dup doesn't exist? Ali
Re: main.d(61): Error: temp_[i_] isn't mutable
On 06/20/2010 02:29 PM, Ali Çehreli wrote: Andrei Alexandrescu wrote: > IMHO it's more general if the regexp took the string type as a > parameter. This is because later that is easier generalizable to > accepting a range that's different from an array. Agreed. Given T which may be an immutable type, what is the cleanest way of creating a mutable copy of that type? typeof(array.dup) works on arrays but what if T is a value type or any type where .dup doesn't exist? Ali std.conv.to should work with most sensible combinations. Andrei
Re: main.d(61): Error: temp_[i_] isn't mutable
Hi Andrei, == Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article > On 06/20/2010 12:56 PM, Ali Çehreli wrote: > > Ben Hanson wrote: > >> == Quote from Justin Spahr-Summers (justin.spahrsumm...@gmail.com)'s > >>> "string" is actually an alias for "immutable(char)[]" (and > >> similarly for > >>> the other string types), so its contents are not modifiable, though > >> its > >>> length can be adjusted and contents appended. If you need to be > >> able to > >>> modify the characters, just use char[] instead. You can then use the > >>> .idup property to get a string afterward. > >> > >> I'm converted temp_ to CharT[] as suggested, but the conversion back > >> to a string is failing: > >> > >> _charset = temp_.idup; > >> > >> main.d(76): Error: cannot implicitly convert expression (_adDupT((& > >> D58TypeInfo_AT4main14__T5regexTAyaZ18basic_string_token5CharT6__initZ),cast > >> > >> (string)temp_)) of type immutable(CharT)[] to string > > > > > > Would it work for you if the regex template took the character type > > instead of the string type? > > > > The relevant lines: > > > > template regex(CharT) > > { > > // ... > > alias CharT[] StringT; > > StringT _charset; > > enum size_t MAX_CHARS = CharT.max + 1; > > // ... > > _charset = squeeze(_charset.idup).dup; > > > > And then, in main: > > > > regex!(char).basic_string_token token_; > > > > Ali > IMHO it's more general if the regexp took the string type as a > parameter. This is because later that is easier generalizable to > accepting a range that's different from an array. > My dream: to have a compile-time-generated regex engine that can operate > on any input stream. > Andrei I'm currently using strings for the regex strings themselves. In lexertl, I use templated free functions what work with iterators, which means input can come from different sources. This sounds like the kind of thing you are talking about? Regards, Ben
Re: main.d(61): Error: temp_[i_] isn't mutable
On 06/21/2010 03:37 AM, Ben Hanson wrote: I'm currently using strings for the regex strings themselves. In lexertl, I use templated free functions what work with iterators, which means input can come from different sources. This sounds like the kind of thing you are talking about? Regards, Ben Sounds about right! Andrei
Should conversion of mutable return value to immutable allowed?
Implicit conversions to immutable in the following two functions feel harmless. Has this been discussed before? string foo() { char[] s; return s; // Error: cannot implicitly convert expression //(s) of type char[] to string } string bar() { char[] s; return s ~ s; // Error: cannot implicitly convert expression //(s ~ s) of type char[] to string } Is there a reason why that's not possible? I am sure there must be other cases that at least I would find harmless. :) Ali
Re: Should conversion of mutable return value to immutable allowed?
On 02/24/2011 07:08 PM, Ali Çehreli wrote: Implicit conversions to immutable in the following two functions feel harmless. Has this been discussed before? string foo() { char[] s; return s; // Error: cannot implicitly convert expression // (s) of type char[] to string } string bar() { char[] s; return s ~ s; // Error: cannot implicitly convert expression // (s ~ s) of type char[] to string } Is there a reason why that's not possible? I am sure there must be other cases that at least I would find harmless. :) Ali I'm all for that. Can hardly how auto conversion in the sense mutable --> immutable could be harmful, but may miss a meaningful point. This would esp be nice for strings, since we regularly need to use char arrays to construct textual content. Denis -- _ vita es estrany spir.wikidot.com
Re: Should conversion of mutable return value to immutable allowed?
On 02/24/2011 10:28 AM, spir wrote: > On 02/24/2011 07:08 PM, Ali Çehreli wrote: >> Implicit conversions to immutable in the following two functions feel >> harmless. >> Has this been discussed before? >> >> string foo() >> { >> char[] s; >> return s; // Error: cannot implicitly convert expression >> // (s) of type char[] to string >> } >> >> string bar() >> { >> char[] s; >> return s ~ s; // Error: cannot implicitly convert expression >> // (s ~ s) of type char[] to string >> } >> >> Is there a reason why that's not possible? I am sure there must be >> other cases >> that at least I would find harmless. :) >> >> Ali > > I'm all for that. Can hardly how auto conversion in the sense mutable > --> immutable could be harmful, but may miss a meaningful point. It shouldn't be allowed if a reference to that char[] is left behind. Otherwise although the receiver would think that the data wouldn't change; it could be changed by that other reference. struct S { char[] s; string foo() { return s;// <-- Must not be allowed } } But when the object in question is about to go out of scope? I don't know. On the other hand, reducing some implicit behavior is also good. > This > would esp be nice for strings, since we regularly need to use char > arrays to construct textual content. > > Denis I have another question: Does calling .idup copy any data below? string foo() { char[] s; return s.idup; // Is the content copied? } Ali
Re: Should conversion of mutable return value to immutable allowed?
On 24.02.2011 19:08, Ali Çehreli wrote: Implicit conversions to immutable in the following two functions feel harmless. Has this been discussed before? string foo() { char[] s; return s; // Error: cannot implicitly convert expression // (s) of type char[] to string } string bar() { char[] s; return s ~ s; // Error: cannot implicitly convert expression // (s ~ s) of type char[] to string } Is there a reason why that's not possible? I am sure there must be other cases that at least I would find harmless. :) Ali Currently, the correct way to do it is to use the phobos function assumeUnique, like: string bar() { char[] s; return assumeUnique(s); } Note that this does only little more than casting to immutable, so you have to ensure there is no mutable reference left behind. Anyway, it might be nice if the compiler could detect some trivial cases and insert the cast appropriately. But on the other hand, the compiler will never to be able to auto-detect all cases, and so its cleaner to use assumeUnique explicitly. - Krox
Re: Should conversion of mutable return value to immutable allowed?
Ali Ãehreli Wrote: > I have another question: Does calling .idup copy any data below? > > string foo() > { > char[] s; > return s.idup; // Is the content copied? > } > > Ali > Yes, dup stands for duplicate and is a property of arrays. There was discussion for allowing immutable objects to be created and return from pure functions.
Re: Should conversion of mutable return value to immutable allowed?
Also there is std.exception.assumUnique()
Re: Should conversion of mutable return value to immutable allowed?
Ali Çehreli napisał: > Implicit conversions to immutable in the following two functions feel > harmless. Has this been discussed before? > > string foo() > { > char[] s; > return s; // Error: cannot implicitly convert expression >//(s) of type char[] to string > } > > string bar() > { > char[] s; > return s ~ s; // Error: cannot implicitly convert expression >//(s ~ s) of type char[] to string > } > > Is there a reason why that's not possible? I am sure there must be other > cases that at least I would find harmless. :) Indeed. The returned object can be safely set to stone when its only aliases to the outside world point to immutable data. Such a guarantee is expressed in today's language by marking the function pure and all its arguments immutable. The conversion is currently not allowed as the above virtue of immutably pure functions was discovered not too long ago. If you want it, vote up: http://d.puremagic.com/issues/show_bug.cgi?id=5081 -- Tomek