www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Statically forbid string ~ size_t ?

reply bearophile <bearophileHUGS lycos.com> writes:
This comes from a thread in D.learn.

This is a small Python2 program:


from sys import argv
x = len(argv)
s = "hello"
s += x
print s


Python is strongly typed so it refuses to append an integer number to a string:

Traceback (most recent call last):
  File "...\test.py", line 4, in <module>
    s += x
TypeError: cannot concatenate 'str' and 'int' objects


In Java if you append an integer number to a string the integer number gets
first converted to a string:


class Main {
    public static void main(String[] args) {
        int x = args.length;
        String s = "hello";
        s += x;
        System.out.println(s);
    }
}


That Java code outputs:

hello0


Both Java and Python are far more commonly known than D, and they shape
programmers expectations a bit.

This D2 code compiles and runs with DMD 2.056head:


void main(string[] args) {
    int x = args.length;
    string s = "hello";
    s ~= x;
}



(In this case Python2 is typed more strongly than D.)

I think that int+char is acceptable in D, but string~size_t is not good. I
think this is bug prone (especially given the expectations of programmers
coming from other languages). So I suggest to statically disallow
string~size_t. string~char, string~dchar, and string~string are of course OK.

So far I have written no enhancement request/bug report on this because I am
not so sure...

Bye,
bearophile
Oct 13 2011
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 13 Oct 2011 17:07:32 -0400, bearophile <bearophileHUGS lycos.com>  
wrote:

 This comes from a thread in D.learn.

 This is a small Python2 program:


 from sys import argv
 x = len(argv)
 s = "hello"
 s += x
 print s


 Python is strongly typed so it refuses to append an integer number to a  
 string:

 Traceback (most recent call last):
   File "...\test.py", line 4, in <module>
     s += x
 TypeError: cannot concatenate 'str' and 'int' objects


 In Java if you append an integer number to a string the integer number  
 gets first converted to a string:


 class Main {
     public static void main(String[] args) {
         int x = args.length;
         String s = "hello";
         s += x;
         System.out.println(s);
     }
 }


 That Java code outputs:

 hello0


 Both Java and Python are far more commonly known than D, and they shape  
 programmers expectations a bit.

 This D2 code compiles and runs with DMD 2.056head:


 void main(string[] args) {
     int x = args.length;
     string s = "hello";
     s ~= x;
 }



 (In this case Python2 is typed more strongly than D.)

 I think that int+char is acceptable in D, but string~size_t is not good.  
 I think this is bug prone (especially given the expectations of  
 programmers coming from other languages). So I suggest to statically  
 disallow string~size_t. string~char, string~dchar, and string~string are  
 of course OK.

I think in order to disallow this, you have to disallow dchar = size_t. IMO, I think it's worth it. It's very uncommon to create a dchar using an integral. -Steve
Oct 13 2011
next sibling parent "Nick Sabalausky" <a a.a> writes:
"Marco Leise" <Marco.Leise gmx.de> wrote in message 
news:op.v3a8isjg9y6py2 marco-leise.homedns.org...
Am 13.10.2011, 23:11 Uhr, schrieb Steven Schveighoffer 
<schveiguy yahoo.com>:
 I think in order to disallow this, you have to disallow dchar = size_t.

 IMO, I think it's worth it.  It's very uncommon to create a dchar using 
 an integral.

 -Steve

I recently wrote JavaScript code that generates a Greek letter starting with ? (alpha) from an integer. It's just the shortest way to do it that works in most languages based on C syntax. I assume I could do it another way.

Yes: c = cast(char)123; // Or whatever code-unit desired
Like initializing with a character and then incrementing by the index  of 
the letter I want. 

Oct 13 2011
prev sibling parent Norbert Nemec <Norbert Nemec-online.de> writes:
On 13.10.2011 23:55, Marco Leise wrote:
 I recently wrote JavaScript code that generates a Greek letter starting
 with α (alpha) from an integer. It's just the shortest way to do it that
 works in most languages based on C syntax. I assume I could do it
 another way. Like initializing with a character and then incrementing by
 the index of the letter I want.

That's the kind of hack that works nicely on certain ranges of Unicode but makes no sense in a language-independent program. Having this in a quick-and-dirty piece of code may be acceptable, but experience shows that such quick-and-dirty solutions typically survive much longer than intended and bite you years later. Modern languages that offer full unicode have to prevent quick-and-dirty conversions wherever possible. This means that string handling gets more difficult for everyone. You always have to do proper conversions even if you don't intend to handle international text. However, it also means that your code will still work if it turns out lateron that non-english speakers want to use it. IMO, D should make a strict separation between numbers and unicode characters.
Oct 13 2011
prev sibling next sibling parent "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:j77juk$157p$1 digitalmars.com...
 This comes from a thread in D.learn.

 This is a small Python2 program:


 from sys import argv
 x = len(argv)
 s = "hello"
 s += x
 print s


 Python is strongly typed so it refuses to append an integer number to a 
 string:

 Traceback (most recent call last):
  File "...\test.py", line 4, in <module>
    s += x
 TypeError: cannot concatenate 'str' and 'int' objects


 In Java if you append an integer number to a string the integer number 
 gets first converted to a string:


 class Main {
    public static void main(String[] args) {
        int x = args.length;
        String s = "hello";
        s += x;
        System.out.println(s);
    }
 }


 That Java code outputs:

 hello0


 Both Java and Python are far more commonly known than D, and they shape 
 programmers expectations a bit.

 This D2 code compiles and runs with DMD 2.056head:


 void main(string[] args) {
    int x = args.length;
    string s = "hello";
    s ~= x;
 }



 (In this case Python2 is typed more strongly than D.)

 I think that int+char is acceptable in D, but string~size_t is not good. I 
 think this is bug prone (especially given the expectations of programmers 
 coming from other languages). So I suggest to statically disallow 
 string~size_t. string~char, string~dchar, and string~string are of course 
 OK.

 So far I have written no enhancement request/bug report on this because I 
 am not so sure...

Yea, the implicit character-number conversions are an irritating artifact of C's overly-weak typing. I wish we'd get rid of them.
Oct 13 2011
prev sibling next sibling parent "Marco Leise" <Marco.Leise gmx.de> writes:
Am 13.10.2011, 23:11 Uhr, schrieb Steven Schveighoffer  =

<schveiguy yahoo.com>:
 I think in order to disallow this, you have to disallow dchar =3D size=

 IMO, I think it's worth it.  It's very uncommon to create a dchar usin=

 an integral.

 -Steve

I recently wrote JavaScript code that generates a Greek letter starting = = with =CE=B1 (alpha) from an integer. It's just the shortest way to do it= that = works in most languages based on C syntax. I assume I could do it anothe= r = way. Like initializing with a character and then incrementing by the ind= ex = of the letter I want.
Oct 13 2011
prev sibling parent reply Don <nospam nospam.com> writes:
On 13.10.2011 23:07, bearophile wrote:
 This comes from a thread in D.learn.

 This is a small Python2 program:


 from sys import argv
 x = len(argv)
 s = "hello"
 s += x
 print s


 Python is strongly typed so it refuses to append an integer number to a string:

 Traceback (most recent call last):
    File "...\test.py", line 4, in<module>
      s += x
 TypeError: cannot concatenate 'str' and 'int' objects


 In Java if you append an integer number to a string the integer number gets
first converted to a string:


 class Main {
      public static void main(String[] args) {
          int x = args.length;
          String s = "hello";
          s += x;
          System.out.println(s);
      }
 }


 That Java code outputs:

 hello0


 Both Java and Python are far more commonly known than D, and they shape
programmers expectations a bit.

 This D2 code compiles and runs with DMD 2.056head:


 void main(string[] args) {
      int x = args.length;
      string s = "hello";
      s ~= x;
 }



 (In this case Python2 is typed more strongly than D.)

 I think that int+char is acceptable in D, but string~size_t is not good. I
think this is bug prone (especially given the expectations of programmers
coming from other languages). So I suggest to statically disallow
string~size_t. string~char, string~dchar, and string~string are of course OK.

 So far I have written no enhancement request/bug report on this because I am
not so sure...

The problem is things like: int i; string s = "0x" ~ ('0' + x); since char + int --> int.
Oct 13 2011
next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Don" <nospam nospam.com> wrote in message 
news:j77p3i$1eac$1 digitalmars.com...
 The problem is things like:
 int i;
 string s = "0x" ~ ('0' + x);
 since char + int --> int.

1. Maybe it would be better to have "char + int --> char"? Sounds much more sensible to me, although I haven't thought too much about it. When do you ever add a number to a code unit and *not* expect to end up with another code unit? 2. I see nothing wrong with needing an explicit cast when going from int to char, even in that example. What we have now is a teeny, tiny, minor, minor, minor convenience for some not-particularly-common situations. And the cost for that negligable benefit is shit like this: "I have "~count~" apples" // Ka-boom -- I want a compile error on shit like that (heck, even an implicit to!string would at least be an improvement over what it does now).
Oct 13 2011
parent bcs <bcs example.com> writes:
On 10/13/2011 05:29 PM, Nick Sabalausky wrote:
 "Don"<nospam nospam.com>  wrote in message
 news:j77p3i$1eac$1 digitalmars.com...
 The problem is things like:
 int i;
 string s = "0x" ~ ('0' + x);
 since char + int -->  int.

1. Maybe it would be better to have "char + int --> char"? Sounds much more sensible to me, although I haven't thought too much about it. When do you ever add a number to a code unit and *not* expect to end up with another code unit?

int i = 0; foreach(c; somesrting) { i = i * 10; i = i + c; }
 2. I see nothing wrong with needing an explicit cast when going from int to
 char, even in that example. What we have now is a teeny, tiny, minor, minor,
 minor convenience for some not-particularly-common situations. And the cost
 for that negligable benefit is shit like this: "I have "~count~" apples" //
 Ka-boom  --  I want a compile error on shit like that (heck, even an
 implicit to!string would at least be an improvement over what it does now).

Oct 13 2011
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 13 Oct 2011 18:34:35 -0400, Don <nospam nospam.com> wrote:

 On 13.10.2011 23:07, bearophile wrote:
 This comes from a thread in D.learn.

 This is a small Python2 program:


 from sys import argv
 x = len(argv)
 s = "hello"
 s += x
 print s


 Python is strongly typed so it refuses to append an integer number to a  
 string:

 Traceback (most recent call last):
    File "...\test.py", line 4, in<module>
      s += x
 TypeError: cannot concatenate 'str' and 'int' objects


 In Java if you append an integer number to a string the integer number  
 gets first converted to a string:


 class Main {
      public static void main(String[] args) {
          int x = args.length;
          String s = "hello";
          s += x;
          System.out.println(s);
      }
 }


 That Java code outputs:

 hello0


 Both Java and Python are far more commonly known than D, and they shape  
 programmers expectations a bit.

 This D2 code compiles and runs with DMD 2.056head:


 void main(string[] args) {
      int x = args.length;
      string s = "hello";
      s ~= x;
 }



 (In this case Python2 is typed more strongly than D.)

 I think that int+char is acceptable in D, but string~size_t is not  
 good. I think this is bug prone (especially given the expectations of  
 programmers coming from other languages). So I suggest to statically  
 disallow string~size_t. string~char, string~dchar, and string~string  
 are of course OK.

 So far I have written no enhancement request/bug report on this because  
 I am not so sure...

The problem is things like: int i; string s = "0x" ~ ('0' + x); since char + int --> int.

string s = "0x" ~ cast(char)('0' + x); Problem solved. -Steve
Oct 14 2011
parent Peter Alexander <peter.alexander.au gmail.com> writes:
On 14/10/11 12:23 PM, Steven Schveighoffer wrote:
 On Thu, 13 Oct 2011 18:34:35 -0400, Don <nospam nospam.com> wrote:

 On 13.10.2011 23:07, bearophile wrote:
 I think that int+char is acceptable in D, but string~size_t is not
 good. I think this is bug prone (especially given the expectations of
 programmers coming from other languages). So I suggest to statically
 disallow string~size_t. string~char, string~dchar, and string~string
 are of course OK.

 So far I have written no enhancement request/bug report on this
 because I am not so sure...

The problem is things like: int i; string s = "0x" ~ ('0' + x); since char + int --> int.

string s = "0x" ~ cast(char)('0' + x); Problem solved. -Steve

Agreed. I don't think it's worth violating fundamental principles for the sake of a minor convenience in relatively uncommon situations. Honestly, I'd like to get rid of implicit conversions altogether, but maybe that's just me...
Oct 14 2011