February 04, 2016
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.



February 05, 2016
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.
February 05, 2016
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?

February 05, 2016
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.
February 05, 2016
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.
February 05, 2016
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
February 05, 2016
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()?

February 05, 2016
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
February 06, 2016
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.
1 2 3
Next ›   Last »