June 03, 2020
On 6/3/20 10:28 PM, Adam D. Ruppe wrote:
> On Thursday, 4 June 2020 at 01:38:50 UTC, Walter Bright wrote:
>> Furthermore, stdout has to acquire a mutex before writing to it:
> 
> No need for any of this on the OS level, a write up to like 4k is guaranteed to be atomic.
> 
> It is the C buffer that isn't :(
> 
> And the C buffer is a consistent source of pain for user-interactive i/o. Buffering makes a big performance difference when you are actually outputting a block... but with user-interactive you rarely actually *want* buffering since users want to see their results ASAP! And remember, pipes are frequently user-interactive too and them not being flushed frequently is a FAQ among new users, especially IDE users.
> 
> I kinda feel buffering should not be done across function boundaries for stdout and stderr. Other files maybe.

I don't think you are consider the ramifications. You NEED a buffer, otherwise, e.g. you will be issuing system calls for writing 5 bytes, followed by an immediate system call for 5 more. And that isn't cheap. Locking a mutex would be dwarfed by that. Flushing on newlines is a reasonable compromise.

But it doesn't have to be a C buffer (unless you want to interact with printf).

There are good reasons to use C buffering for the standard handles. But it sucks that ALL Phobos I/O has to be based on it (including opening a file that you never use in a C call).

-Steve
June 04, 2020
On Thursday, 4 June 2020 at 03:00:26 UTC, Steven Schveighoffer wrote:
> buffer, otherwise, e.g. you will be issuing system calls for writing 5 bytes, followed by an immediate system call for 5 more.

Yeah, I know. You and I have both written low-level I/O code, we both know how it works and the huge difference proper buffering can make.

But the question is where do you have implicit flushes? I'm arguing for at the end of the function.

The call to writefln or whatever would do an intermediate buffer, but when it returns, it flushes it all at once. You don't flush intermediates if you can get away with it, but you treat each function as a direct write.

If a user actually writes out `write("h"); write("e"); write("l");`, well, that's on them, maybe they wanted to see it spell out!

But if they write `writefln("hello, %s, you have %d points!", name, score);`, the implementation should NOT do

os.write("hello, ");
os.write(name);
os.write(", you have ");

no, it should go ahead and buffer those pieces, then at the very end write it all.

Just again, if the USER writes it out in separate calls... well, that's on them.


This will match what happens in most cases anyway since the C buffer DOES flush on \n most the time (and when it doesn't, users complain and I have to explain it to them AGAIN)


getting a lil off topic for templates btw.......
June 03, 2020
On 6/3/20 11:14 PM, Adam D. Ruppe wrote:

> getting a lil off topic for templates btw.......

Yeah, for sure.

My one final point would be that sometimes writing things out piecemeal based on logic is natural. I don't think the user should have to do acrobatics to fit it all in one call.

BTW, I misunderstood your original point, and thought you meant stdout and stderr should not be buffered at all.

-Steve
June 03, 2020
On 6/3/2020 7:28 PM, Adam D. Ruppe wrote:
> I kinda feel buffering should not be done across function boundaries for stdout and stderr. Other files maybe.

That's why there's "isatty()".
June 04, 2020
On Thursday, 4 June 2020 at 01:38:50 UTC, Walter Bright wrote:
> On 6/3/2020 3:21 PM, Steven Schveighoffer wrote:
>> Unless you are suggesting that Phobos completely drop support for interleaving printf and writeln calls? If you are, I assure you Walter will not accept that.
>
> I just checked with him, and he assured me he won't.

:)

> Also, a plain writeln("hello") must be thread safe just like puts("hello"). The reason is simply customer demand. I recall the bad old days when multiple threads would write to stdout, and you'd get:
>
>   heworllldo

That's simple, multiple threads shouldn't be writing to stdout ;) And that's only a half-joke. There of course must be a thread-safe writeln, just as there must be a non-thread-safe writeln (with different names, obviously). Which is the default should depend on the program. If you're only running one thread, or more to the point, only doing stdout from one thread [at a time], you have no use for those kinds of locks. It's just waste of cache. If you're not using any C libraries, or ones you are using aren't doing stdout, you have no use for FILE*. The OS is right there, a syscall away.

Phobos does make provisions for rolling your own sink (formattedWrite), which is great (more templates though :P). But, when you do sit down to write your own, core.sys is startlingly deprived of sys and is full of C. And now it becomes a roll your own syscalls... And then you find core.osthread full of pthread and not osthread.
June 04, 2020
On Wednesday, 3 June 2020 at 20:38:48 UTC, Stefan Koch wrote:
> On Wednesday, 3 June 2020 at 20:02:29 UTC, Walter Bright wrote:
>> On 6/3/2020 7:04 AM, Adam D. Ruppe wrote:
>>> tbh I think this case looks worse than it is.
>>
>> Not if you look at the code generated by:
>>
>>   import std.stdio;
>>
>>   void test()
>>   {
>>     writeln("hello");
>>   }
>>
>> It's embarrassing.
>
> Yes!
>
> and now look at std.traits and std.meta :)

or at std.conv.to:

See: https://www.youtube.com/watch?v=jNos&feature=youtu.be-Va01wA?t=1768
June 04, 2020
On Wednesday, 3 June 2020 at 04:46:54 UTC, Stefan Koch wrote:
> On Wednesday, 3 June 2020 at 03:19:37 UTC, Walter Bright wrote:
>> On 6/2/2020 7:41 PM, Adam D. Ruppe wrote:
>>> Most the rest are reflection helpers in Phobos, many of which could prolly be trivially replaced with inline checks but .... maybe not a big deal anyway. idk.
>>
>> The thing is, `writeln("hello")` can be expanded to `core.stdc.stdio.puts("hello")`. Done.
>>
>> Phobos seems to do a lot of "going around the Horn" instead of taking the canal.
>
> I have been saying that for years.
>
> Apparently you never used `-vcg-ast`.

I've recently been informed that this may have sounded dismissive.
It was not meant that way.

I am just a little frustrated that my work to make this issue visible seems to have gone unnoticed.

Then again .... I didn't exactly advertise it.
June 04, 2020
On Wednesday, 3 June 2020 at 11:22:23 UTC, Stefan Koch wrote:
> AND the user probably would rather have written a loop, but was forced by the language to use recursion.

That's definitely true.

> I will continue on type functions; if the conservative approaches don't work out.

I hope we can get type functions.

--
/Jacob Carlborg
June 04, 2020
On 6/3/2020 2:02 PM, Adam D. Ruppe wrote:
> That's why writeln cannot just blindly forward to puts. It may be able to forward to fwrite() though... which is very close to what it actually does,

What it actually does is generate a blizzard of templates into the object code.
June 04, 2020
On Wednesday, 3 June 2020 at 14:58:59 UTC, Stanislav Blinov wrote:

> A good `writeln` would not call into C  at all.

What would it do then? Call syscalls in the kernel directly? That's more or less only supported on Linux. It's definitely not supported on macOS. You can do it, but it's not supported and make break at any time. Go used to do that, something broke for them and now they're going through the C wrappers.

--
/Jacob Carlborg