November 30, 2009
Mon, 30 Nov 2009 21:06:21 +0800, KennyTM~ wrote:

> On Nov 30, 09 19:01, 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?
> 
> Python do it like this:
> 
> for line in open("foobar.txt"):
>    print(line)
> 
> How many things you need to explain for that elegant code? Line? File? Cout? .newline?

Your argumentation is getting ridiculous. Reading and printing lines of a text file isn't by any means a good measure of standard library quality. I could define something like

  void printFileLines(string fn) { ... }

in my code and use it like this:

  printFileLines("foobar.txt");

When I'm programming with a systems programming language, I really do want to know if it reads the whole 100 GB file into memory before iterating or if not, what kind of buffer it is using. I often also need to work with endianess issues, codepage conversions, file system exceptions etc. If I only need to write simple code (== programming in the small) I might want to use some scripting language instead.

It's really hard to please both audiences without cluttering the stdlib api.
November 30, 2009
"retard" <re@tard.com.invalid> wrote in message news:hevn56$2to1$1@digitalmars.com...
> Mon, 30 Nov 2009 04:51:19 +0000, dsimcha wrote:
>>
>> Yeah, I dislike Tango's (and Java's) I/O design.  I think it's a classic example of overengineering.  I don't care how efficient, flexible, complete, etc. it is if it doesn't "just work" for the simple stuff.
>
> Are you sure you know what you're talking about?
>
>> 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;
> }
>
>> 2.  Read a whole file into an array of bytes.
>
> new File("foobar.bin").read()
>

Sure, once you actually know that and remember it. But trying to discover them in the first place (and discover what modules to import, and how many are needed for #1 up there?) through the API reference is a royal PITA. Part of the problem is that there's about million different classes, modules, structs, functions, whatever all dealing with accessing a file. So I have to figure out which method to use, which is made extra painful by the fact that each way of going about it is spread out across at least three different modules out of a total of I-don't-even-want-to-count. And of course there are zero "all" modules which just leaves me bouncing back up to the imports section of my code every time I make an edit.

"But it's right there in the tutorials, don't go looking through the API ref for it!" Well, ok, but there have been a lot of things I've needed to find (such as more in depth details) that the tuts don't tell me, and that I've had to look through the API ref or even source to find. So now I have to worry about not only what module to look in for what I want, but also which set of docs.


November 30, 2009
"retard" <re@tard.com.invalid> wrote in message news:hevo45$2to1$2@digitalmars.com...
> Mon, 30 Nov 2009 04:55:29 +0000, dsimcha wrote:
>
> Well, they have been teaching the Java i/o stuff to first year students for a while now. I completely agree that it's a bit too complicated for novices, but it's not the only bad thing:
>
> public static void main(String[] args)
> { System.out.println("Hello world!"); }
>

Correction:

class Main {
  public static void main(String[] args)
  { System.out.println("Hello world!"); }
}

(Or something like that anyway, been forever since I touched Java.)

> Wtf. They used to learn Scheme:
>
> (print "Hello World")
>
> I guess the PhD requirement is a bit exaggerating. Of course you do need to learn some basic concepts first. OTOH I know a handful of C programmers who just don't get why their (unbuffered) i/o routines always perform badly, and use libraries instead.


November 30, 2009
retard wrote:
> Mon, 30 Nov 2009 21:06:21 +0800, KennyTM~ wrote:
> 
>> On Nov 30, 09 19:01, 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?
>> Python do it like this:
>>
>> for line in open("foobar.txt"):
>>    print(line)
>>
>> How many things you need to explain for that elegant code? Line? File?
>> Cout? .newline?
> 
> Your argumentation is getting ridiculous. Reading and printing lines of a text file isn't by any means a good measure of standard library quality. I could define something like
> 
>   void printFileLines(string fn) { ... }
> 
> in my code and use it like this:
> 
>   printFileLines("foobar.txt");
> 
> When I'm programming with a systems programming language, I really do want to know if it reads the whole 100 GB file into memory before iterating or if not, what kind of buffer it is using. I often also need to work with endianess issues, codepage conversions, file system exceptions etc. If I only need to write simple code (== programming in the small) I might want to use some scripting language instead.
> 
> It's really hard to please both audiences without cluttering the stdlib api.

I don't have much time to spend on std.stdio nowadays, but the clear intent there is to provide range-based access that satisfies both audiences by using a good abstraction instead of cluttering the API.

Andrei
November 30, 2009
retard wrote:
> Mon, 30 Nov 2009 12:01:22 +0100, 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?
> 
> I guess something like this:
> 
> JustDoItWith("foobar.txt") {
>   ...
> }

foreach (char[] line; File("text.txt").byLine()) {
   ...
}

Efficient, flexible, convenient. Closes automatically the file, too, which Tango seems doesn't.


Andrei
November 30, 2009
On Mon, 30 Nov 2009 18:25:41 +0300, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> retard wrote:
>> Mon, 30 Nov 2009 12:01:22 +0100, 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?
>>  I guess something like this:
>>  JustDoItWith("foobar.txt") {
>>   ...
>> }
>
> foreach (char[] line; File("text.txt").byLine()) {
>     ...
> }
>
> Efficient, flexible, convenient. Closes automatically the file, too, which Tango seems doesn't.
>
>
> Andrei

If it closes file automatically, then why do you close it explicitly in slurp?

The code is almost the same except that "Lines" class works with any Input Stream (memory stream, file stream, network stream, pipe, i/o device etc).
November 30, 2009
== Quote from retard (re@tard.com.invalid)'s article
> Mon, 30 Nov 2009 21:06:21 +0800, KennyTM~ wrote:
> > On Nov 30, 09 19:01, 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?
> >
> > Python do it like this:
> >
> > for line in open("foobar.txt"):
> >    print(line)
> >
> > How many things you need to explain for that elegant code? Line? File? Cout? .newline?
> Your argumentation is getting ridiculous. Reading and printing lines of a
> text file isn't by any means a good measure of standard library quality.
> I could define something like
>   void printFileLines(string fn) { ... }
> in my code and use it like this:
>   printFileLines("foobar.txt");
> When I'm programming with a systems programming language, I really do
> want to know if it reads the whole 100 GB file into memory before
> iterating or if not, what kind of buffer it is using. I often also need
> to work with endianess issues, codepage conversions, file system
> exceptions etc. If I only need to write simple code (== programming in
> the small) I might want to use some scripting language instead.
> It's really hard to please both audiences without cluttering the stdlib
> api.

Right, but I do scientific work.  I've never written a polished app that's designed to be used by non-programmers or to be internationalized, where caring about things like unicode is important.  Most of my programming is very algorithm-centric and CPU-bound.  Anything I/O is generally regarded as just a means of getting data in to process it with your algorithms.  The algorithms are where I want to spend about 99% of my coding efforts, but I need a systems language here for performance reasons.  For I/O I just want the quickest, simplest thing available.  If the character set supports A, C, T, G, and U (the five characters of DNA and RNA), it's good enough for me.

I'm sure other niches have similar things:  Dead simple requirements in one dimension, but need for a full-fledged systems language to fulfill requirements in another dimension.  For example, I work with huge datasets and need to tune memory management pretty frequently.  Someone writing business software might care more about unicode and "proper" I/O than I do, but probably wouldn't care at all about the ability to tune memory management.  Maybe their need for a systems language is because they want native binaries or an easy way to interface with C code.
November 30, 2009
== Quote from dsimcha (dsimcha@yahoo.com)'s article
> == Quote from retard (re@tard.com.invalid)'s article
> > Mon, 30 Nov 2009 21:06:21 +0800, KennyTM~ wrote:
> > > On Nov 30, 09 19:01, 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?
> > >
> > > Python do it like this:
> > >
> > > for line in open("foobar.txt"):
> > >    print(line)
> > >
> > > How many things you need to explain for that elegant code? Line? File? Cout? .newline?
> > Your argumentation is getting ridiculous. Reading and printing lines of a
> > text file isn't by any means a good measure of standard library quality.
> > I could define something like
> >   void printFileLines(string fn) { ... }
> > in my code and use it like this:
> >   printFileLines("foobar.txt");
> > When I'm programming with a systems programming language, I really do
> > want to know if it reads the whole 100 GB file into memory before
> > iterating or if not, what kind of buffer it is using. I often also need
> > to work with endianess issues, codepage conversions, file system
> > exceptions etc. If I only need to write simple code (== programming in
> > the small) I might want to use some scripting language instead.
> > It's really hard to please both audiences without cluttering the stdlib
> > api.
> Right, but I do scientific work.  I've never written a polished app that's
> designed to be used by non-programmers or to be internationalized, where caring
> about things like unicode is important.  Most of my programming is very
> algorithm-centric and CPU-bound.  Anything I/O is generally regarded as just a
> means of getting data in to process it with your algorithms.  The algorithms are
> where I want to spend about 99% of my coding efforts, but I need a systems
> language here for performance reasons.  For I/O I just want the quickest, simplest
> thing available.  If the character set supports A, C, T, G, and U (the five
> characters of DNA and RNA), it's good enough for me.
> I'm sure other niches have similar things:  Dead simple requirements in one
> dimension, but need for a full-fledged systems language to fulfill requirements in
> another dimension.  For example, I work with huge datasets and need to tune memory
> management pretty frequently.  Someone writing business software might care more
> about unicode and "proper" I/O than I do, but probably wouldn't care at all about
> the ability to tune memory management.  Maybe their need for a systems language is
> because they want native binaries or an easy way to interface with C code.

I guess the idea here is that the beauty of D2/Phobos is that it's a systems programming language/lib, but one that only makes you care that it's a systems programming language for the parts of your code where you really need the power of a systems language.  For the parts of your code where that power is overkill, you can seamlessly shift into a more scripting language style of programming, without any messy glue layers, inter-language interfaces, etc. getting in the way.
November 30, 2009
Denis Koroskin wrote:
> On Mon, 30 Nov 2009 18:25:41 +0300, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> retard wrote:
>>> Mon, 30 Nov 2009 12:01:22 +0100, 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?
>>>  I guess something like this:
>>>  JustDoItWith("foobar.txt") {
>>>   ...
>>> }
>>
>> foreach (char[] line; File("text.txt").byLine()) {
>>     ...
>> }
>>
>> Efficient, flexible, convenient. Closes automatically the file, too, which Tango seems doesn't.
>>
>>
>> Andrei
> 
> If it closes file automatically, then why do you close it explicitly in slurp?

Because a compiler bug prevented the destructor from functioning correctly. The manual close does no harm now but of course should be removed.

> The code is almost the same except that "Lines" class works with any Input Stream (memory stream, file stream, network stream, pipe, i/o device etc).

I hope we'd be able to add such streams to Phobos too, perhaps using your networking library for transport.


Andrei
November 30, 2009
Lars T. Kyllingstad, el 30 de noviembre a las 12:16 me escribiste:
> 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?
> 
> 
> I wouldn't go as far as saying "yuck" to the above, but I like the Phobos way better:
> 
>   foreach (line; File("foobar.txt").byLine)
>   {
>      ...
>   }

I think you need a few more imports in Tango too.

-- 
Leandro Lucarella (AKA luca)                     http://llucax.com.ar/
----------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145  104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------
Come on, now,
I hear you're feeling down.
Well I can ease your pain
Get you on your feet again.