www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Char.length

reply "Jane Doe" <Jane.Doe mindphuck.com> writes:
One thing that bothers me quite a bit is that char's do not have 
length. This makes it difficult in templates that can take either 
strings or chars.

While one can write a template that returns the length of a 
string or char, I would imagine that this could be implemented in 
the compiler more efficiently?

     char.length always returns 1.

Similarly, it would be nice to be able to use [] on chars.

     char[x] returns char.

Example:

     auto last(T)(T s) { return s[s.length-1]; }

     void main()
     {
	writeln(last("asdf"));
	writeln(last('c'));       // fails!! But surely this should work!
     }



http://dpaste.dzfl.pl/cba5a635d08e

     Error: s must be an array or pointer type, not char
     Error: no property 'length' for type 'char'

Basically, I see no reason why char's can't be more confluent 
with strings, at least on the surface. I would reduce code 
bloat/specialization for no real reason.

If the compile knows a type is a char then char.length = 1 and 
char[x] = char. Shouldn't be hard or cause any problems?
Jul 10 2014
next sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 10 July 2014 at 17:01:45 UTC, Jane Doe wrote:
 One thing that bothers me quite a bit is that char's do not 
 have length. This makes it difficult in templates that can take 
 either strings or chars.

 While one can write a template that returns the length of a 
 string or char, I would imagine that this could be implemented 
 in the compiler more efficiently?

     char.length always returns 1.

 Similarly, it would be nice to be able to use [] on chars.

     char[x] returns char.

 Example:

     auto last(T)(T s) { return s[s.length-1]; }

     void main()
     {
 	writeln(last("asdf"));
 	writeln(last('c'));       // fails!! But surely this should 
 work!
     }



 http://dpaste.dzfl.pl/cba5a635d08e

     Error: s must be an array or pointer type, not char
     Error: no property 'length' for type 'char'

 Basically, I see no reason why char's can't be more confluent 
 with strings, at least on the surface. I would reduce code 
 bloat/specialization for no real reason.

 If the compile knows a type is a char then char.length = 1 and 
 char[x] = char. Shouldn't be hard or cause any problems?
It looks nice on the surface but it quite quickly unravels. string and char are very different types: one is a single-byte value type, the other is a 16 byte (on x64) structure representing an arbitrary length window on to arbitrary memory. The situations where they are interchangeable in code are the exceptions, not the rule.
Jul 10 2014
parent "Jane Doe" <Jane.Doe mindphuck.com> writes:
On Thursday, 10 July 2014 at 17:11:14 UTC, John Colvin wrote:
 On Thursday, 10 July 2014 at 17:01:45 UTC, Jane Doe wrote:
 One thing that bothers me quite a bit is that char's do not 
 have length. This makes it difficult in templates that can 
 take either strings or chars.

 While one can write a template that returns the length of a 
 string or char, I would imagine that this could be implemented 
 in the compiler more efficiently?

    char.length always returns 1.

 Similarly, it would be nice to be able to use [] on chars.

    char[x] returns char.

 Example:

    auto last(T)(T s) { return s[s.length-1]; }

    void main()
    {
 	writeln(last("asdf"));
 	writeln(last('c'));       // fails!! But surely this should 
 work!
    }



 http://dpaste.dzfl.pl/cba5a635d08e

    Error: s must be an array or pointer type, not char
    Error: no property 'length' for type 'char'

 Basically, I see no reason why char's can't be more confluent 
 with strings, at least on the surface. I would reduce code 
 bloat/specialization for no real reason.

 If the compile knows a type is a char then char.length = 1 and 
 char[x] = char. Shouldn't be hard or cause any problems?
It looks nice on the surface but it quite quickly unravels. string and char are very different types: one is a single-byte value type, the other is a 16 byte (on x64) structure representing an arbitrary length window on to arbitrary memory. The situations where they are interchangeable in code are the exceptions, not the rule.
This is simply wrong. There are man types with functionality of length. One can create a class Char that has lenght. Arrays have length.
Jul 10 2014
prev sibling next sibling parent "Kiith-Sa" <kiithsacmp gmail.com> writes:
On Thursday, 10 July 2014 at 17:01:45 UTC, Jane Doe wrote:
 One thing that bothers me quite a bit is that char's do not 
 have length. This makes it difficult in templates that can take 
 either strings or chars.

 While one can write a template that returns the length of a 
 string or char, I would imagine that this could be implemented 
 in the compiler more efficiently?

     char.length always returns 1.

 Similarly, it would be nice to be able to use [] on chars.

     char[x] returns char.

 Example:

     auto last(T)(T s) { return s[s.length-1]; }

     void main()
     {
 	writeln(last("asdf"));
 	writeln(last('c'));       // fails!! But surely this should 
 work!
     }



 http://dpaste.dzfl.pl/cba5a635d08e

     Error: s must be an array or pointer type, not char
     Error: no property 'length' for type 'char'

 Basically, I see no reason why char's can't be more confluent 
 with strings, at least on the surface. I would reduce code 
 bloat/specialization for no real reason.

 If the compile knows a type is a char then char.length = 1 and 
 char[x] = char. Shouldn't be hard or cause any problems?
Would cause unexpected behavior / hard to track errors on typos. If you want, you can do it yourself with UFCS: import std.traits; size_t length(C)(C c) if(isSomeChar!C) { return 1; } unittest { assert('a'.length == 1); } Not sure if you can do the same for opIndex(S)(S s) if(isSomeString!C) , probably not. But you can do: auto at(T)(T t, I index) if(isIntegral!T && (isSomeChar!T || isSomeString!T)) { static if(isSomeChar!T) { assert(index == 0, "Non-zero index makes no sense for a single character); return t; } else { return t[index]; } } unittest { assert("qwe".at(1) == 'w'.at(0)); } (Note that I didn't test any of those, it may need modification) That said, it's much better practice/safer/more maintainable use static if individually in any code that needs to treat characters and strings the same way, since they are _not_ the same. Static typing exists for a reason.
Jul 10 2014
prev sibling parent "sigod" <sigod.mail gmail.com> writes:
On Thursday, 10 July 2014 at 17:01:45 UTC, Jane Doe wrote:
     auto last(T)(T s) { return s[s.length-1]; }

     void main()
     {
 	writeln(last("asdf"));
 	writeln(last('c'));       // fails!! But surely this should 
 work!
     }
Yes, it should, if it's JavaScript. Can you show some cases that bothers you so much?
Jul 10 2014