November 30, 2009
Ary Borenszweig wrote:
> KennyTM~ wrote:
>>>> By
>>>> far the two most important pieces of I/O functionality I need are:
>>>>
>>>> 1.  Read a text file line-by-line.
>>>
>>> foreach (line; new Lines!(char) (new File ("foobar.txt")))
>>>    Cout (line).newline;
>>> }
>>>
>>
>> yuck.
> 
> Yuck?? I find that code very elegant. How would you like it to be?
foreach (line; open("foobar.txt")) {
  writeln(line);
}

I find the .newline idea rather hackish.
November 30, 2009
Pelle MÃ¥nsson:

> foreach (line; open("foobar.txt")) {
>    writeln(line);
> }

With the xio module of my dlibs:
import d.xio: xfile;

foreach (line; xfile("foobar.txt"))
    putr(line);

xfile is optimized to reduce memory rellocations as much as possible in the most common case of about 90 chars long lines.
There is an xstdin too.

Bye,
bearophile
November 30, 2009
bearophile wrote:
> Pelle MÃ¥nsson:
> 
>> foreach (line; open("foobar.txt")) {
>>    writeln(line);
>> }
> 
> With the xio module of my dlibs:
> import d.xio: xfile;
> 
> foreach (line; xfile("foobar.txt"))
>     putr(line);
> 
> xfile is optimized to reduce memory rellocations as much as possible in the most common case of about 90 chars long lines.
> There is an xstdin too.

Why not just reuse the same buffer as the previous line? That approach is inherently adaptive. And why is there a need for xstdin vs. xfile? Stdin _is_ a file.

Andrei
December 01, 2009
Andrei Alexandrescu:
> Why not just reuse the same buffer as the previous line? That approach is inherently adaptive.

That approach is unsafe. xfile yields byte strings, in D1. When I write 10 lines long scripts I usually don't need every bit of optimization, I need the less bug-prone code as possible, because the thing I have to optimize is my coding time. In D1 strings are mutable, so if you put them in an AA as keys you must dup them to avoid bugs if you reuse the same buffer.


>And why is there a need for xstdin vs. xfile? Stdin _is_ a file.<

I use it like this:
foreach (line; xstdin) { ... }
line is a string with newline at the end.
I know this isn't the best design, but it's the most handy for my purposes. I need to do a limited number of things in those scripts and iterating over the lines of a fine and over the lines of the stdin are the only two that matter.

Bye,
bearophile
December 01, 2009
bearophile wrote:
> Andrei Alexandrescu:
>> Why not just reuse the same buffer as the previous line? That approach is inherently adaptive.
> 
> That approach is unsafe. xfile yields byte strings, in D1. When I write 10 lines long scripts I usually don't need every bit of optimization, I need the less bug-prone code as possible, because the thing I have to optimize is my coding time. In D1 strings are mutable, so if you put them in an AA as keys you must dup them to avoid bugs if you reuse the same buffer.
> 

You'll have to .dup them if you want to use them as non-views always. I for one like that approach more.

Why call it xfile and not just open?

>> And why is there a need for xstdin vs. xfile? Stdin _is_ a file.<
> 
> I use it like this:
> foreach (line; xstdin) { ... }
> line is a string with newline at the end.
> I know this isn't the best design, but it's the most handy for my purposes. I need to do a limited number of things in those scripts and iterating over the lines of a fine and over the lines of the stdin are the only two that matter.
> 
> Bye,
> bearophile
December 01, 2009
On Tue, 01 Dec 2009 15:22:23 +0300, Pelle Månsson <pelle.mansson@gmail.com> wrote:

> bearophile wrote:
>> Andrei Alexandrescu:
>>> Why not just reuse the same buffer as the previous line? That approach is inherently adaptive.
>>  That approach is unsafe. xfile yields byte strings, in D1. When I write 10 lines long scripts I usually don't need every bit of optimization, I need the less bug-prone code as possible, because the thing I have to optimize is my coding time. In D1 strings are mutable, so if you put them in an AA as keys you must dup them to avoid bugs if you reuse the same buffer.
>>
>
> You'll have to .dup them if you want to use them as non-views always. I for one like that approach more.
>
> Why call it xfile and not just open?
>
>>> And why is there a need for xstdin vs. xfile? Stdin _is_ a file.<
>>  I use it like this:
>> foreach (line; xstdin) { ... }
>> line is a string with newline at the end.
>> I know this isn't the best design, but it's the most handy for my purposes. I need to do a limited number of things in those scripts and iterating over the lines of a fine and over the lines of the stdin are the only two that matter.
>>  Bye,
>> bearophile

In his notation, xfoo is a lazy version of foo (i.e. it reads file in chunks as opposed to reading the whole file at once).

So you are essentially asking, "why file instead of open?". What's the difference? It's a bikeshed discussion, but I believe file("filename") is more clear than open("filename"). Besides, I'm used to "close" everything I "open", which is not suitable here.
December 01, 2009
Denis Koroskin wrote:
> On Tue, 01 Dec 2009 15:22:23 +0300, Pelle Månsson <pelle.mansson@gmail.com> wrote:
> 
>> bearophile wrote:
>>> Andrei Alexandrescu:
>>>> Why not just reuse the same buffer as the previous line? That approach is inherently adaptive.
>>>  That approach is unsafe. xfile yields byte strings, in D1. When I write 10 lines long scripts I usually don't need every bit of optimization, I need the less bug-prone code as possible, because the thing I have to optimize is my coding time. In D1 strings are mutable, so if you put them in an AA as keys you must dup them to avoid bugs if you reuse the same buffer.
>>>
>>
>> You'll have to .dup them if you want to use them as non-views always. I for one like that approach more.
>>
>> Why call it xfile and not just open?
>>
>>>> And why is there a need for xstdin vs. xfile? Stdin _is_ a file.<
>>>  I use it like this:
>>> foreach (line; xstdin) { ... }
>>> line is a string with newline at the end.
>>> I know this isn't the best design, but it's the most handy for my purposes. I need to do a limited number of things in those scripts and iterating over the lines of a fine and over the lines of the stdin are the only two that matter.
>>>  Bye,
>>> bearophile
> 
> In his notation, xfoo is a lazy version of foo (i.e. it reads file in chunks as opposed to reading the whole file at once).
> 
> So you are essentially asking, "why file instead of open?". What's the difference? It's a bikeshed discussion, but I believe file("filename") is more clear than open("filename"). Besides, I'm used to "close" everything I "open", which is not suitable here/.

File looks like a constructor. You are not constructing a file you open for reading.

Also, saying that you close everything you open, are you deallocating everything you allocate as well? I feel we have moved past such symmetry.
December 01, 2009
Pelle Månsson wrote:
> File looks like a constructor. You are not constructing a file you open for reading.

"open" by itself is ambiguous.  What are you opening?  A window?  A network port?  I think the word "file" needs to be in there somewhere to disambiguate.


-- 
Rainer Deyke - rainerd@eldwood.com
December 01, 2009
On 30.11.2009 7:02, retard wrote:
> foreach (line; new Lines!(char) (new File ("foobar.txt")))
>    Cout (line).newline;
> }
>

To be fair, it's a bit simpler than that in Tango:

foreach (line; new TextFileInput("foobar.txt"))
   Cout (line).newline;
}

>>  2.  Read a whole file into an array of bytes.
>
> new File("foobar.bin").read()
>

This one too:

auto contents = File.get("foobar.bin");

get is a static method in the File class.


But I won't pretend that I think Tango I/O is easy to use.  There's a lot of interfaces and classes, and usually several ways to accomplish the same thing.  Some classes are just thin wrappers over others, which can be confusing.
December 01, 2009
Rainer Deyke:
> "open" by itself is ambiguous.  What are you opening?  A window?  A network port?  I think the word "file" needs to be in there somewhere to disambiguate.

When you program in Python you remember that open is a built-in function to open files :-)
When you want to open other things you import other names from some module.
So this ambiguity usually doesn't introduce bugs. It' a well known convention. Few well chosen conventions (sensible defaults) save you from a lot of useless coding.

Bye,
bearophile