<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div apple-content-edited="true"><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><span class="Apple-style-span" style="border-collapse: separate; border-spacing: 0px 0px; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: auto; -khtml-text-decorations-in-effect: none; text-indent: 0px; -apple-text-size-adjust: auto; text-transform: none; orphans: 2; white-space: normal; widows: 2; word-spacing: 0px; "><div>I suppose the question here is how often you exceed the 256-character stack-allocated buffer size?  If not often then occasionally allocating in the heap is not a huge problem.  I'm not too fussed about this anyway because generational GC will quickly reclaim things that die as young as this buffer does.  I think you underestimate the effectiveness of modern GC algorithms.  Anyway, optimizing here for short nm texts presumably handles the common case.  Why work hard to optimize the uncommon case?</div><div><br class="webkit-block-placeholder"></div></span></span></span></span></span></span></span></span></div></span></div><div><div>On Feb 25, 2008, at 10:38 AM, Jay wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><div class="hmmessage" style="font-size: 10pt; font-family: Tahoma; ">I know this area has been brewing under the surface a while.<br>I'll bring it up. :)<br> <br>Here is some apparently typical code:<br> <br>PROCEDURE Escape (nm: TEXT): TEXT =<br>  VAR len: INTEGER;   buf: ARRAY [0..255] OF CHAR;<br>  BEGIN<br>    IF (nm = NIL) THEN RETURN NIL; END;<br>    len := Text.Length (nm);<br>    IF (len + len <= NUMBER (buf))<br>      THEN RETURN DoEscape (nm, len, buf);<br>      ELSE RETURN DoEscape (nm, len, NEW (REF ARRAY OF CHAR, len + len)^);<br>    END;<br>  END Escape;<br><br>PROCEDURE DoEscape (nm: TEXT;  len: INTEGER;  VAR buf: ARRAY OF CHAR): TEXT =<br>  VAR n_escapes := 0;  src, dest: INTEGER;  c: CHAR;<br>  BEGIN<br>    Text.SetChars (buf, nm);<br>    FOR i := 0 TO len-1 DO<br>      IF (buf[i] = BackSlash) THEN INC (n_escapes); END;<br>    END;<br>    IF (n_escapes = 0) THEN RETURN nm; END;<br>    src  := len - 1;<br>    dest := src + n_escapes;<br>    WHILE (src > 0) DO<br>      c := buf[src];  DEC (src);<br>      buf[dest] := c;  DEC (dest);<br>      IF (c = BackSlash) THEN  buf[dest] := BackSlash;  DEC (dest);  END;<br>    END;<br>    RETURN Text.FromChars (SUBARRAY (buf, 0, len + n_escapes));<br>  END DoEscape;<br><br><br>Look at how inefficient this is.<br>For a long string it makes a heap allocation, even if in the end it makes no changes to the string.<br>For any length string it copies it out to an array.<br>Then if there are any changes, it copies it again, probably into heap, likely the input immediately becoming garbage.<br>Heap allocation may be fast, but building up garbage and causing more work for the garbage collector I assume is bad.<br>And if the string had no backslashes, it's all a big waste.<br> <br>I assume texts are read only?<br> <br>I know lots of systems have read only strings.<br>There are pluses and minus to them. They can be single-instanced.<br>Some systems with read only strings have another type, such as "StringBuilder" or "StringBuffer".<br><br><br>So -- I don't have a specific question, but maybe a mutable string "class" aka "type" is needed?<br>Not necessarily in the language but in m3core or libm3?<br>Maybe it's already there?<br> <br>I just spent a few hours diddling with arrays of chars.<br>Unfortunately they are not resizable.<br>It was not entirely satisfactory. Besides the array I had to pass around a length and a start.<br>Wrapping this up in one record TYPE MutableString= ... might be a good idea.<br> <br>For more efficient read only access, would it be reasonable for the runtime to materialize on-demand 8 bit and 16 bit representations of a string if a user calls some new thing like Text.GetDirectA (t: TEXT) : REF ARRAY OF CHAR, Text.GetDirectW (t: TEXT) : REF ARRAY OF WIDECHAR? Throw an exception if the string cannot be represented with 8 bit characters? Or use utf8?<br> <br>Besides, I know I'm a big predictable whiner but I like how this works in Windows..<br>It may not have been as seamless, but it works and it really doesn't tend to break or slow down existing code.<br>roughly:<br>  "foo" is an 8 bit string of type char* (or const char* or possibly const char[4])<span class="Apple-converted-space"> </span><br>  L"foo" is an 16 bit string of type<span class="Apple-converted-space"> </span><font face="">wchar_t* (ditto, and aka WCHAR)<span class="Apple-converted-space"> </span></font><br>  "L" for "long" aka "wide"<span class="Apple-converted-space"> </span><br> <br>Functions must be written to specifically use one or the other.<br>In C++ you can templatize. There is std::string and std::wstring that are template instantiations.<br>Lots of C functions are duplicated. strcpy => wcscpy, strcat => wcscat, etc.<br>And really there's no point in 8 bit strings.<br>If you have a blob, that's an array of bytes or something, not characters.<span class="Apple-converted-space"> </span><br> <br>It works.<br> <br>Utf8 is another seemingly popular route but I think it's a hack.<br>I think mostly people don't touch their code and say, voila, it's utf8, and they only really support the same old English or possibly 8 bit characters (some European characters).<br>Granted, to some extent, this does work, as long as you don't do anything with the string but strlen, strcpy, and some others and pass it to code that does treat it correctly. Still, variably sized encodings seem like a bad idea here, and 16 bits per character seem affordable enough. And yes, I know that Unicode is actually know 20 bits per character and some characters take two wchar_ts but I try to ignore that...<br>And I know there is a lot of existing code, but sometimes there is a need for progress too...<br> <br>Ok, maybe NOW I'll look at the cygwin/shobjgen problem. :)<br> <br> <br> - Jay<br> <br><br><hr>Helping your favorite cause is as easy as instant messaging. You IM, we give.<span class="Apple-converted-space"> </span><a href="http://im.live.com/Messenger/IM/Home/?source=text_hotmail_join" target="_new">Learn more.</a></div></span></blockquote></div><br></body></html>