Re: Roles and IO?

2008-12-12 Thread Dmitry Karasik
Hi Leon!

 Leon Perl 5's solution is to use a fat interface, and raise an error if
 Leon an unsupported action is tried. 

Wouldn't the proposed solution raise an error if an unsupported role
method is tried? It's not that the proposed solution is inappropriate,
but the problem that I think you're trying to solve won't be solved 
by it.

-- 
Sincerely,
Dmitry Karasik



Re: Roles and IO?

2008-12-12 Thread Leon Timmermans
On Fri, Dec 12, 2008 at 3:04 AM, Jon Lang datawea...@gmail.com wrote:
 One of the things about roles is that once you have composed a bunch
 of them into another role, they're considered to be composed into
 whatever that role is composed into.  So does File would be
 equivalent to does Mappable does Pollable does Statable does Ownable
 (barring potential conflicts between Mappable, Pollable, Statable, and
 Ownable which File would presumably resolve).

I assumed a new role makes a new interface. In other words, that a
type that happens to do Pollable, Mappable, Statable and Ownable
wouldn't automatically do File in that case. If I was wrong my abuse
of subset wouldn't be necessary. Otherwise, maybe there should be a
clean way to do that. Now I'm thinking of it, wouldn't something like

our ::File = Mapable  Pollable  Statable  Ownable;

do the trick?

On Fri, Dec 12, 2008 at 3:52 AM, Mark J. Reed markjr...@gmail.com wrote:
 As Jonathan said, I think composition makes more sense here... but what if
 you have an interface that expects an IO object and does nothing with it but
 pass it into some other interface?  How does it declare that?  It seems like
 there still needs to be a generic superrole that means some non-empty but
 unspecified subset of these roles - maybe Closable would work, but it's
 not real clear.

Yeah, I wasn't clear on that, but I agree there should be some base
role shared by all these roles, though I'm wondering if that should be
shared by all handles or just IO handles. I see no reason why
Closable should be limited to IO handles, but I do see a use for
being able to indicate you're talking about an IO handle. I'd say it
makes sense to define IO as Readable | Writable.

On Fri, Dec 12, 2008 at 9:23 AM, Dmitry Karasik dmi...@karasik.eu.org wrote:
 Wouldn't the proposed solution raise an error if an unsupported role
 method is tried? It's not that the proposed solution is inappropriate,
 but the problem that I think you're trying to solve won't be solved
 by it.


In the worst case scenario, you're right. However if you use the roles
properly this shouldn't happen because you'd get an error much sooner.
If your interface expects a Seekable and you pass it a pipe, it will
immediately raise an error, instead of waiting until you try to use
it.

Regards,

Leon


Re: Roles and IO?

2008-12-12 Thread TSa

HaloO,

Leon Timmermans wrote:

I assumed a new role makes a new interface. In other words, that a
type that happens to do Pollable, Mappable, Statable and Ownable
wouldn't automatically do File in that case.


I also think that a new role File that does also the four others
is a new type on its own, particularly if it has a body that defines
additional stuff.



If I was wrong my abuse
of subset wouldn't be necessary. Otherwise, maybe there should be a
clean way to do that. Now I'm thinking of it, wouldn't something like

our ::File = Mapable  Pollable  Statable  Ownable;

do the trick?


IIRC, we deemed junctions as unfit for type constructors. A type
constraint that requires all types to match uses juxtaposition
and if one interface is enough a non-junctive | is used. So without
the ampersands it should be fine.



On Fri, Dec 12, 2008 at 9:23 AM, Dmitry Karasik dmi...@karasik.eu.org wrote:

Wouldn't the proposed solution raise an error if an unsupported role
method is tried? It's not that the proposed solution is inappropriate,
but the problem that I think you're trying to solve won't be solved
by it.



In the worst case scenario, you're right. However if you use the roles
properly this shouldn't happen because you'd get an error much sooner.
If your interface expects a Seekable and you pass it a pipe, it will
immediately raise an error, instead of waiting until you try to use
it.


Yes, I like the idea of a fine-grained set of roles and types
composed of it by juxtaposition. This allows signatures to state
their requirements clearly and machine enforcable. IOW, your approach
precisely solves the problem that fat interfaces can raise errors
only lately, that is when a call is attempted.


Regards, TSa.
--

The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Roles and IO?

2008-12-12 Thread Jon Lang
Leon Timmermans wrote:
 I assumed a new role makes a new interface. In other words, that a
 type that happens to do Pollable, Mappable, Statable and Ownable
 wouldn't automatically do File in that case. If I was wrong my abuse
 of subset wouldn't be necessary. Otherwise, maybe there should be a
 clean way to do that.

Hmm... true enough.

There was another contributer here who proposed an is like modifier
for type matching - I believe that he used £ for the purpose, in that
'File' would mean 'anything that does File', while '£ File' would mean
'anything that can be used in the same sort of ways as File'.  That
is, perl 6 uses nominative typing by default, while '£' would cause it
to use structural typing (i.e., duck-typing) instead.

FWIW, I'd be inclined to have anonymous roles use duck-typing by
default - that is, $Foo.does role {does Pollable; does Mappable; does
Statable; does Ownable} would be roughly equivalent to $Foo.does £
role {does Pollable; does Mappable; does Statable; does Ownable} -
the theory being that there's no way that a role that you generate on
the fly for testing purposes will ever match any of the roles composed
into a class through nominative typing; so the only way for it to be
at all useful is if it uses structural typing.

(I say roughly equivalent because I can see cause for defining £
Foo such that it only concerns itself with whether or not the class
being tested has all of the methods that Foo has, whereas the
anonymous role {does Foo} would match any role that does Foo.  As
such, you could say things like:

  role {does Foo; does £ Bar; has $baz}

to test for an object that .does Foo, has all of the methods of Bar,
and has an accessor method for $baz.

-- 
Jonathan Dataweaver Lang


Roles and IO?

2008-12-11 Thread Leon Timmermans
Hi all,

I've been thinking about how the IO interface should be organized in
perl6. It seems that part of S16 has received little attention so far.

One main problem with filehandles is that are rather diverse. The only
operation that all of them have in common is close. Reading versus
writing is a obvious difference, there are many more differences. One
can't seek a socket or a pipe, and likewise one can't accept on a
file. A listening socket can't even be read or written to. At the same
time, they all do have some parts in common with some other types of
handles.

Perl 5's solution is to use a fat interface, and raise an error if an
unsupported action is tried. I think that approach is needlessly
fragile. Another solution is to make a separate class for every
variety of handle, but IMO that's a plain fugly solution that simply
doesn't scale up very well.

What I propose is using role composition for *everything*. Most
importantly that includes the roles Readable and Writable, but also
things like Seekable, Mapable, Pollable, Statable, Ownable, Buffered
(does Readable), Socket, Acceptable (does Pollable), and more.

That may however make some interfaces is a bit wordy. I think that can
be conveyed using a subset like this (though that may be abusing the
feature).

subset File of Mapable  Pollable  Statable  Ownable;

In this case, these calls:

open($filename, :w);

would return a Writable  File, and

Socket::connect($remote_host, $port, :typeinet);

would return a Socket  Buffered  Pollable  Writable


Regards,

Leon Timmermans


Re: Roles and IO?

2008-12-11 Thread Jon Lang
Leon Timmermans wrote:
 What I propose is using role composition for *everything*. Most
 importantly that includes the roles Readable and Writable, but also
 things like Seekable, Mapable, Pollable, Statable, Ownable, Buffered
 (does Readable), Socket, Acceptable (does Pollable), and more.

 That may however make some interfaces is a bit wordy. I think that can
 be conveyed using a subset like this (though that may be abusing the
 feature).

 subset File of Mapable  Pollable  Statable  Ownable;

subset is the wrong approach: a subset is about taking an existing
role and restricting the range of objects that it will match.  What
you're really asking for are composite roles:

  role File does Mappable does Pollable does Statable does Ownable {}

One of the things about roles is that once you have composed a bunch
of them into another role, they're considered to be composed into
whatever that role is composed into.  So does File would be
equivalent to does Mappable does Pollable does Statable does Ownable
(barring potential conflicts between Mappable, Pollable, Statable, and
Ownable which File would presumably resolve).

-- 
Jonathan Dataweaver Lang


Re: Roles and IO?

2008-12-11 Thread Brandon S. Allbery KF8NH

On 2008 Dec 11, at 20:16, Leon Timmermans wrote:

One main problem with filehandles is that are rather diverse. The only
operation that all of them have in common is close. Reading versus


Be glad Xenix is dead.  There were filehandles which didn't even  
support close() (they were actually handles for shared memory and  
semaphores).


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




Re: Roles and IO?

2008-12-11 Thread Mark J. Reed
On Thu, Dec 11, 2008 at 8:16 PM, Leon Timmermans faw...@gmail.com wrote:

 What I propose is using role composition for *everything*. Most
 importantly that includes the roles Readable and Writable, but also
 things like Seekable, Mapable, Pollable, Statable, Ownable, Buffered
 (does Readable), Socket, Acceptable (does Pollable), and more.


Mapable is better spelled Mappable in English.  Arguably, it should be
Stattable as well; statable means state-able.


 That may however make some interfaces is a bit wordy. I think that can
 be conveyed using a subset like this (though that may be abusing the
 feature).

 subset File of Mapable  Pollable  Statable  Ownable;


As Jonathan said, I think composition makes more sense here... but what if
you have an interface that expects an IO object and does nothing with it but
pass it into some other interface?  How does it declare that?  It seems like
there still needs to be a generic superrole that means some non-empty but
unspecified subset of these roles - maybe Closable would work, but it's
not real clear.





-- 
Mark J. Reed markjr...@gmail.com