I didn't realise this hadn't gone to the list. Enjoy, all :).
---------- Forwarded message ----------
Date: Tue, 17 Feb 2009 14:34:07 +1100 (EST)
From: Timothy S. Nelson <wayl...@wayland.id.au>
To: Leon Timmermans <faw...@gmail.com>
Subject: Re: r25328 - docs/Perl6/Spec
On Mon, 16 Feb 2009, Leon Timmermans wrote:
On Mon, Feb 16, 2009 at 4:50 AM, Timothy S. Nelson
<wayl...@wayland.id.au> wrote:
I like it if we can make it work, but it may be too nonsensical to get
anything useful out of it. See my discussion below.
So far, all ideas based on it result in incredibly verbose code.
Creating an IO object should only be one statement. Anything else is
failure IMNSHO.
I see the problem; lets see if we can address that one too :).
First, let me reprint an example I gave below:
$socket = new IO::Socket::INET($RemoteHost, $RemotePort, OtherOption => 1);
$socket.Blockingness = 1; # Ok, maybe not blockingness, but you know what I
mean
$socket.OtherOption = 0; # Changed our mind from what we said in the class
creation call
$socket.open(); # This could be called "connect", maybe
I wasn't very clear here in what I was trying to demonstrate. This
example needed more "..." in it. I was assuming that the lines were not all
immediately following each other, but I in no way communicated that; sorry :).
Allow me to point out that if I wanted to write the first three lines
of what I proposed above in a single call, I'd do it like this:
$socket = new IO::Socket::INET($RemoteHost, $RemotePort,
OtherOption => 0,
Blockingness => 1,
);
...which I hope you'll agree is vaguely perlish. Hopefully we can also
choose sensible defaults for all these options.
My assumption was that people would sometimes want to create an IO
object without opening/connecting it, which is why I separated the creation and
.open() calls into two separate statements. But choosing sensible defaults
applies here; what if we had it open by default on creation unless someone
passes in a NoOpen => 1 option? Or maybe leave that to the implementations;
files open by default, and sockets don't?
This was an example of me not thinking. Basically, it was because it
was easier than writing IO::Readable IO::Writeable. I'll ignore the
question as it crops up throughout; someone feel free to replace POSIX with
something else.
Most of them should not be doing defined as implementing both. If a
file is opened read-only, the object it returns should not be
IO::Writeable. Hence, IO::File and such shouldn't be implementing
IO::Readable or IO::Writeable. Such things should remain orthogonal,
that is the whole idea of using roles!
Ok, I'm vaguely starting to see the purpose of all this :). Say I do
this:
$fh = new IO::File($filename);
while($_ = $fh.getline) {
push @lines;
}
$fh.close();
Yes I know there are better ways to do it, but how does IO::Readable
get there? Does it get mixed in at open time or something?
As a rakudo user, I'm also wondering whether we shouldn't be
referring more to the Parrot IO stuff, but that may just be me.
Parrot has very different goals for its IO interface: being able to
implement the IO of all implemented languages is more important than
having the best possible interface. In short, it's an implementation
detail.
Sorry, I wasn't clear again. I was thinking more from the point of
view that a number of the things we've said appear to refer to the underlying
OS calls and how they map to Perl6. I was thinking maybe we should talk about
how the Parrot calls map to Perl6 (in our discussion, not in the Spec). But
Maybe they're similar enough anyway that it doesn't really matter :).
Question -- is there a reason this is in IO, instead of eg. S29? If
not, I'll move it there.
AFAIK it's mostly used for obscure IO calls. I do agree it shouldn't
really be in S16 though.
Ok, I've moved it.
Disagree -- I think these belong in IO::Unbuffered. Maybe we could
make that optional, though :).
It may have a purpose in IO::POSIX, but other than that it doesn't
make too much sense to me. The interface is stuck in 1969. We should
make our open flexible enough that it can handle the use cases that
now require sysopen, without having the same sucky interface.
Sorry, I was unclear. I don't think those calls belong in
IO::Unbuffered, but that whatever does our open should, if the object does
IO::Unbuffered, apply the correct parameters. But I agree with you about
unification of interface.
Hmm. I still haven't gotten the hang of Perl 6. What I want is for
the name of this function to be the one that automatically gets called on
object creation. Then you do something like this:
$fobj = new IO::File($filename); # Creates handle
$fobj.open(); # opens file
Opening a file shouldn't be two lines, this is Perl! I think this
whole Openable thing is harming us. Simple things should be simple.
I agree about simplicity; see my comments at the top about opening/not
opening by default.
Should it? I'm just thinking about the interactions between IO::File
and IO::FileSystem. Maybe I'm just wondering about the name :). I'd argue
that maybe
I think I was out date, it's apparently called IO::FileSystem now
(more OS neutral I guess).
I think IO::Filesystem is more like a directory handle, and
IO::FileSystemEntry is more like IO::Stattable, which means that I need to
document IO::FileSystemEntry, and separate it from IO::FileSystem.
class IO::File ... {
has IO::FileSystemEntry $FSEntry;
...
}
...and that you could then do:
$fobj = new IO::File($filename);
if($fobj.FSEntry.ModificationTime > '2008') { print "Modified this year\n";
}
$fobj.open()
...
...and incidentally, the above is an example of why I wanted to
separate the object creation and the open calls. But with my comments at the
top of this e-mail, this would still be possible, but the "simple things
simple" rule would also be conserved.
In other words, I'm arguing that maybe we need a separate class for
the calls that do stuff to the "outside" of a file, verses the calls that do
stuff to the "inside" of a file. But maybe that's what roles are for. I'm
undecided. Thoughts, anyone?
Yeah, it should be a separate class, definitely. Has-a, not is-a.
Great :).
I'd break this into two; one like the init call above that creates
the object, and has the local and remote host/port passed in, but doesn't do
any calls.
Maybe something like this example for a client:
$socket = new IO::Socket::INET($RemoteHost, $RemotePort, OtherOption => 1);
$socket.Blockingness = 1; # Ok, maybe not blockingness, but you know what I
mean
$socket.OtherOption = 0; # Changed our mind from what we said in the class
creation call
$socket.open(); # This could be called "connect", maybe
That's simply not Perlish. There is no excuse why it shouldn't be
possible to open a socket in one line. This would be a setback
compared to Perl 5's IO::Socket::INET. Let's not make Perl 6 a new
Java. Simple things should be simple.
Agreed. I discussed this at the top of this e-mail, instead of here.
I'm kinda keen to call the function open() instead of connect(), so
that things are more consistent across the whole IO interface, but I agree
that attaching the listen stuff to that call was a bad idea.
Why would different things need to have the same name? That makes
absolutely no sense at all.
I guess I don't see them as being different in any way. In both cases,
you specify the data source that you want to connect to, and get a handle to
act on it.
For the server, I'd suggest an additional role, IO::Listening, that
has both listen() and accept() calls on it. Would that work for you? Or is
that essentially exactly what you suggested below, but with a name change?
:)
What I suggested is something that combines bind() and listen() on creation.
Ok, sounds good, although I'd like the option to turn them both off if
useful.
HTH, and hopefully I've communicated marginally better this time.
:)
---------------------------------------------------------------------
| Name: Tim Nelson | Because the Creator is, |
| E-mail: wayl...@wayland.id.au | I am |
---------------------------------------------------------------------
----BEGIN GEEK CODE BLOCK----
Version 3.12
GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V- PE(+) Y+>++ PGP->+++
R(+) !tv b++ DI++++ D G+ e++>++++ h! y-
-----END GEEK CODE BLOCK-----
---------------------------------------------------------------------
| Name: Tim Nelson | Because the Creator is, |
| E-mail: wayl...@wayland.id.au | I am |
---------------------------------------------------------------------
----BEGIN GEEK CODE BLOCK----
Version 3.12
GCS d+++ s+: a- C++$ U+++$ P+++$ L+++ E- W+ N+ w--- V-
PE(+) Y+>++ PGP->+++ R(+) !tv b++ DI++++ D G+ e++>++++ h! y-
-----END GEEK CODE BLOCK-----