Re: print function

2016-02-05 Thread cy via Digitalmars-d-learn

On Friday, 5 February 2016 at 12:35:14 UTC, Artur Skawina wrote:
D's std lib implementations are sometimes really awful, but in 
this case it's not actually that bad:


   print("hi","there");

->

   fwrite("hi", 1, 2, 0x7ff68d0cb640) = 
2
   fwrite(" ", 1, 1, 0x7ff68d0cb640)  = 
1
   fwrite("there", 1, 5, 0x7ff68d0cb640)  = 
5
   fwrite("\n", 1, 1, 0x7ff68d0cb640) = 
1


Oh wow, and you thought to actually test it. I was just 
eyeballing the code and running my mouth off. I can't fathom how 
that's possible, because the only thing the write() template does 
is translate each string argument to put(w,arg) where w is a 
LockingTextWriter, and LockingTextWriter.put only outputs a 
string if the sizeof... oh.


Yeah, my bad. Now I see it only puts each character as a string, 
one at a time, if those characters are wide characters or 
multibyte characters. It only does that if C.sizeof!=1 and I was 
confusing .sizeof for .length. So for w"abc" it would put "a\0" 
"b\0" "c\0" three times, I think, but for just "abc" it goes 
straight to fwrite. It's the length of each character in bytes, 
not the length of each string.


utf-8 encoded is still C.sizeof==1 I'm pretty sure. It's only 
when you try to decode the characters or make "ropes" that you 
end up with that iterative expansion of put().


Years ago I had to investigate why phobos showed up in the perf 
profile of a program, when the only used part was some `write` 
call used to print diagnostics. What I saw made me never use or 
look at D's std lib again. Except for meta programing and 
toy/example programs where it doesn't matter.


Maybe you should look again? I thought it was rather elegant, 
except for the bizarre individual-character expansion that I 
mistook for reality. It's not fast, but... very safe. Any D 
process is going to lock the specific area of the file, so that 
when you read a bunch, you're not going to have it change halfway 
through, and two things aren't going to be writing in the same 
place at the same time, at least not within individual write 
calls.


Re: print function

2016-02-05 Thread Marc Schütz via Digitalmars-d-learn

On Friday, 5 February 2016 at 07:04:27 UTC, cy wrote:
Mind if I elaborate on this a bit? If that is unrolled, I 
understand it will unroll into several calls to write, as in 
print("1","2","3") => write("1"," ");write("2"," 
");write("3","\n");




Up to here, yes.

And presumably, write() unrolls its arguments too. Each string 
argument to write() unrolls to a put(). And put("abc") unrolls 
into put("a");put("b");put("c"), each of which that call the C 
routine fwrite with a length 1.


No, (explicit) unrolling with foreach could only happen if 
there's either a variadic argument list, or if "abc" were a 
template argument. (In the latter case you'd need more than a 
simple foreach.) Of course, I don't know whether put() call 
fwrite() for every single character (these are written with 
single quotes, btw), but that wouldn't be unrolling strictu sensu.


Re: print function

2016-02-05 Thread ixid via Digitalmars-d-learn
On Thursday, 4 February 2016 at 22:13:36 UTC, Ola Fosheim Grøstad 
wrote:
Well, it is probably not the best point in time to have 
absolute beginners use D anyway.


That is a ridiculous thing to say and a great way of ensuring a 
language dies. Good starting resources help everyone.


Re: print function

2016-02-05 Thread Artur Skawina via Digitalmars-d-learn
On 02/05/16 08:04, cy via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 15:32:48 UTC, Artur Skawina wrote:
>>void print(A...)(A a) {
>>   foreach (N, ref e; a)
>>  write(e, N==A.length-1?"\n":" ");
>>}
> 
>>> will be unrolled at compile time
> 
> Mind if I elaborate on this a bit? If that is unrolled, I understand it will 
> unroll into several calls to write, as in print("1","2","3") => write("1"," 
> ");write("2"," ");write("3","\n");

Yes, and they are all using the same `write!(string, string)` instance
(there will be one for every printed type, `write!(typeof(A[N]), string)`).


> Any literal string you pass to std.stdio.write will be expanded into 1 fwrite 
> invocation per character.

D's std lib implementations are sometimes really awful, but in
this case it's not actually that bad:

   print("hi","there");

->

   fwrite("hi", 1, 2, 0x7ff68d0cb640) = 2
   fwrite(" ", 1, 1, 0x7ff68d0cb640)  = 1
   fwrite("there", 1, 5, 0x7ff68d0cb640)  = 5
   fwrite("\n", 1, 1, 0x7ff68d0cb640) = 1


What happens between `print` and `fwrite` - I have no idea.
Years ago I had to investigate why phobos showed up in the
perf profile of a program, when the only used part was some
`write` call used to print diagnostics. What I saw made me
never use or look at D's std lib again. Except for meta
programing and toy/example programs where it doesn't matter.

artur


Re: print function

2016-02-05 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Friday, 5 February 2016 at 12:35:14 UTC, Artur Skawina wrote:
call used to print diagnostics. What I saw made me never use or 
look at D's std lib again. Except for meta programing and 
toy/example programs where it doesn't matter.


What do you use instead? A buffer and Posix write() and 
aio_write()?




Re: print function

2016-02-05 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Friday, 5 February 2016 at 07:04:27 UTC, cy wrote:
tl;dr speed demons use std.stream.InputStream.read() whenever 
you can, and std.stream.OutputStream.write() its result.


Isn't std.stream deprecated?



Re: print function

2016-02-05 Thread Artur Skawina via Digitalmars-d-learn
On 02/05/16 14:38, Ola Fosheim Grøstad via Digitalmars-d-learn wrote:
> On Friday, 5 February 2016 at 12:35:14 UTC, Artur Skawina wrote:
>> call used to print diagnostics. What I saw made me never use or look at D's 
>> std lib again. Except for meta programing and toy/example programs where it 
>> doesn't matter.
> 
> What do you use instead? A buffer and Posix write() and aio_write()?

For ad-hoc temporary debugging usually a local wrapper

   @noinline writeln(A...)(A a) {
  import std.stdio;
  std.stdio.writeln(a);
   }

[the reason for @noinline is to not disturb the caller]
This is where the `print` function would be useful. It
could even be made to work at CT (w/ compiler help; this
has been a often requested feature).

For programs that output one or few text lines to stdout
(results, status updates etc) - `printf` -- it's already
there in libc anyway, so zero-cost and GC-free.

For everything else - the C/Posix functions.


artur


Re: print function

2016-02-04 Thread cym13 via Digitalmars-d-learn

On Thursday, 4 February 2016 at 10:18:35 UTC, ixid wrote:
Do you think your knowledge and experience is a good model for 
how a new user who hasn't done much if any programming before 
would approach this?


A design choice had to be made and made it was. Adding another 
function now (or worse, changing the existing ones) would only 
bring more confusion for beginners and unconsistency to the 
language. I firmly believe that no matter what your experience 
you have having one and preferably only one way to do things is 
more important to ease the learning process than having spaces or 
not.


Re: print function

2016-02-04 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Thursday, 4 February 2016 at 10:59:50 UTC, Mike Parker wrote:
IMO, while giving beginner's a helping hand is a great thing, I 
don't think it's a good basis to use as a design for a standard 
library.


Yes, better to have a "beginners toolkit" starting-point-codebase 
and build a tutorial around it.




Re: print function

2016-02-04 Thread ixid via Digitalmars-d-learn

On Thursday, 4 February 2016 at 11:04:23 UTC, cym13 wrote:

On Thursday, 4 February 2016 at 10:18:35 UTC, ixid wrote:
Do you think your knowledge and experience is a good model for 
how a new user who hasn't done much if any programming before 
would approach this?


A design choice had to be made and made it was. Adding another 
function now (or worse, changing the existing ones) would only 
bring more confusion for beginners and unconsistency to the 
language. I firmly believe that no matter what your experience 
you have having one and preferably only one way to do things is 
more important to ease the learning process than having spaces 
or not.


That's a nonsensical argument given the number of printing and 
writing functions that exist.


Re: print function

2016-02-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, February 04, 2016 00:40:55 ixid via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 00:30:03 UTC, cym13 wrote:
> > On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
> >> It would be nice to have a simple writeln that adds spaces
> >> automatically like Python's 'print' in std.stdio, perhaps
> >> called print.
> >
> > Sounds way too redundant to me.
>
> Normally you'd be right but printing out data is such a common
> thing, especially for beginners. It's the kind of thing that can
> make their early experience of a language a lot more positive.
>
> writeln(a, " ", b, " ", c, " ", d);
>
> Is very clunky. Programming languages are like cereal, you need
> sugar to get the kids hooked.

I would normally expect someone to do that with writefln, which would be
cleaner. e.g.

writefln("%s %s %s %s", a, b, c, d);

Personally, I've never felt the need for a function like you're describing.

- Jonathan M Davis



Re: print function

2016-02-04 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 4 February 2016 at 10:18:35 UTC, ixid wrote:
On Thursday, 4 February 2016 at 10:05:15 UTC, Jonathan M Davis 
wrote:
I would normally expect someone to do that with writefln, 
which would be cleaner. e.g.


writefln("%s %s %s %s", a, b, c, d);

Personally, I've never felt the need for a function like 
you're describing.


- Jonathan M Davis


Do you think your knowledge and experience is a good model for 
how a new user who hasn't done much if any programming before 
would approach this?


IMO, while giving beginner's a helping hand is a great thing, I 
don't think it's a good basis to use as a design for a standard 
library.


Re: print function

2016-02-04 Thread ixid via Digitalmars-d-learn
On Thursday, 4 February 2016 at 10:05:15 UTC, Jonathan M Davis 
wrote:
I would normally expect someone to do that with writefln, which 
would be cleaner. e.g.


writefln("%s %s %s %s", a, b, c, d);

Personally, I've never felt the need for a function like you're 
describing.


- Jonathan M Davis


Do you think your knowledge and experience is a good model for 
how a new user who hasn't done much if any programming before 
would approach this?


Re: print function

2016-02-04 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Thursday, 4 February 2016 at 14:25:21 UTC, bachmeier wrote:
Unfortunately there is no such thing and it is unlikely to 
exist in the next decade.


Well, it is probably not the best point in time to have absolute 
beginners use D anyway. But a well commented library, that don't 
focus on performance and teach good habits using the non-advanced 
D feature subset, can go a long way if the design is explained in 
a companion tutorial. A "build your own pythonesque library" 
tutorial wrapped up as a zip-file with a sensible main-file 
template that is ready to compile.


That way newbies can just unzip it into a new directory when they 
start a new project "resetting" former mistakes.






Re: print function

2016-02-04 Thread cy via Digitalmars-d-learn

On Thursday, 4 February 2016 at 15:32:48 UTC, Artur Skawina wrote:

   void print(A...)(A a) {
  foreach (N, ref e; a)
 write(e, N==A.length-1?"\n":" ");
   }



will be unrolled at compile time


Mind if I elaborate on this a bit? If that is unrolled, I 
understand it will unroll into several calls to write, as in 
print("1","2","3") => write("1"," ");write("2"," 
");write("3","\n");


And presumably, write() unrolls its arguments too. Each string 
argument to write() unrolls to a put(). And put("abc") unrolls 
into put("a");put("b");put("c"), each of which that call the C 
routine fwrite with a length 1.


So the above print, if you did print("hi","there") it would become
write("hi"," "); write("there","\n")
which would become
put("hi");put(" ");put("there");put("\n");
which would become
put("h");put("i");put(" 
");put("t");put("h");put("e");put("r");put("e");put("\n");


And then it compiles.

Any literal string you pass to std.stdio.write will be expanded 
into 1 fwrite invocation per character. And 
std.format.formattedWrite is called on aggregate types like 
lists, which stringifies each value, and passes the string to 
put(), resulting in again, 1 fwrite per character.


Why put() doesn't just call fwrite without expanding into 1 
character strings, I have no idea. Something with wide 
characters, I guess? But even then it could use one fwrite for 
normal characters. It's not like

fwrite("a",1,1,stdout);fwrite("b",1,1,stdout);
will fail any less if the output stream dies before "b" than
fwrite("ab",2,1,stdout);

Why put() doesn't call the C "fputc" function for 1 character 
strings, I *really* have no idea.


Seems to me some fancy code generation producing write("a"," ", 
"b", " ", "c", "\n") or even put("a b c\n") would still expand 
into 1 put() per character, before it finished compiling.


tl;dr speed demons use std.stream.InputStream.read() whenever you 
can, and std.stream.OutputStream.write() its result. Don't expect 
std.stdio to let you have nice things. std.file.write is always 
preferable if you can generate the whole file beforehand.


Re: print function

2016-02-04 Thread bachmeier via Digitalmars-d-learn
On Thursday, 4 February 2016 at 11:04:15 UTC, Ola Fosheim Grøstad 
wrote:

On Thursday, 4 February 2016 at 10:59:50 UTC, Mike Parker wrote:
IMO, while giving beginner's a helping hand is a great thing, 
I don't think it's a good basis to use as a design for a 
standard library.


Yes, better to have a "beginners toolkit" 
starting-point-codebase and build a tutorial around it.


That would be a reasonable argument if such a thing existed and 
was included with the compiler.


import newbie;

void main() {
  print("Jack", "Black");
}

Unfortunately there is no such thing and it is unlikely to exist 
in the next decade.


Re: print function

2016-02-04 Thread Kagamin via Digitalmars-d-learn

On Thursday, 4 February 2016 at 14:25:21 UTC, bachmeier wrote:
Unfortunately there is no such thing and it is unlikely to 
exist in the next decade.


There is http://forum.dlang.org/post/mtsd38$16ub$1...@digitalmars.com


Re: print function

2016-02-04 Thread Dejan Lekic via Digitalmars-d-learn

On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
It would be nice to have a simple writeln that adds spaces 
automatically like Python's 'print' in std.stdio, perhaps 
called print.


There are many implementations of string interpolation in D (that 
is what you want, basically). One of them is given in Phillipe's 
excellent book about templates: 
https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/D-templates-tutorial.md#simple-string-interpolation .


Re: print function

2016-02-04 Thread ixid via Digitalmars-d-learn

On Thursday, 4 February 2016 at 13:46:46 UTC, Dejan Lekic wrote:

On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
It would be nice to have a simple writeln that adds spaces 
automatically like Python's 'print' in std.stdio, perhaps 
called print.


There are many implementations of string interpolation in D 
(that is what you want, basically). One of them is given in 
Phillipe's excellent book about templates: 
https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/D-templates-tutorial.md#simple-string-interpolation .


I have written an attempt at it but my point was that a print 
function would be a good addition to the standard library rather 
than asking someone to write an implementation for me.


string makePrintString(T)(T length) {
import std.conv : to;

string s = "writeln(";
foreach( i; 0 .. length) {
s ~= "a[" ~ i.to!string ~ "]";
if(i != length - 1)
s ~= ",\" \",";
else s ~= ");";
}

return s;
}   

void print(A...)(A a) { 
static if(a.length) {
mixin(makePrintString(a.length));
} else writeln;
}


Re: print function

2016-02-04 Thread Artur Skawina via Digitalmars-d-learn
On 02/04/16 15:02, ixid via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 13:46:46 UTC, Dejan Lekic wrote:
>> On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
>>> It would be nice to have a simple writeln that adds spaces automatically 
>>> like Python's 'print' in std.stdio, perhaps called print.

> I have written an attempt at it but my point was that a print function would 
> be a good addition to the standard library rather than asking someone to 
> write an implementation for me.
> 
> string makePrintString(T)(T length) {
> import std.conv : to;
>
> string s = "writeln(";
> foreach( i; 0 .. length) {
> s ~= "a[" ~ i.to!string ~ "]";
> if(i != length - 1)
> s ~= ",\" \",";
> else s ~= ");";
> }
>
> return s;
> }   
> 
> void print(A...)(A a) {   
> static if(a.length) {
> mixin(makePrintString(a.length));
> } else writeln;
> }

   void print(A...)(A a) {
  foreach (N, ref e; a)
 write(e, N==A.length-1?"\n":" ");
   }


artur


Re: print function

2016-02-04 Thread bachmeier via Digitalmars-d-learn

On Thursday, 4 February 2016 at 15:10:18 UTC, Kagamin wrote:

On Thursday, 4 February 2016 at 14:25:21 UTC, bachmeier wrote:
Unfortunately there is no such thing and it is unlikely to 
exist in the next decade.


There is 
http://forum.dlang.org/post/mtsd38$16ub$1...@digitalmars.com


The important feature is the one that it doesn't offer - it's not 
part of the default installation. Without that, it doesn't help 
new users much. It's not even listed on the "Getting Started" for 
that matter.


Re: print function

2016-02-04 Thread sigod via Digitalmars-d-learn

On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
It would be nice to have a simple writeln that adds spaces 
automatically like Python's 'print' in std.stdio, perhaps 
called print.


It seems Andrei decided to add such function: 
http://forum.dlang.org/thread/n8vr0l$ist$1...@digitalmars.com


Re: print function

2016-02-04 Thread Artur Skawina via Digitalmars-d-learn
On 02/04/16 16:32, Artur Skawina wrote:
> 
>void print(A...)(A a) {
>   foreach (N, ref e; a)
>  write(e, N==A.length-1?"\n":" ");
>}

BTW, that was *deliberately* written that way as a compromise
between efficiency and template bloat. It can of course be
done like

   void print(alias SEP=" ", alias EOL="\n", A...)(A a) {
  
mixin(`write(`~iota(A.length).map!(a=>"a["~text(a)~"],")().join("SEP,")~"EOL);");
   }

but that seems too expensive, when the use is just in toy
programs and debugging.


artur


Re: print function

2016-02-04 Thread ixid via Digitalmars-d-learn

On Thursday, 4 February 2016 at 17:34:33 UTC, Artur Skawina wrote:

On 02/04/16 16:32, Artur Skawina wrote:
but that seems too expensive, when the use is just in toy 
programs and debugging.


I hadn't really considered the relative cost-benefit, it's just a 
habit to try to hardcode things at compile time. =) It certainly 
seems to make sense to do it that way.


Re: print function

2016-02-04 Thread Artur Skawina via Digitalmars-d-learn
On 02/04/16 18:53, ixid via Digitalmars-d-learn wrote:
> On Thursday, 4 February 2016 at 17:34:33 UTC, Artur Skawina wrote:
>> On 02/04/16 16:32, Artur Skawina wrote:
>> but that seems too expensive, when the use is just in toy programs and 
>> debugging.
> 
> I hadn't really considered the relative cost-benefit, it's just a habit to 
> try to hardcode things at compile time. =) It certainly seems to make sense 
> to do it that way.

Just to clarify -- *all* versions work at CT; the static-foreach
will be unrolled at CT, and the mixin argument will be fully
evaluated at CT too. The only difference is in a) readability, b)
the `write` template instantiations (and potential re-use).

Using the std lib `write*` templates has a huge cost; for any
kind of /real/ programs, that care about performance at all, they
are better avoided. (But it probably doesn't matter if you already
heavily rely on GC and don't print much, other than that they add
tons of code to the executable)


artur


Re: print function

2016-02-03 Thread ixid via Digitalmars-d-learn

On Thursday, 4 February 2016 at 00:30:03 UTC, cym13 wrote:

On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
It would be nice to have a simple writeln that adds spaces 
automatically like Python's 'print' in std.stdio, perhaps 
called print.


Sounds way too redundant to me.


Normally you'd be right but printing out data is such a common 
thing, especially for beginners. It's the kind of thing that can 
make their early experience of a language a lot more positive.


writeln(a, " ", b, " ", c, " ", d);

Is very clunky. Programming languages are like cereal, you need 
sugar to get the kids hooked.


Re: print function

2016-02-03 Thread cym13 via Digitalmars-d-learn

On Thursday, 4 February 2016 at 00:23:07 UTC, ixid wrote:
It would be nice to have a simple writeln that adds spaces 
automatically like Python's 'print' in std.stdio, perhaps 
called print.


Sounds way too redundant to me.


Re: print function

2016-02-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, February 04, 2016 00:23:07 ixid via Digitalmars-d-learn wrote:
> It would be nice to have a simple writeln that adds spaces
> automatically like Python's 'print' in std.stdio, perhaps called
> print.

If that's what you're looking for, I expect that most of us would think that
it's just better to use writefln with a format string. But if you really
want it, you can always create such a wrapper yourself.

- Jonathan M Davis