www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D annoyances from a new user

reply graue oceanbase.org writes:
Hello, I've been reading about D for awhile now and just tried to write my first
program in it, a program that hides words in a grid of user-defined size and
prints the result. While writing this program, I was annoyed by the following
things:

---
If I do

alias std.stream.stdout stdout;

writef("Word: ");
stdout.flush();
char[] word = stdin.readLine();

the "Word: " still doesn't display in time. In fact, if I do that in a loop,
none of the printings of "Word: " appear until after the loop has completed and
all the words have been read in.

---

To uppercase a character, I have to call a C-style function toupper() and do
"import std.ctype". I expected, and I think it would be neater if, I could just
do

char[] areYouSatisfied = stdin.readLine();
if(areYouSatisfied[0].toUpper == 'Y')
..

---

I'm annoyed that I have to use this much code to make a rectangular array:

char[][] makeBoard(T foo, int width, int height)
{
char[][] board;

char[][] getProperlySizedArray(int width, int height)
{
char[][] result;
result.length = height;
for(int i = 0; i < result.length; i++)
result[i].length = width;
return result;
}

board = getProperlySizedArray(width, height);

// fill in board...

return board;
}

Shouldn't there be a cleaner way?

---

I don't understand why the above code is different from doing

char[][] getProperlySizedArray(int width, int height)
{
char[][] result;
result.length = height;
foreach(char[] line; result)
line.length = width;
return result;
}

For some reason, the latter does not set the widths correctly, as though the
foreach is not doing anything.

---

In the code two examples up, I shouldn't have to do

char[][] makeBoard(T foo, int width, int height)
{
char[][] board;

char[][] getProperlySizedArray(int width, int height)
{
// ...
}

board = getProperlySizedArray(width, height);

// ...

return board;
}

instead of just

char[][] makeBoard(T foo, int width, int height)
{
char[][] board = getProperlySizedArray(width, height);

char[][] getProperlySizedArray(int width, int height)
{
// ...
}

// ...

return board;
}

Apparently nested functions need forward declarations, like C functions, but I
was glad to be rid of that requirement. I don't think nested functions should
need forward declarations or definitions either.

---

I much prefer printf() to writefln(). It's clearer and easier to put the formula
in one place and the data in another, instead of intermingling them. With
writefln(), I'm much more likely to forget a space, for example, when I do
something like:

writefln("I am ", age, " years old and ", height, "inches tall");

It's easy to forget one of the spaces at the beginning or end of a string. With
printf() on the other hand, the error is obvious:

printf("I am %d years old and %dinches tall\n", age, height);

Also notice how easy it is to see what information is being used, and what the
final result will look like. It just works. I'm aware that printf() is still
available, but writef() and writefln() are shiny new features and I bet everyone
will feel obligated to use them... and I just don't see the advantage.

---

Note that I haven't made any classes at present; I just wrote a procedural-style
program.

Feel free to argue with me, agree with me, ignore this post, suggest alternative
techniques etc.

-graue
May 25 2005
next sibling parent kris <fu bar.org> writes:
graue oceanbase.org wrote:
 To uppercase a character, I have to call a C-style function toupper() and do
 "import std.ctype". I expected, and I think it would be neater if, I could just
 do
 
 char[] areYouSatisfied = stdin.readLine();
 if(areYouSatisfied[0].toUpper == 'Y')
 ..

It would truly be wonderful if one could add 'properties' to native types (and arrays) in the manner you describe. Even better if there were a default set provided by the compiler, as you imply above. - Kris
May 25 2005
prev sibling next sibling parent SeeSchloss <SeeSchloss_member pathlink.com> writes:
Hello, I've been reading about D for awhile now and just tried to write my first
program in it, a program that hides words in a grid of user-defined size and
prints the result. While writing this program, I was annoyed by the following
things:

Hmm, I'll try to answer to some of these problems.
---
If I do

alias std.stream.stdout stdout;

writef("Word: ");
stdout.flush();
char[] word = stdin.readLine();

the "Word: " still doesn't display in time. In fact, if I do that in a loop,
none of the printings of "Word: " appear until after the loop has completed and
all the words have been read in.

But it works if you use stdout.writef instead of writef (which is also more consistent). I'm not sure why, though.
---

To uppercase a character, I have to call a C-style function toupper() and do
"import std.ctype". I expected, and I think it would be neater if, I could just
do

char[] areYouSatisfied = stdin.readLine();
if(areYouSatisfied[0].toUpper == 'Y')
..

Well... I guess you could do a wrapper class called Char which has a toUpper function, but basic types do not have functions.
---

I'm annoyed that I have to use this much code to make a rectangular array:

char[][] makeBoard(T foo, int width, int height)
{
char[][] board;

char[][] getProperlySizedArray(int width, int height)
{
char[][] result;
result.length = height;
for(int i = 0; i < result.length; i++)
result[i].length = width;
return result;
}

board = getProperlySizedArray(width, height);

// fill in board...

return board;
}

Shouldn't there be a cleaner way?
---

I don't understand why the above code is different from doing

char[][] getProperlySizedArray(int width, int height)
{
char[][] result;
result.length = height;
foreach(char[] line; result)
line.length = width;
return result;
}

For some reason, the latter does not set the widths correctly, as though the
foreach is not doing anything.

Use foreach (inout char[] line ; result) if you want to modify the lines.
---

In the code two examples up, I shouldn't have to do

char[][] makeBoard(T foo, int width, int height)
{
char[][] board;

char[][] getProperlySizedArray(int width, int height)
{
// ...
}

board = getProperlySizedArray(width, height);

// ...

return board;
}

instead of just

char[][] makeBoard(T foo, int width, int height)
{
char[][] board = getProperlySizedArray(width, height);

char[][] getProperlySizedArray(int width, int height)
{
// ...
}

// ...

return board;
}

Apparently nested functions need forward declarations, like C functions, but I
was glad to be rid of that requirement. I don't think nested functions should
need forward declarations or definitions either.

Not sure about that, I would have thought it works but I don't have a d compiler handy.
---

I much prefer printf() to writefln(). It's clearer and easier to put the formula
in one place and the data in another, instead of intermingling them. With
writefln(), I'm much more likely to forget a space, for example, when I do
something like:

writefln("I am ", age, " years old and ", height, "inches tall");

It's easy to forget one of the spaces at the beginning or end of a string. With
printf() on the other hand, the error is obvious:

printf("I am %d years old and %dinches tall\n", age, height);

Also notice how easy it is to see what information is being used, and what the
final result will look like. It just works. I'm aware that printf() is still
available, but writef() and writefln() are shiny new features and I bet everyone
will feel obligated to use them... and I just don't see the advantage.

Well you can also use writefln ("I am %d years old and %d cm tall", age, height);
---

Note that I haven't made any classes at present; I just wrote a procedural-style
program.

Feel free to argue with me, agree with me, ignore this post, suggest alternative
techniques etc.

Well, a suggestion would be to read the doc, I hope I didn't make mistakes myself :) SeeSchloss
May 25 2005
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
<graue oceanbase.org> wrote in message
news:d7182f$1ai2$1 digitaldaemon.com...
 Hello, I've been reading about D for awhile now and just tried to write my

 program in it, a program that hides words in a grid of user-defined size

 prints the result. While writing this program, I was annoyed by the

 things:

 ---
 If I do

 alias std.stream.stdout stdout;

 writef("Word: ");
 stdout.flush();
 char[] word = stdin.readLine();

 the "Word: " still doesn't display in time. In fact, if I do that in a

 none of the printings of "Word: " appear until after the loop has

 all the words have been read in.

The problem is there are two stdout's. One is in std.stream, the other is in std.c.stdio. writef works with std.c.stdio.stdout, not std.stream.stdout. Obviously, one of these needs to change its spelling.
May 25 2005
next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
<snip>
 The problem is there are two stdout's. One is in std.stream, the
 other is in std.c.stdio. writef works with std.c.stdio.stdout, not
 std.stream.stdout.
 
 Obviously, one of these needs to change its spelling.

The sheer number of functions from different modules I find myself calling to do console I/O gets at me a bit. writef and writefln from std.stdio, putchar, puts and fflush from std.c.stdio, probably one or two others.... CTTAI maybe now that std.stream has writef(ln) it can be done a bit more tidily, but I'm not sure. And once we have a good text I/O lib (a project I'm planning on undertaking at some point) we certainly will have this consolidation and more.... Stewart. -- My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
May 25 2005
prev sibling next sibling parent "Lionello Lunesu" <lio lunesu.removethis.com> writes:
I'm sorry, I feel like am only bashing lately, but I really have good 
intentions, and I'm very hopeful I'll be programming only in D someday.

We should not really mix the C run-time with Phobos. Phobos should use only 
Phobos and native OS functions, I think. The CRT is there to ease porting 
existing programs.

Changing names will not diminish the confusion. We'll end up with two 
different names for two similar things. People looking for stdout will use 
std.c.stdio.stdout, and end up mixing old-style C with new-style Phobos D.

L. 
May 25 2005
prev sibling next sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:d71d34$1vbe$1 digitaldaemon.com...
 <graue oceanbase.org> wrote in message
 news:d7182f$1ai2$1 digitaldaemon.com...
 Hello, I've been reading about D for awhile now and just tried to write 
 my

 program in it, a program that hides words in a grid of user-defined size

 prints the result. While writing this program, I was annoyed by the

 things:

 ---
 If I do

 alias std.stream.stdout stdout;

 writef("Word: ");
 stdout.flush();
 char[] word = stdin.readLine();

 the "Word: " still doesn't display in time. In fact, if I do that in a

 none of the printings of "Word: " appear until after the loop has

 all the words have been read in.

The problem is there are two stdout's. One is in std.stream, the other is in std.c.stdio. writef works with std.c.stdio.stdout, not std.stream.stdout. Obviously, one of these needs to change its spelling.

That's one way. Another way is to have phobos use one system for io instead of the C runtime and std.stream. I personally think it's very odd that std.stdio doesn't use std.stream. It's like 1/2 of phobos use FILE*'s and the C lib and 1/2 uses phobos. In terms of user code one gets compile errors that there are multiple stdouts and stdins when you start mixing std.stream and std.c.stdio so the user knows there is something fishy going on. Defining an alias is an unfortunate way of getting over the problem since picking one or the other is usually a better idea. Having two names will just mean people mix the two without realizing they are mixing the two.
May 25 2005
prev sibling parent reply James McComb <ned jamesmccomb.id.au> writes:
Walter wrote:

 The problem is there are two stdout's. One is in std.stream, the other is in
 std.c.stdio. writef works with std.c.stdio.stdout, not std.stream.stdout.
 
 Obviously, one of these needs to change its spelling.

What about din and dout? ;) James McComb
May 25 2005
parent Vathix <vathix dprogramming.com> writes:
On Wed, 25 May 2005 22:44:09 -0400, James McComb <ned jamesmccomb.id.au>  
wrote:

 Walter wrote:

 The problem is there are two stdout's. One is in std.stream, the other  
 is in
 std.c.stdio. writef works with std.c.stdio.stdout, not  
 std.stream.stdout.
  Obviously, one of these needs to change its spelling.

What about din and dout? ;)

How about foo and bar
May 25 2005
prev sibling parent "Unknown W. Brackets" <unknown simplemachines.org> writes:
You can use writefln like printf:

writefln("I am %d years old and %dinches tall\n", age, height);

Nested functions are documented as not being "look ahead" friendly.

I don't see the problem with toupper() or just comparing 
areYouSatisfied[0] against 'y' and 'Y'.  It's a function call either way 
- you just want it to look different?

-[Unknown]
May 25 2005