Re: readf with strings

2011-06-22 Thread bearophile
Ali Çehreli:

> "oku" means "read":
> 
> // Read into an existing variable
> double d;
> oku("Please enter a double: ", &d);
> 
> // Read and return a value
> int i = oku!int("Please enter an int: ");

I have a related enhancement request since lot of time:
http://d.puremagic.com/issues/show_bug.cgi?id=4716

Bye,
bearophile


Re: readf with strings

2011-06-22 Thread Kai Meyer

On 06/22/2011 09:30 AM, Ali Çehreli wrote:

On Wed, 22 Jun 2011 14:57:57 +, GreatEmerald wrote:


This should be a very elementary question. How do you get a string off
stdin? Or an integer, or a boolean, for that matter? If I use this:

   float MyFloat;
   string MyString;
   readf("%f",&MyFloat);
   writeln(MyFloat);
   readf("%s",&MyString);
   writeln(MyString);

I get the float printed correctly, but when it asks to input the string,
whatever I input gets ignored - I can't reach the writeln part in any
way and I have to forcibly close the program. The same thing is with
ints - if I enter an int, it acts as if I didn't enter anything at all.
But floats work fine for some reason. Any thoughts about what is
happening there?

I'm using openSUSE 11.4 and DMD 2.053.


Reading from an input stream is sometimes confusing.

Things to remember:

- Use %s for any type unless there is reason not to

- The line terminator from the previous entry is still in the input. (You
may call readf(" ") to flush those white space characters. (I've just
discovered this.))

- string can hold any character including space and the line terminator.
That's why pressing the Enter doesn't terminate reading a string.

- Use a space character before any format specifier to ignore zero or
more whitespace characters before the previous input: " %s".

- To read a string (actually a line), use chomp(readln())

- I don't know whether this is intended and I don't think that we should
routinely use this: The EOF (Ctrl-D on Unix consoles, Ctrl-Z on Windows)
terminates reading the string but strangely not the entire input.

import std.stdio;
import std.string;

void main()
{
 float MyFloat;
 readf(" %s",&MyFloat);
 writeln(MyFloat);

 readf(" ");

 string MyString = chomp(readln());
 writeln(MyString);
}

Ali


Remember that readf is reading characters, and converting them to types 
for you. I've just gotten in the habbit of reading in the string, and 
then parsing the string on my own. Readf doesn't grant me anything 
special that I can't do on my own. It's easy enough to do something like 
this:


[kai.meyer@kai-rhel6 sandbox]$ cat d_read.d
import std.stdio;
import std.string;
import std.conv;

void main()
{
string[] buffer;
int a;
float b;
string c;
buffer = chomp(readln()).split(" ");
a = to!(int)(buffer[0]);
b = to!(float)(buffer[1]);
c = buffer[2..$].join(" ");
writef("Read in: '%d' '%f' '%s'\n", a, b, c);
}


If I type:
1 1.3 this is a string

On the command line after the execution, I get this back:
Read in: '1' '1.30' 'this is a string'

It's not very stream-ish, because readln breaks on a new line. You could 
call the "buffer = chomp..." line again if (buffer.length == 0) before 
you attempt another conversion.




Re: readf with strings

2011-06-22 Thread Ali Çehreli
On Wed, 22 Jun 2011 13:45:56 -0500, Jimmy Cao wrote:

> On Wed, Jun 22, 2011 at 1:31 PM, Ali Çehreli  wrote:
> 
>> On Wed, 22 Jun 2011 20:17:39 +0200, Andrej Mitrovic wrote:
>>
>> > This library has some nice user-input methods for D2:
>> > https://github.com/he-the-great/JPDLibs/tree/cmdln
>>
>> Thanks! :)
>>
>> The Turkish D community has experimented with a similar solution:
>>
>>  http://ddili.org/forum/post/2960

> The design of this community site is quite splendid.

Thank you! :) We have three books too:

- D Programming Language (complete, except special memory management like 
emplace(), the 'new' and 'delete' operators, interacting with the garbage 
collector, etc. That chapter is being written as we speak)

- GtkD (needs work)

- Game Programming with SDL (freshly started; moving on pretty well)

  http://ddili.org/ders/index.html

> So D has three
> major language sub-communities:  German, Japanese, and Turkish?

The wiki lists others:

  http://www.prowiki.org/wiki4d/wiki.cgi

Ali


Re: readf with strings

2011-06-22 Thread Jimmy Cao
On Wed, Jun 22, 2011 at 1:31 PM, Ali Çehreli  wrote:

> On Wed, 22 Jun 2011 20:17:39 +0200, Andrej Mitrovic wrote:
>
> > This library has some nice user-input methods for D2:
> > https://github.com/he-the-great/JPDLibs/tree/cmdln
>
> Thanks! :)
>
> The Turkish D community has experimented with a similar solution:
>
>  http://ddili.org/forum/post/2960
>
> "oku" means "read":
>
>// Read into an existing variable
>double d;
>oku("Please enter a double: ", &d);
>
>// Read and return a value
>int i = oku!int("Please enter an int: ");
>
> Ali
>

The design of this community site is quite splendid.  So D has three major
language sub-communities:  German, Japanese, and Turkish?


Re: readf with strings

2011-06-22 Thread Andrej Mitrovic
I didn't know there was a Turkish D community. :)


Re: readf with strings

2011-06-22 Thread Ali Çehreli
On Wed, 22 Jun 2011 20:17:39 +0200, Andrej Mitrovic wrote:

> This library has some nice user-input methods for D2:
> https://github.com/he-the-great/JPDLibs/tree/cmdln

Thanks! :)

The Turkish D community has experimented with a similar solution:

  http://ddili.org/forum/post/2960

"oku" means "read":

// Read into an existing variable
double d;
oku("Please enter a double: ", &d);

// Read and return a value
int i = oku!int("Please enter an int: ");

Ali


Re: An effort at creating a free ebook for learning D

2011-06-22 Thread Jimmy Cao
I've done some major restructuring to the ebook.  Now, the link to the first
lesson is:
http://en.wikibooks.org/wiki/D_(The_Programming_Language)/d2/Phobos/Lesson_1
There are 7 lessons currently.  Lesson 3 (Functions) and 9 (Slicing) are not
written as of now.
If you contribute, please add yourself to:
http://en.wikibooks.org/wiki/D_(The_Programming_Language)/Contributors

Please, do feel free to add content, tips, and code.  There's no errata;
just fix it, that's all.
Anybody know a good idea for a picture to put in the index page:
http://en.wikibooks.org/wiki/D_(The_Programming_Language) ?

Thanks
Jimmy


Re: readf with strings

2011-06-22 Thread Ali Çehreli
On Wed, 22 Jun 2011 20:59:46 +0300, Dainius (GreatEmerald) wrote:

> I see. Using %s does indeed work with ints, and chomp(readln()) works
> with strings. It's rather counter-intuitive, though.

There are many counter intuitive bits and imperfect modelling in stream I/
O. For example "42a" is perfectly fine when reading an int because the 
reader decides that the '4' and '2' characters make up the int and 'a' 
must be for something else. Why? :) What if I really meant that "42a" 
should be read as int. It should be an error!

I think strings are special because they are powerful to take any 
character.

Additionally output and input are not symmetrical: The ints 1 and 2 would 
be written as 12 back to back but they can't be read as two ints.

> I wonder why there
> isn't a simpler way to do this, something like writeln() - you could
> input the variables as parameters and it would automatically read
> them...

I know that the insistence on the space character to munch white space is 
intentional. Andrei commented on a bug that this is more consistent than 
scanf()'s implicit munching.

There is  that is being (is?) deprecated. It reads simpler like 
writeln:

import std.cstream;

void main()
{
double d;
int i;
din.readf(&d, &i);
dout.writefln("d: %s, i: %s", d, i);
}

It would still be problematic with strings. How many characters should be 
a part of it?

Ali


Re: readf with strings

2011-06-22 Thread Andrej Mitrovic
This library has some nice user-input methods for D2:
https://github.com/he-the-great/JPDLibs/tree/cmdln


Re: An effort at creating a free ebook for learning D

2011-06-22 Thread Ali Çehreli
On Mon, 20 Jun 2011 16:13:37 -0600, Kai Meyer wrote:

> I wrote some code a while back that was intended to be portable (between
> windows and linux anyway). I used 'writef("Hello\n");' a lot, and those
> always printed correctly on windows. Does writef do something different
> than write with the '\n' character?

(I can't see Jose Armando Garcia's answer to this question. For some 
reason it appears empty in my news reader (Pan 0.133).)

As far as I know, "text mode" file access already translates those 
characters. '\n' always means "new line" to be replaced with each 
platform's correct code sequence.

Ali


Re: readf with strings

2011-06-22 Thread Dainius (GreatEmerald)
I see. Using %s does indeed work with ints, and chomp(readln()) works
with strings. It's rather counter-intuitive, though.
I wonder why there isn't a simpler way to do this, something like
writeln() - you could input the variables as parameters and it would
automatically read them...


Re: Implicit conversion of unique objects to mutable and immutable

2011-06-22 Thread Ali Çehreli
On Wed, 22 Jun 2011 15:58:02 +, Timon Gehr wrote:

> On Wed, 22 Jun 2011 00:02:55 +, Ali Çehreli wrote:
> 
>> I wonder whether a UniqueRef object could be returned, which could
>> allow a single casting of its data to mutable or immutable at the call
>> site. Further casts could throw, but that would be a runtime solution.
>> :-/
> 
> Further casts should return null.

I thought about that too but if null is a valid value itself and if the 
value should be casted only once, throwing seemed a better choice.

> Timon

Ali


Re: Implicit conversion of unique objects to mutable and immutable

2011-06-22 Thread Timon Gehr
On Wed, 22 Jun 2011 00:02:55 +, Ali Çehreli wrote:

> I wonder whether a UniqueRef object could be returned, which could allow
> a single casting of its data to mutable or immutable at the call site.
> Further casts could throw, but that would be a runtime solution. :-/

Further casts should return null.


Timon


Re: readf with strings

2011-06-22 Thread Ali Çehreli
On Wed, 22 Jun 2011 14:57:57 +, GreatEmerald wrote:

> This should be a very elementary question. How do you get a string off
> stdin? Or an integer, or a boolean, for that matter? If I use this:
> 
>   float MyFloat;
>   string MyString;
>   readf("%f", &MyFloat);
>   writeln(MyFloat);
>   readf("%s", &MyString);
>   writeln(MyString);
> 
> I get the float printed correctly, but when it asks to input the string,
> whatever I input gets ignored - I can't reach the writeln part in any
> way and I have to forcibly close the program. The same thing is with
> ints - if I enter an int, it acts as if I didn't enter anything at all.
> But floats work fine for some reason. Any thoughts about what is
> happening there?
> 
> I'm using openSUSE 11.4 and DMD 2.053.

Reading from an input stream is sometimes confusing.

Things to remember:

- Use %s for any type unless there is reason not to

- The line terminator from the previous entry is still in the input. (You 
may call readf(" ") to flush those white space characters. (I've just 
discovered this.))

- string can hold any character including space and the line terminator. 
That's why pressing the Enter doesn't terminate reading a string.

- Use a space character before any format specifier to ignore zero or 
more whitespace characters before the previous input: " %s".

- To read a string (actually a line), use chomp(readln())

- I don't know whether this is intended and I don't think that we should 
routinely use this: The EOF (Ctrl-D on Unix consoles, Ctrl-Z on Windows) 
terminates reading the string but strangely not the entire input.

import std.stdio;
import std.string;

void main()
{
float MyFloat;
readf(" %s", &MyFloat);
writeln(MyFloat);

readf(" ");

string MyString = chomp(readln());
writeln(MyString);
}

Ali


readf with strings

2011-06-22 Thread GreatEmerald
This should be a very elementary question. How do you get a string off stdin?
Or an integer, or a boolean, for that matter? If I use this:

  float MyFloat;
  string MyString;
  readf("%f", &MyFloat);
  writeln(MyFloat);
  readf("%s", &MyString);
  writeln(MyString);

I get the float printed correctly, but when it asks to input the string,
whatever I input gets ignored - I can't reach the writeln part in any way and
I have to forcibly close the program. The same thing is with ints - if I enter
an int, it acts as if I didn't enter anything at all. But floats work fine for
some reason. Any thoughts about what is happening there?

I'm using openSUSE 11.4 and DMD 2.053.


Re: Implicit conversion of unique objects to mutable and immutable

2011-06-22 Thread Steven Schveighoffer
On Tue, 21 Jun 2011 20:31:19 -0400, Jonathan M Davis   
wrote:



On 2011-06-21 16:50, Ali Çehreli wrote:

On Tue, 21 Jun 2011 23:02:43 +, Jonathan M Davis wrote:
> On 2011-06-21 15:25, Ali Çehreli wrote:
>> (Note: I have a feeling that this must be related to the old 'unique'
>> discussions, which I had somehow managed to stay out of. If so, I
>> apologize for repeating an old story.)
>>
>> It is most useful for a function to return the most mutable type  
unless

>> there is good reason not to. Do you agree?
>
> No. In a lot of cases, what you generally want is immutable, not
> mutable. In particular, if you're talking about strings, we favor
> string, wstring, and dstring over char[], wchar[], or dchar[] unless  
you

> actually need to alter the string.

I agree with all of that, but it should not be the function that
restricts the caller. The function should return immutable only when the
result is really immutable.

If the returned object is mutable and unique, it is pretentious of the
function to evangelically return immutable. :) Besides, the caller can't
know whether it was actually mutable but was returned as immutable
because it was the right thing to do. Otherwise the caller could cast to
mutable to save a copy.

> immutable is preferred, because it's generally more efficient.

Not in this case because the caller must make a copy to mutate further.
If the function could return 'unique mutable' and if that could be  
casted

to immutable implicitly, then all would be fine.


As I said, in Phobos, when a new string must be allocated, the type  
returned
is generally string (so it's immutable), whereas if the result of the  
function
is likely to be slice of the string passed in, then the function is  
templated
to return the same type of string as was passed to it. There's no  
extraneous

copying going on in order to return string. The _only_ case where it's
arguably forced on the caller is in the case where a copy _must_ be  
made, in

which case the function returns string rather than char[].


The issue is that newly-allocated data can be considered unique.  It would  
be advantageous for this to implicitly cast to mutable *or* immutable.  In  
other words, imposing the immutable limitation is artificial, and in some  
cases makes things less usable.


Think about dup and idup.  Wouldn't it be more straightforward if you just  
did dup and assigned it to whatever type you wanted?  Wouldn't it be more  
universal if all functions that create new data didn't have to have a  
mutable and immutable version?


If it's a slice of the input, it should be using inout, but inout is  
broken.


I think the clear path here is to use strong-pure functions to implicitly  
cast to immutable.  Such functions would have to return char[] because if  
it returns const(char)[] or immutable(char)[], it's possible the result is  
a slice of the input.


For example, the following function can only return a newly-allocated  
char[] (without using casts):


pure char[] foo(immutable(char)[] arg1, const(char)[] arg2)) {...}

So it is safe to assume the return is unique.

To answer Ali, we can add unique to the language, but this adds yet  
another type of const (unique has to do with const).  This might not go  
over well in a language with already 4 types of const (const, mutable,  
immutable, inout).  Where it does help quite a bit is for sharing mutable  
data, but of course, we can start building library constructs that allow  
that.


-Steve