Re: r25328 - docs/Perl6/Spec (fwd)

2009-02-17 Thread Timothy S. Nelson

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

Re: The use of roles in S16 (Was: Re: r25328 - docs/Perl6/Spec)

2009-02-17 Thread Dave Whipp

Daniel Ruoso wrote:


Maybe I'm thinking sideways again, but I haven't thought of open as
being a method of any IO object, because usually open is the thing
that gets you an IO Object.

I'd expect the plain open to be really a sub (maybe a is export
method in the generic IO role), that does whatever it needs to do to
provide you an IO object, including composing the roles according to the
features it supports.


An important concept of testability is to decouple the use of objects 
from their creation. Global factory functions make testing harder. That 
said, in perl we can always override them, which would provide the 
necessary seam.


One way of thinking about open is that it is a method on a file system 
object (or, more generally, on an IO server role):


  $fh = $*os.open($filename, :rw);
  $fh = $internet.open($url, :ro);
  ...

Admittedly, that approach would tend to lead Perl down the road of Java, 
so it's probably good to have a global sub to hide the underlying details.


It might seem even better be to introduce an object that represents the 
concept of an openable thing:


  $file = $file_system.find($filename);
  $fh = $file.open(:rw);

However, file systems are very OS-dependent, so it is generally 
counterproductive to attempt to build a data structure that shadows a 
filesystem (e.g. what happens to $file if the underlying file is renamed?)


Re: The use of roles in S16 (Was: Re: r25328 - docs/Perl6/Spec)

2009-02-17 Thread Brandon S. Allbery KF8NH

On 2009 Feb 16, at 22:44, Timothy S. Nelson wrote:
	So you can have a stream handle which does IO::Writeable, but will  
throw an error on any attempt to write?  Anyway, you've answered my  
question in the other e-mail.


Not sure what you're getting at, but the obvious example is a  
writeable handle on a full filesystem.  I don't think we want Perl  
deciding to remove IO::Writeable because the fs happens to be full at  
the instant it's opened.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part


The use of roles in S16 (Was: Re: r25328 - docs/Perl6/Spec)

2009-02-16 Thread Daniel Ruoso
Em Sáb, 2009-02-14 às 18:01 +0100, Leon Timmermans escreveu:
 On Sat, Feb 14, 2009 at 6:38 AM,  pugs-comm...@feather.perl6.nl wrote:
  +=head2 IO::Openable
  +This role implies that the object can be connected to, or listened on.
 I'm not sure if I really hate or love this. I'm not quite convinced if
 the use of it anyway.

Maybe I'm thinking sideways again, but I haven't thought of open as
being a method of any IO object, because usually open is the thing
that gets you an IO Object.

I'd expect the plain open to be really a sub (maybe a is export
method in the generic IO role), that does whatever it needs to do to
provide you an IO object, including composing the roles according to the
features it supports.

One important thing here, is that the roles are not intended to
represent attributes of the object. For instance, IO::Readable and
IO::Writeable are not going to be composed depending on the parameters
you send to open, but if you're in a Linux system, it should probably
return an object that does IO::Linux26 (which does IO::POSIX[$SomeLevel]
does IO::BSD[$Somewhat], which should also compose IO::Readable and
IO::Writeable independent of the open mode).

So the idea is not about having the object to have the roles dinamically
composed and de-composed depending on the access mode, but to have a way
to implement a custom IO object that performs only the features it want
to implement and yet being able to be used interchangeably with other IO
objects.

That way, in the code that uses an IO object, if you want to be able to
do unbuffered raw read from the object you receive as argument, you use

sub foo(IO::Readable $bar) {...}

and that way, it should be easy to provide a entirely made-up IO object
that can be used by foo without any harm or magic.

daniel



Re: The use of roles in S16 (Was: Re: r25328 - docs/Perl6/Spec)

2009-02-16 Thread Timothy S. Nelson

On Mon, 16 Feb 2009, Daniel Ruoso wrote:


Em Sáb, 2009-02-14 às 18:01 +0100, Leon Timmermans escreveu:

On Sat, Feb 14, 2009 at 6:38 AM,  pugs-comm...@feather.perl6.nl wrote:

+=head2 IO::Openable
+This role implies that the object can be connected to, or listened on.

I'm not sure if I really hate or love this. I'm not quite convinced if
the use of it anyway.


Maybe I'm thinking sideways again, but I haven't thought of open as
being a method of any IO object, because usually open is the thing
that gets you an IO Object.


[See my other e-mail to Leon for my comments on this].


One important thing here, is that the roles are not intended to
represent attributes of the object. For instance, IO::Readable and
IO::Writeable are not going to be composed depending on the parameters
you send to open, but if you're in a Linux system, it should probably
return an object that does IO::Linux26 (which does IO::POSIX[$SomeLevel]
does IO::BSD[$Somewhat], which should also compose IO::Readable and
IO::Writeable independent of the open mode).


	So you can have a stream handle which does IO::Writeable, but will 
throw an error on any attempt to write?  Anyway, you've answered my question 
in the other e-mail.


Thyanks,

-
| 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-


Re: r25328 - docs/Perl6/Spec

2009-02-15 Thread Timothy S. Nelson

On Sat, 14 Feb 2009, Leon Timmermans wrote:


On Sat, Feb 14, 2009 at 6:38 AM,  pugs-comm...@feather.perl6.nl wrote:

+=head2 IO::Openable
+
+This role implies that the object can be connected to, or listened on.
+
+=over 4
+
+=item open
+
+ method Bool open();
+
+Attempts to open the handle.  Depending on the implementation, this could be 
an open()
+call, a connect(), a listen(), or something similar.
+
+=back
+


I'm not sure if I really hate or love this. I'm not quite convinced if
the use of it anyway.


	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.



Why should this do POSIX? What about non-POSIX operating systems?


	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.


	I haven't written a program that was intended to be run on anything 
other than Unix or Embedded in years, so I'm quite pleased to get some input 
from non-POSIX types.  I'm happy (once we sort out what we're doing) for 
others to edit the thing, now that I've gone and restructured it all :).


	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.


http://www.parrotcode.org/docs/ops/io.html


+=item syscall
+


That functions should be well hidden


	Question -- is there a reason this is in IO, instead of eg. S29?  If 
not, I'll move it there.



+=item sysopen
+


I vote for sysopen (and all other sys functions) to be wiped out of existence.


	Disagree -- I think these belong in IO::Unbuffered.  Maybe we could 
make that optional, though :).



+=head1 Classes
+
+=head2 IO::File
+
+This does file input and output.
+
+class  IO::File does IO::POSIX does IO::Closeable does IO::Openable {
+...
+}
+
+=over
+
+=item init
+
+ method init(String $filename, $options?);
+ method init(Int $fd);
+
+ # Read
+ $fobj = new IO::File($filename);
+
+ # Write
+ $fobj = new IO::File($filename, :w);
+
+ # Read using file descriptor
+ $fobj = new IO::File($fd);
+
+Associate an IO object with an already-open file descriptor,
+presumably passed in from the parent process.
+
+=back


Why is that function called init, and not open? That's rather non-intuitive.


	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


This should do IO::Seekable and (to be written) IO::Stattable.


	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


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()
...

	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?



+=head2 IO::Socket::INET
+
+class  IO::Socket::INET does IO::Socket {
+...
+}
+
+=over
+
+=item  init
+
+ method Bool init($RemoteHost, $RemotePort, $LocalHost?, $LocalPort?);
+
+=item open($Listen?);
+
+If $Listen is 0, it does a connect().  If $Listen is 1, it does a connect() 
and a
+listen().  If $Listen is 2, it does a listen(), but no connect().
+


I *really* hate that interface, and I don't see how it covers an
accepting socket.


	Ok, I agree there's room for improvement, but I'm not 100% sure I 
agree on the details.



IMO there should be two calls


At least 3 :).


method IO connect($RemoteHost, $RemotePort, *%options)

where *%options can contain things like the local address,
non-blockingness, etc...


	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

	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.


	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 

Re: r25328 - docs/Perl6/Spec

2009-02-15 Thread Brandon S. Allbery KF8NH

On 2009 Feb 15, at 22:50, Timothy S. Nelson wrote:

On Sat, 14 Feb 2009, Leon Timmermans wrote:

+=item sysopen


I vote for sysopen (and all other sys functions) to be wiped out of  
existence.


Disagree -- I think these belong in IO::Unbuffered.  Maybe we could  
make that optional, though


I think sysopen etc. should go away, instead allowing open() to  
specify unbuffered.  In general anything that exposes a system file  
descriptor is an abstraction violation (unless in a module which is  
intended to do so; IO::Posix?).


The original intent behind sysopen() was to allow system file  
descriptor mode flags to be used; this was a workaround for perl5's  
open being insufficiently flexible.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part


Re: r25328 - docs/Perl6/Spec

2009-02-15 Thread Timothy S. Nelson

On Sun, 15 Feb 2009, Brandon S. Allbery KF8NH wrote:


On 2009 Feb 15, at 22:50, Timothy S. Nelson wrote:

On Sat, 14 Feb 2009, Leon Timmermans wrote:

+=item sysopen


I vote for sysopen (and all other sys functions) to be wiped out of 
existence.


Disagree -- I think these belong in IO::Unbuffered.  Maybe we could make 
that optional, though


I think sysopen etc. should go away, instead allowing open() to specify 
unbuffered.  In general anything that exposes a system file descriptor is an 
abstraction violation (unless in a module which is intended to do so; 
IO::Posix?).


	I'm not convinced about it being an option to open, but if you said 
instead that it should be an attribute on a role (IO::Openable?), then I'd 
happily agree.


The original intent behind sysopen() was to allow system file descriptor mode 
flags to be used; this was a workaround for perl5's open being insufficiently 
flexible.


That's good to know; thanks.

:)


-
| 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-



Re: r25328 - docs/Perl6/Spec

2009-02-14 Thread Leon Timmermans
On Sat, Feb 14, 2009 at 6:38 AM,  pugs-comm...@feather.perl6.nl wrote:
 +=head2 IO::Openable
 +
 +This role implies that the object can be connected to, or listened on.
 +
 +=over 4
 +
 +=item open
 +
 + method Bool open();
 +
 +Attempts to open the handle.  Depending on the implementation, this could be 
 an open()
 +call, a connect(), a listen(), or something similar.
 +
 +=back
 +

I'm not sure if I really hate or love this. I'm not quite convinced if
the use of it anyway.

 +=head2 IO::Socket
 +
 +role   IO::Socket does IO::POSIX does IO::Openable does IO::Closeable {
 +...
 +}
 +
 +=over
 +
 +=item IO.accept
 +
 +=item IO.bind
 +
 +=item Socket.pair
 +
 +our List of IO method pair(Int $domain, Int $type, Int $protocol)
 +
 +A wrapper for socketpair(2), returns a pair of IO objects representing the
 +reader and writer ends of the socket.
 +
 +   use Socket;
 +   ($r, $w) = Socket.pair(AF_UNIX, SOCK_STREAM, PF_UNSPEC);
 +
 +
 +=back
 +

Why should this do POSIX? What about non-POSIX operating systems?

 +=item syscall
 +

That functions should be well hidden

 +=item sysopen
 +

I vote for sysopen (and all other sys functions) to be wiped out of existence.

 +=head1 Classes
 +
 +=head2 IO::File
 +
 +This does file input and output.
 +
 +class  IO::File does IO::POSIX does IO::Closeable does IO::Openable {
 +...
 +}
 +
 +=over
 +
 +=item init
 +
 + method init(String $filename, $options?);
 + method init(Int $fd);
 +
 + # Read
 + $fobj = new IO::File($filename);
 +
 + # Write
 + $fobj = new IO::File($filename, :w);
 +
 + # Read using file descriptor
 + $fobj = new IO::File($fd);
 +
 +Associate an IO object with an already-open file descriptor,
 +presumably passed in from the parent process.
 +
 +=back

Why should this do POSIX? What about non-POSIX operating systems?

Why is that function called init, and not open? That's rather non-intuitive.

This should do IO::Seekable and (to be written) IO::Stattable.

 +=head2 IO::FileSystem
 +
 +This reads directories, worries about ownership and permissions, and the 
 like.
 +
 +class  IO::FileSystem does IO::POSIX does IO::Closeable does IO::Openable {
 +...
 +}

Why should this do POSIX? What about non-POSIX operating systems?

 +=head2 IO::Socket::INET
 +
 +class  IO::Socket::INET does IO::Socket {
 +...
 +}
 +
 +=over
 +
 +=item  init
 +
 + method Bool init($RemoteHost, $RemotePort, $LocalHost?, $LocalPort?);
 +
 +=item open($Listen?);
 +
 +If $Listen is 0, it does a connect().  If $Listen is 1, it does a connect() 
 and a
 +listen().  If $Listen is 2, it does a listen(), but no connect().
 +

I *really* hate that interface, and I don't see how it covers an
accepting socket.

IMO there should be two calls

method IO connect($RemoteHost, $RemotePort, *%options)

where *%options can contain things like the local address,
non-blockingness, etc...

method IO::Accepting listen($LocalHost, $LocalPort, *%options)

role IO::Accepting does IO::Socket {
IO accept();
}

 -=head1 Input and Output
 +=head2 IO::Pipe

 -=over 4
 +class  IO::Pipe does IO::POSIX does IO::Closeable does IO::Openable {
 +...
 +}

Why should this do POSIX? What about non-POSIX operating systems?

Regards,

Leon Timmermans


Re: r25328 - docs/Perl6/Spec

2009-02-14 Thread Brandon S. Allbery KF8NH

On 2009 Feb 14, at 12:01, Leon Timmermans wrote an unending refrain of:

Why should this do POSIX? What about non-POSIX operating systems?



I think the point here is that on POSIX systems that gets you ioctl()  
and fcntl(), and on non-POSIX systems either they don't exist or they  
throw runtime errors.  Aside from my earlier suggestion that non-POSIX  
systems generally have similar functions for which we should consider  
a common rubric, I'm not sure if this (does IO::POSIX) is backwards  
or if my/our(?) understanding of does is backwards, or possibly  
tangential.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




PGP.sig
Description: This is a digitally signed message part


Re: r25328 - docs/Perl6/Spec

2009-02-14 Thread Leon Timmermans
On Sat, Feb 14, 2009 at 10:31 PM, Brandon S. Allbery KF8NH
allb...@ece.cmu.edu wrote:

 I think the point here is that on POSIX systems that gets you ioctl() and
 fcntl(), and on non-POSIX systems either they don't exist or they throw
 runtime errors.  Aside from my earlier suggestion that non-POSIX systems
 generally have similar functions for which we should consider a common
 rubric, I'm not sure if this (does IO::POSIX) is backwards or if my/our(?)
 understanding of does is backwards, or possibly tangential.


IMO IO::POSIX should do exactly what it says it does: implement POSIX
as closely as possible. Since we probably can't implement much of it
on non-POSIX platforms, I don't think it should be part of our
specification (though I do think it should be part of our
implementation, because it is definitely useful).

I think it would be a lot better to implement a more portable wrapper
around the necessary functionality.

Regards,

Leon


r25328 - docs/Perl6/Spec

2009-02-13 Thread pugs-commits
Author: wayland
Date: 2009-02-14 06:38:34 +0100 (Sat, 14 Feb 2009)
New Revision: 25328

Modified:
   docs/Perl6/Spec/S16-io.pod
Log:
S16-io: Reorganised everything, grouping things together a bit better.  This is 
only a 
draft; otherwise I'd be a lot more careful :).  

Specifically, I've:
-   Taken some of the stuff that was spread throughout the document, and 
put it in 
with its associated role 
-   Created sections for a lot of the different classes we'll need

It still needs a lot of work.  



Modified: docs/Perl6/Spec/S16-io.pod
===
--- docs/Perl6/Spec/S16-io.pod  2009-02-14 05:28:12 UTC (rev 25327)
+++ docs/Perl6/Spec/S16-io.pod  2009-02-14 05:38:34 UTC (rev 25328)
@@ -82,8 +82,17 @@
 
 =item method Bool close()
 
-returns True on success, but might return an unthrown failure.
+Closes the file or pipe associated with the object.
 
+Returns True on success, but might return an unthrown failure.  
+Returns true only if IO buffers are successfully flushed and closes the system
+file descriptor.  
+
+You don't have to close IO if you are immediately going to do
+another Copen on it, because Copen will close it for you.  (See
+Copen.)  However, an explicit Cclose on an input file resets the line
+counter (C$.), while the implicit close done by Copen does not.
+
 =back
 
 =head2 IO::Buffered
@@ -184,6 +193,15 @@
 Reads the next character in the set $.encoding according to the
 $.locale.
 
+=item getc
+
+our Bool method getc (IO $self: Bool :async)
+
+Returns the next character from the input stream attached to IO,
+or the undefined value at end of file, or if there was an error (in
+the latter case C$! is set). The C:async flag lets the call
+return an undefined value if no character is immediately available.
+
 =cut
 
 =head2 IO::Writeable::Encoded
@@ -218,12 +236,165 @@
 $.output_field_seaparator and $.output_escape is set, it should do the
 escaping.
 
+=item print
+
+our Bool method print (IO $self: *...@list)
+our Bool multi print (*...@list)
+our Bool method print (Str $self: IO $io)
+
+Prints a string or a list of strings.  Returns Bool::True if
+successful, Failure otherwise.  The IO handle, if supplied, must be
+an object that supports I/O.  Indirect objects in Perl 6 must always
+be followed by a colon, and any indirect object more complicated than
+a variable should be put into parentheses.
+
+If IO is omitted, prints to C$*DEFOUT, which is aliased to C$*OUT
+when the program starts but may be temporarily or permanently rebound to
+some other file handle.  The form with leading dot prints C$_ to C$*DEFOUT
+unless an explicit filehandle is supplied.
+
+It is a compiler error to use a bare Cprint without arguments.
+(However, it's fine if you have an explicit argument list that evaluates to
+the empty list at runtime.)
+
+There is are no variables corresponding to Perl 5's C$, and
+C$\ variables.  Use Cjoin to interpose separators; use filehandle
+properties to change line endings.
+
+=item say
+
+our Bool method say (IO $self: *...@list)
+our Bool multi say (*...@list)
+our Bool method say (Str $self: IO $io)
+
+This is identical to print() except that it auto-appends a newline after
+the final argument.
+
+Was:print Hello, world!\n;
+Now:say   Hello, world!;
+
+As with Cprint, it is a compiler error to use a bare Csay without
+arguments.
+
+=item printf
+
+our Bool method printf (IO $self: Str $fmt, *...@list)
+our Bool multi printf (Str $fmt, *...@list)
+
+The function form works as in Perl 5 and always prints to $*DEFOUT.
+The method form uses IO handles, not formats, as objects.
+
 =back
 
+=head2 IO::Openable
+
+This role implies that the object can be connected to, or listened on.
+
+=over 4
+
+=item open
+
+ method Bool open();
+
+Attempts to open the handle.  Depending on the implementation, this could be 
an open() 
+call, a connect(), a listen(), or something similar.  
+
+=back
+
+=head2 IO::Socket
+
+role   IO::Socket does IO::POSIX does IO::Openable does IO::Closeable {
+...
+}
+
+=over
+
+=item IO.accept
+
+=item IO.bind
+
+=item Socket.pair
+
+our List of IO method pair(Int $domain, Int $type, Int $protocol)
+
+A wrapper for socketpair(2), returns a pair of IO objects representing the
+reader and writer ends of the socket.
+
+   use Socket;
+   ($r, $w) = Socket.pair(AF_UNIX, SOCK_STREAM, PF_UNSPEC);
+
+
+=back
+
 =head1 Filehandles, files, and directories
 
 =over 4
 
+=item IO.fcntl
+
+Available only as a handle method.
+
+=item IO.ioctl
+
+Available only as a handle method.
+
+=item IO.name
+
+The C.name method returns the name of the file/socket/uri the handle
+was opened with, if known.  Returns undef otherwise.  There is no
+corresponding Cname() function.
+
+=item syscall
+
+=item sysopen
+
+=item umask
+
+=item utime
+
+=back
+
+=head1 Classes
+
+=head2 IO::File
+
+This does file input and output.  
+
+class  IO::File does IO::POSIX