Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Sam Vilain

Darren Duncan wrote:
3. Redefine prepare() and execute() such that the first is expressly for 
activities that can be done apart from a database (and hence can also be 
done for a connection handle that is closed at the time) while all 
activities that require database interaction are deferred to the second.


That would be nice, but there are some DBDs for which you need the database
on hand for $dbh.prepare() to work.  In particular, DBD::Oracle.

I think that what you are asking for can still work, though;

  # this module creates lots of SQL::Statement derived objects, without
  # necessarily loading DBI.
  use MyApp::Queries <%queries>;

  # not connect, so doesn't connect
  my $db = DBI.new( :source("myapp") );

  # prepare the objects as far as possible
  my %sths;
  for %queries.kv -> $query_id, $query_ast_or_template {
  %sths{$query_id} = $db.prepare($query_ast_or_template);
  }

  # connect
  $db.connect;

  # now proceed as normal
  my $sth = %sths;
  $sth.execute( :param("foo"), :this("that") );

So, effectively the prepare can happen at any time, and it's up to the
DBD to decide whether to actually do anything with it immediately or not.
ie, on Pg the STHs would be built before the DB is connected, and on Oracle
they are built the first time they are used (and then cached).

Now I realize that it may be critically important for an application to 
know at prepare() time about statically-determinable errors, such as 
mal-formed SQL syntax, where error detection is handled just by the 
database.  For their benefit, the prepare()+execute() duality could be 
broken up into more methods, either all used in sequence or some 
alternately to each other, so users get their errors when they want 
them.  But regardless of the solution, it should permit for all 
database-independent preparation to be separated out.


OK, so we have these stages;

  1. (optional) generate an AST from SQL
  2. (optional) generate SQL string from an AST
  3. generate a handle for the statement, sans connection
  4. prepare handle for execution, with connection
  5. execute statement

I think these all fit into;

  1. SQL::Statement.new(:sql("..."));
  2. $statement.as_sql;
  3. $dbh.prepare($statement) or $dbh.prepare($statement, :nodb);
  4. $dbh.prepare($statement) or $sth.prepare while connected
  5. $sth.execute

In particular, I don't think that the DB driver should automatically
get a chance to interfere with SQL::Statement; if they want to do that,
then they should specialise SQL::Statement.  IMHO.

Perhaps you have some other examples that don't fit this?

5. All details used to construct a connection handle should be 
completely decomposed rather than shoved into an ungainly "data 
source".


I interpret this as asking that the detailed parameters to the DBI
connection are expanded into named options rather than simply bundled into
a string.

That, I agree with, and I guess it would be useful occasionally to be
able to specify all that rather than just setting it up once and labelling
those connection parameters with a "source" that comes from ~/.dbi.
Particularly for writing gui dialogs for interactive database utilities.

Either way, you don't want most applications dealing with this complexity
at all, really.

6. DBI drivers should always be specified by users with their actual 
package name, such as 'DBD::SQLite', and not some alternate or 
abbreviated version that either leaves the 'DBD::' out or is spelled 
differently.  Similarly, the DBI driver loader should simply try to load 
exactly the driver name it is given, without munging of any type.  This 
approach is a lot more simple, flexible and lacks the cludges of the 
current DBI.  DBI driver implementers can also name their module 
anything they want, and don't have to name it 'DBD::*'. A DBI driver 
should not have to conform to anything except a specific API by which it 
is called, which includes its behaviour upon initialization, invocation, 
and destruction.


Is this useful?

I can't see a reason that the DBI.new() / DBI.connect() call shouldn't be
flexible in what it accepts;

  $dbh = DBI.new( :driver );   # means DBD::Rosetta
  $dbh = DBI.new( :driver ); # specify full package
  $dbh = DBI.new( :driver(Rosetta::Emulate::DBD) ); # pass type object
  $dbh = DBI.new( :driver(DBD::SQLite.new(:foo)) ); # pass driver object

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-04 Thread Sam Vilain

Darren Duncan wrote:
Okay, considering that using the same name prepare() like this may 
confuse some people, here is a refined solution that uses 3 methods 
instead; please disregard any contrary statements that I previously made:


I think I'm beginning to like it.

Allow me to suggest one or two further refinements...


  # Opt 1: A user that wants the most control can do this (new feature):

  my $sth1 = $dbh.compile( $sql_or_ast ); # always sans connection
  $sth1.prepare(); # always with connection, even if DBD doesn't use it
  $sth1.execute(); # always with connection


To me, the "compiled" form of the STH is related to the driver, but
re-usable between connections; you should be able to use something like;

  my $sth1 = DBD::SQLite.compile( $sql_or_ast );
  $sth1 = DBI.compile( :statement($sql_or_ast), :driver );

This would give you a STH which is divorced from the actual DB connection
instance.  Because you constructed it like this, without reference to a
(possibly unconnected) connection object, then $sth1.prepare is not
available.

You'd then need to use something like;

  $sth1.prepare($dbh);
  $dbh.prepare($sth1);

Note I also think what you wrote should work, too.

The new feature is if you decide to use compile(); you then give that 
method the arguments you would have given to prepare(), and you invoke 
prepare() on the result with no arguments; each DBD would decide for 
itself how the work is divided between compile() and prepare() with the 
limitation that compile() is not allowed to access the database; ideally 
the DBD would place as much work there as is possible, which would vary 
between Oracle/Pg/etc.


Agreed.


In particular, I don't think that the DB driver should automatically
get a chance to interfere with SQL::Statement; if they want to do that,
then they should specialise SQL::Statement.  IMHO.
I am operating under the assumption here that while the new DBI is 
designed to effectively support wrapper modules, the wrapper modules 
would also be altered from their current DBI-1-geared designs to 
accomodate DBI-2.

But still, what do you mean by "interfere"?


Well, when you parse the statement into an AST, the flavour of SQL will
affect how it is parsed and what is allowed.  Eg, Oracle has significant
features in some comments (query hints).  It also has quirky and somewhat
useless keywords like CONNECT BY.

So, when you ask a DBH connected to a driver to parse something, then it
will use that driver's SQL dialect, if one exists, but I still want to be
able to deal with SQL ASTs without implying a SQL flavour.


Either way, you don't want most applications dealing with this complexity
at all, really.
I am operating under the assumption that this system should work if 
there are no external config files that the DBI/DBD would read, and the 
application would provide that information; if its in a file, the 
application would read it in, or would explicitly tell DBI where it is.  
Or at least it should be possible for this to happen, even if a DBD 
defaults to look in a default location when it doesn't get the 
equivalent from the application.


Absolutely, that must work.  But it would still be nice to be able to
config this without digging through the application to see where the
password is written.

Unless there is a design flaw in DBI, we should not have to update that 
module just because a new driver came into existence whose name has not 
yet been hard-coded into DBI.

See this block for example, from DBI.pm v1.48:
 my $dbd_prefix_registry = {
  ad_  => { class => 'DBD::AnyData',},

  [...]

  yaswi_   => { class => 'DBD::Yaswi',},
 };
I mean, what's up with that?  I assume DBI 1 has this for legacy app 
backwards compatability, but DBI version 2 should never have to 
accomodate such abhorrent computer programming practices in its core.


Such a great word, abhorrent.  So fitting for this case.  It sure does
look like an (over&premature&misguided)-optimisation to avoid using the
full module name in an internal hash or something like that.  But then
maybe (I&we&none(Gaia)) are missing some context there.

Sam.


Re: Time::Local

2005-07-05 Thread Sam Vilain

Darren Duncan wrote:
Actually, there was a big oversight in my last message.  It does not 
handle approximate or relative dates, such as when you don't know the 
details.


FWIW, this is handled by DateTime::Incomplete, and also will be natively
supported by Date::Gregorian.

You're describing with this and other messages very much how the `Date'
distribution in pugs is being designed.  I'd very much appreciate input
on that interface.

Sam.


Re: Time::Local

2005-07-05 Thread Sam Vilain

Craig DeForest wrote:

Using the TAI epoch of 1958-01-01 00:00:00 has several advantages:
- TAI is recognized by international standards-setting bodies (BIPM).
	- Perl6 will then shake out the 31-bit time rollover a full 12 years before 


I like this in principle, however I wonder of the merits of professing to
return something of more accuracy than can actually ever be realistically
assured from any of the platforms Perl runs.

For a start, to convert from the available time source - the system clock
- to TAI, you need to know;

  a) current adjustments, or when the lack of adjustments is considered
 valid up to (after that date, of course, if the list of adjustments
 is not updated, getting the time or converting from a time to a date
 on a calendar is an exception).

  b) whether or not the system clock is automatically correcting for
 leap seconds, ie when ntpd is running and sync'ed up.

In any case, I'll add "to_TAI" as one of the marshalling methods for
Date objects in Date.pm

I guess it comes down to what guarantees we decide to make on the nature
of time().  If a leap second passes while the script is running, can the
value returned by time() regress?

In fact, do we even need a fixed epoch?  Why not just free-wheel it and
make 0 the time the script started, get it to count seconds, and let
interfaces for the system clock / orson database solve the hard problems.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-06 Thread Sam Vilain

Maxim Sloyko wrote:
 But this is not the point. The point was that usage of some file with 
passwords by *DEFAULT* is not the way to go, IMHO. It raises more 
problems than it solves.


Can you give an example of such a problem that wasn't already there?

Just to be clear, the file would only need to contain passwords if the
DBD requires them.

Sam.


Re: Dependency Injection

2005-07-06 Thread Sam Vilain

Piers Cawley wrote:

Then the harness that actually sets up the application would simply do
use Logger::DBI :dsn<...>, :user<...>, :password<>
and Logger::DBI would install itself as the default Logger class.
The question is, how does one write Injected to make this work? Or what
features do we need to be able to write Injected? Thinking about this, it
shouldn't be too hard to implement 'Injected' in Perl 5:


FWIW this is exactly what I would like to achieve with the Date objects;
allowing code that doesn't care about which Date representation they want
the ability to just say "any Date representation".

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-11 Thread Sam Vilain

Darren Duncan wrote:
I should emphasize that I never expected to be able to send any type of 
ASTs over the pipe to the database.  They would still be interpreted by 
the database driver for Perl and/or a wrapper thereon, into the database 
native format.  Its just that, to an application, it would appear that 
the ASTs were going over the pipe, as to their effect, even though they 
weren't behind the scenes.


Indeed.  I think the principle "bug" to "fix" is getting away from this
notion that all you need to do is do a little bit of template-based
query building, use the DBI and magically expect all database portability
problems to go away.

And then, recommend an approach that *is* portable.  Take your excellent
Rosetta infrastructure, pull the API to pieces, simplify the
documentation, then condone it as another simple and effective way to
write new database driven applications.  And hopefully simplify the DBDs
that necessarily need to do SQL parsing along the way.

So, everyone who is still happy to code to a particular database's SQL
language can continue to do so, but we'll eventually move the Cargo Cult
away from the situation we're in today where there is a vague promise of
portability but so many caveats that it's practically impossible to
write portable code.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-12 Thread Sam Vilain

Dean Arnold wrote:

RE: LOBs and "SQL Parse Trees": having recently implemented
LOB support for a JDBC driver (and soon for a DBD), I can assure
you that SQL parse trees are unneeded to support them. For databases


Great!

Perhaps you can shed some light on how to do it for this, then.

SQL command;

  INSERT INTO FOO (?, ?, ?, ?);

Column 3 is a BYTEA column in Pg and needs special peppering to work.

or this;

  SELECT
 *
  FROM
 FOO
  WHERE
 SOME_DATE_COLUMN > ?

SOME_DATE_COLUMN is the database native date type.  On Oracle you'll
need to convert the ? to a 'TO_DATE(?)'.

Sam.


Re: Raw bytes in perl6

2005-07-12 Thread Sam Vilain

Yuval Kogman wrote:

By the way, a nice use case for using the rules engine could be
"parsing" a stream of SAX events into a structure... XML::Simple in
perl6 could be really as simple as it sounds =)
Can anyone see this being retrofitted on top of current rules
semantics? How does PGE relate to this?


Yes, in fact SGML DTDs, once reduced to compact forms such as in;

http://search.cpan.org/src/SAMV/Perldoc-0.13/t/09-scottish.t

End up looking surprisingly similar to rules.

Sam.


Re: DBI v2 - The Plan and How You Can Help

2005-07-13 Thread Sam Vilain

Dean Arnold wrote:

Column 3 is a BYTEA column in Pg and needs special peppering to work.

What sort of "peppering" ? DBI provides SQL_BLOB, and SQL_CLOB
type descriptors (as well as SQL_BLOB_LOCATOR and SQL_CLOB_LOCATOR), so
presumably DBD::Pg (or any other DBD supporting LOBs) provides the
logic to map from
$sth->bind_param(3, $somelob, SQL_CLOB);

>>> SOME_DATE_COLUMN is the database native date type. On Oracle you'll
>>> need to convert the ? to a 'TO_DATE(?)'.
> Er, why ? I haven't used DBD::Oracle lately, but assuming you
> $sth->bind_param(1, '2005-07-13', SQL_DATE),
> I'd assume DBD::Oracle would be smart enough to communicate that

That bind_param peppering is precisely what I'm talking about, thanks
for demonstrating my point.  This requirement to use "bind_param" to
explicitly tell the DBI which placeholders correspond to which types
is rarely mentioned on any introductions to DBI, and as a result, very
few people carry this out in practice or are prepared to do the
necessary re-work to code bases to perform it.

So, DBD drivers need to hope that the database driver is smart enough to
pull apart the query, match it against the schema and automatically
setup the type correctly.  Perhaps many C database access libraries
provide enough information to do this, and pardon my ignorance for never
having written or worked on a DBD to this level - but I'm guessing that
such query introspection isn't always possible.

And, in a sense, requiring that the DBD is able to introspect the query
and DTRT is an "extra restriction" that DBD authors need to conform to,
setting the bar for conformance so high that it is practically impossible
to write portable database access code.

Please note that I'm not suggesting that we do away with the existing
interface, for people who don't care about writing portable database
code.  But I'd like to be able to write, for instance;

  use v6;
  use DBI-2;

  my $query = SQL {
  SELECT
  *
  FROM
  FOO
  LEFT JOIN BAR
  ON BAR.FOOID = FOO.ID
  };

  if ($one) {
  $query &&= SQL::WhereClause {
  ONE = $one
  };
  }

  my $dbh = DBI.connect(:source("myapp"));
  my $sth = $dbh.prepare($query);
  my $resultset = $sth.execute();

  for =$resultset -> @row {
 ...
  }

So what's happening here?

Well, the SQL construct marks the beginning of a segment of code that
happens to be in an alternate grammar, corresponding to some level of
ANSI SQL.  This builds an object which corresponds to that query.  In
fact, this can happen at compile time!  The SQL { } is actually a
closure that returns a SQL object when it is called.

The later SQL::WhereClause is the same; the variable isn't merely
interpolated, but is closed over, and included as if it were a
placeholder.  The &&= assignment operator uses the overloaded &&
operator on the SQL object, which sees it is being given a query
fragment, and adds it into the appropriate point on the SQL AST.

This should all be quite transparent - of course, an optional (but
portable) method of writing database queries.  And it's all deliciously
Perlish, yielding less fussing around with buggy code stitching together
queries, and more clean expression of queries using a standard language.

Of course it will be entirely possible to layer support for this sort of
thing atop any DBI interface; but this *is* a version 2, we do have
prototypes for the mechanics of all this stuff - and Done Right™, it
could actually fulfil the goal of DBI - being able to write
Database-driven applications that are truly independant of the database
product in use.  DBI v1 cuts the porting time down to next to nothing;
but we can get it even closer!

Sorry to "bang on" about this for so long, I'm sure you're all getting
sick of it by now- I had hoped that the original suggestion was just
going to be acknowledged as a valid way to enhance portability and
flexibility and considered without too much rehashing of what to some
is an old topic.

Sam.


Re: MML dispatch

2005-07-13 Thread Sam Vilain

Larry Wall wrote:

In addition to what chromatic said, I'd like to point out that you've
got the abstraction levels backwards by my lights: these days I
tend to think of the class as a restricted form of role.  A class is
restricted to having to provide a working interface to real objects.


Can I present an alternative way of viewing them, which I don't think
contradicts with what I've understood of them so far from the
Apocalypses and Synopses documents.

First a couple of definitions;

  A "runtime class" is a package name, and a collection of functions
  that form a "dispatch table".  There are actually two tables - one
  for private and one for public methods.  The public table links to
  "superclasses" where further dispatch may occur.

  A "method" on a Role or a Class is a function that takes two
  implicit arguments; a dispatch table for private method lookups, and
  one for public methods lookups.  The private dispatch table is bound
  when the function is added to a runtime class, but the public
  dispatch table is bound as late as possible (or until the class is
  closed in some situations).

Here's the meat:

  A Class is then a Role that gets its runtime class created, and all
  its methods' private dispatch tables bound at declaration time.

  A Role, on the other hand, leaves methods that can't be called,
  until they are bound into a "runtime class".  So they _look_ like
  they are flattened as the runtime classes are composed, unless you
  are introspecting to the sufficient level.

The "runtime class" would be the ::Type objects, and the real Class and
Role objects what you get from the .meta objects.

This might be a half empty / half full thing, I just thought you might
find that description interesting.  Note that I don't deal with "state",
I'm just treating attributes as if all they are is a set of accessor
functions, which store in an unspecified&unimportant location.

Sam.


Database Transactions and STM [was: Re: STM semantics, the Transactional role]

2005-07-17 Thread Sam Vilain

Yuval Kogman wrote:

everyone gets to choose, and another thing I have in mind is the
Transactional role...
DBI::Handle does Transactional;
To the STM rollbacker and type checker thingy this means that any IO
performed by DBI::Handle invoked code is OK - it can be reversed
using the Transactional interface it proposes.


Is this needed, when you can just;

  atomic {
 unsafeIO { $dbh.begin_work };

 unsafeIO { $dbh.do(...) };

 unsafeIO { $dbh.commit };
  } CATCH {
 $dbh.rollback;
  };

Of course, these unsafeIO calls can go inside a higher level wrapper
for the DBI, assuming that it is possible to detect whether or not
we are running in an atomic{ }, and "which" atomic block we are in.

As for the efficiency of things, hate to say it but that's really up
to the backend in use, and it's highly unlikely that anything other
than Parrot or GHC will support atomic{ }.

However a standard Role for this kind of behaviour might make sense.
Maybe draw up a prototype?

Sam.


Do I need "has $.foo;" for accessor-only virtual attributes?

2005-07-17 Thread Sam Vilain

Say I make an "accessor" method for an attribute that doesn't really
'exist'.

For instance, a good example of this is the "month_0" vs "month"
properties on a date object; I want to make both look equivalent as
real properties, but without the users of the class knowing which
one is the "real" one.

Users of the class includes people subclassing the class, so to them
they need to be able to use $.month_0 and $.month, even though there
is no "has $.month_0" declared in the Class implementation, only
"has $.month".

So, is $.month just shorthand for $?SELF.month, which happens to be
optimised away to a variable access in the common case where the
"method month" isn't defined, or has a sufficiently simple "is
accessor" trait in its declaration?

And that, in turn, $:month is actually $?SELF.(":month"), where
":month" is an alias for the submethod called "month".  After all, we
want Roles used by Classes to have access to this virtual attribute
coolness, too.

These simple definitions should make all sorts of OO tricks possible,
and reduces the definition of Classes to one that is purely
functional (ie, state is just a set of functions too).

Sam.


Re: Do I need "has $.foo;" for accessor-only virtual attributes?

2005-07-18 Thread Sam Vilain

Larry Wall wrote:
> > Users of the class includes people subclassing the class, so to them
> > they need to be able to use $.month_0 and $.month, even though there
> > is no "has $.month_0" declared in the Class implementation, only
> > "has $.month".

We thought about defining the attribute variables that way,
but decided that it would be clearer if they only ever refer to
real attributes declared in the current class.


Clearer in what way?

This implies that you cannot;

  - refactor classes into class heirarchies without performing
code review of all methods in the class and included roles.

  - "wrap" internal attribute access of a superclass in a subclass

This in turn implies that the $.foo syntax is, in general, bad
practice!

Allow me to demonstrate with an example, taken from S12 with
additions:

role Pet {
has $.collar = { Collar.new(Tag.new) };
method id () { return $.collar.tag }
method lose_collar () { undef $.collar }
has $.owner;
}

class Dog does Pet {
has $.location;
has $.home;
does Run;
method play {
if $owner.location ~~ $.location {
 $?SELF.lose_collar();
} else {
 $?SELF.run();
}
}
}

Now, as a user of the "Dog" class, I want to specialise it so that
the collar cannot be removed unless the dog is at home;

class Rotweiler is Dog {
method collar {
Proxy.new(
STORE => sub($self, $val) {
if ($val or $.location ~~ $.home) {
$self.SUPER::collar = $val;
} else {
die "rotweilers must be kept on a leash"
}
},
FETCH => { $self.SUPER::collar },
);
}
}

OK, so that's all well and good - you've changed the public property
"collar" so that your extra logic is there.

But what happens?  You lend your dog to someone else, they call
$dog.play, which calls lose_collar(), which sets $.collar directly.
Whoops, your Rotweiler is on the loose and slobbering over some
unsuspecting 4 year old.

This means that people designing classes and roles have to conciously
make the decision to use $?SELF.foo or ./foo() instead of the more
tempting looking and consistent $.foo

Perhaps you could elucidate your point by giving some examples of
when you *wouldn't* want $.foo to mean ./foo(), and when using a
private attribute would not be the "correct" solution.


: These simple definitions should make all sorts of OO tricks possible,
: and reduces the definition of Classes to one that is purely
: functional (ie, state is just a set of functions too).
One can certainly rewrite $.foo and $:foo in terms of lower level
functional primitives, but we must be careful not to confuse those
with higher-level virtual method calls.  Otherwise we are mixing OO
interface with OO implementation, and we've already discovered in
Perl 5 that that's a Bad Idea.


Funnily enough, I found in Perl 5 that it's a good idea.  Perhaps I
should demonstrate;

  package MyObject;
  use base qw( Class::Tangram );

  # define a string accessor for attribute "foo"
  our $fields = { string => ["foo"] };

  sub get_foo {
  my $self = shift;
  return $self->SUPER::get_foo . "bar";
  }
  sub set_foo {
  my $self = shift;
  my $new_foo = shift;
  return $self->SUPER::set_foo($new_foo . "baz");
  }

  package main;
  my $object = MyObject->new(foo => "foo");

  print $object->foo, "\n";   # prints "foobazbar"

As you can see, instead of ever looking into the object's internal
state, the "superclass" accessor is always used to find the object's
internal state.  This happens by munging @ISA at 'schema import'
time, and building the accessors in an extra inserted class.  Never
do you have to use $object->{foo}; in a sense, so long as you don't
circumvent the designed interface, the objects are already "opaque".


Interfaces between organisms are
cleaner when their innards stay in and their outtards stay out.


Cleaner, perhaps - but how will they ever reproduce?

Seriously, this isn't about innards (private attributes/properties)
and outtards (public attributes/properties).  This is about if you
make a new version and replace one of the outtards, that the
replaced outtards are not used anyway.

Perhaps it would be better to stick to mechanical things.  As you
have already stated you do not want to include general Quantum
Mechanical theory of extended entanglement into Perl 6 [1], it is
unlikely that we will be designing organisms with it.  Organisms do
not fit the mould; they do not reduce easily into clean components,
each piece of the whole is connected to the other via a quantum
entanglement field.  It is therefore not object oriented as the
internal state of every part of the system affects the whole.

So, I will use the analogy of an Automobile.  If you replace the
Engine of 

Re: Do I need "has $.foo;" for accessor-only virtual attributes?

2005-07-20 Thread Sam Vilain

Piers Cawley wrote:

> > Users of the class includes people subclassing the class, so to them
> > they need to be able to use $.month_0 and $.month, even though there
> > is no "has $.month_0" declared in the Class implementation, only
> > "has $.month".

We thought about defining the attribute variables that way,
but decided that it would be clearer if they only ever refer to
real attributes declared in the current class.

Clearer in what way?
This implies that you cannot;

[

  - refactor classes into class heirarchies without performing
code review of all methods in the class and included roles.

,
>>   - "wrap" internal attribute access of a superclass in a subclass
].map:{$_ ~

That's why it's generally a bad idea to use the C<$.whatever> forms outside
your basic accessor methods.

}

This in turn implies that the $.foo syntax is, in general, bad
practice!

Yup.


Not very huffmanised, is it?

Making $.foo =:= $?SELF.foo, and getting to the "raw" attribute $.SUPER::foo
seems like the better solution to me.  But of course, it would, because that's
how *I* program, and $?SELF != all(@coders).

Then we could even sneak in making $.foo(bar) a not-so-offensive ./foo(bar),
with ($.foo)(bar) meaning what $.foo(bar) currently means.  But that really
is a seperate issue, and speculation of it meaningless if we retain the
current specified behaviour.

Sam.


Re: Do I need "has $.foo;" for accessor-only virtual attributes?

2005-07-21 Thread Sam Vilain

Larry Wall wrote:

: Do the following exist then:
:has @x;  # private, lexically scoped

[...]

:has %y;  # private, lexically scoped

[...]

Yes, the sigil is fairly orthogonal to all this, hopefully.


Yes, for isn't the sigil just a compact form of saying "does Hash" or
"does Array" ?  (as well as being part of the unique name, of course)

Sam.


Re: Do I need "has $.foo;" for accessor-only virtual attributes?

2005-07-23 Thread Sam Vilain

Stevan Little wrote:
Yes, we have. One thing to consider is that it is much easier to get the 
"Role order doesn't matter" thing when they are composed. Once you start 
keeping the roles around, you run into the possiblity for such things as 
"next METHOD" being executed in Role context. I wont even speculate on 
what that should/could/would do, because I think we just shouldn't go 
there.


We talked briefly about considering this "flattening" as being a
run-time state thing rather than necessarily taking place in the
Meta-objects.  Is this still tenable?

Side effects like what happens if you do "higher level" stuff like 
run-time modification of Roles after they have been composed into 
classes can be addressed seperately.



No, that's correct.  We've just basically said that $.x is now a method
call, and as long as you stick to that invocation syntax it just has
to be declared as a method somewhere in the parentage/role-age of
this object.  But collisions in $.x declaration will be treated as
collisions in method declaration.
So we really are looking at closure based access to attributes. This 
also means that the idea behind P6Opaque as a storage format is very 
different. In theory, we could implement these style classes in a very 
"Inside-Out" manner. In a way, we could look at:

has $.x is rw;
as being sugar for this (pseudo) Perl 6:
{
my %x;
$?CLASS.meta.add_method('x' => method ($self: ?$value) {
%x{$self.id} = $value if $value.defined;
%x{$self.id};
 });
}


Yes, precisely ... except the method returns a Proxy object.
The proxy object responds differently depending on its context.

This is why I wanted the "accessors" to be traits hanging off the
code object itself, as described in http://xrl.us/guyx, as it makes
this not suck - a null accessor can be quickly optimised away to
direct variable access.  There is a pugs test for these in 
t/oo/attributes/mutators.t


Of course, this interface will need to be extended to support the full 
TIE-like interface that proxy objects support.  Thankfully as we're a 
lot more object oriented these days, I think we might be able to get 
away with:


  my $hash = %object.hash_property;
   :FETCH => should return a Hash object (or Facade), ie .does(Hash)

  my $array = %object.array_property;
   :FETCH => should return a Array object (or Facade), ie .does(Array)

As everything else is just a method call on the returned object.

Exactly which methods are uppercased into "is accessor"-provided entry
points is then a matter of style; though perhaps for a little sugar
a few should be provided where the function names are awkward to type, 
in particular .(post_circumfix:<{}>) and .(post_circumfix:<[]>)


To summarise with code for those who are lost;

  has $.foo;

would be sugar for:

  has $foo;
  method foo is accessor( :FETCH { $foo },
  :STORE -> $x { $foo = $x },
);

If you use \( $object.foo ) - that is, create a reference to the .foo 
property, you get a Proxy object;  the above should be considered 
functionally equivalent to;


  has $foo;
  method foo is rw {
  return Proxy.new(:FETCH { $foo },
   :STORE -> $x { $foo = $x },
  );
  }

This is extended into the other sigil types;

  has %.foo;

is sugar for this:

  has Hash $foo;   # or has %foo, but really, the point is it's
   # an implementation detail, right?
  method foo is rw {
  return Proxy.new( :FETCH{ $foo },  # or a facade
:STORE -> Hash $x { $foo = $x },
  )
but {
method post_circumfix:<{}>($key) is rw {
return Proxy.new( :FETCH{ $foo{$key} },
  :STORE -> $x { $foo{$key} = $x },
);
}
};
  }

Doesn't that look nice and ugly!  :-D

Note that this means that taking a reference to a hash slot is actually 
returning you a proxy object that will access the hash when you call it. 
 Sneaky, huh?  This means that this doesn't have to auto-vivify the 
slot any more, closing the caveat found in

t/builtins/arrays_and_hashes/exists.t by Darren Duncan:

  my $slot_ref = \( %foo );

This looks much tidier with Luke's nomenclature of "is accessor";

has Hash $foo;   # or has %foo, but really, whatever
method foo is accessor
:FETCH { $foo },
:STORE -> Hash $x { $foo = $x },
:HASHENT -> $key is accessor
   :FETCH { $foo{$key} },
   :STORE -> $x { $foo{$key} = $x };

Add brackets to suit.  The HASHENT is an early idea for an optional
shortcut; to avoid creating a facade when "all you wanna do" is define
what happens when you treat the object property as a Hash/Array via
$object.property{key}.  But it's still sugar for the above "but { }"
clause (or any other way of returning a Facade object that .does(Hash)).

Well, if we ditch the 

Re: Database Transactions and STM [was: Re: STM semantics, the Transactional role]

2005-07-23 Thread Sam Vilain

Yuval Kogman wrote:

everyone gets to choose, and another thing I have in mind is the
Transactional role...
DBI::Handle does Transactional;
To the STM rollbacker and type checker thingy this means that any IO
performed by DBI::Handle invoked code is OK - it can be reversed
using the Transactional interface it proposes.

Is this needed, when you can just;
  atomic {
 unsafeIO { $dbh.begin_work };

 unsafeIO { $dbh.do(...) };

 unsafeIO { $dbh.commit };
  } CATCH {
 $dbh.rollback;
  };

Why have STM like constructs if that's what you're going to do
anyway?
The point is to be able to compose unrelated atomic block into one
atomic action.
If we don't get some separation of concerns from STM we might as
well be using locks.


Sorry for the necro-equine flagellation, but I think STM would have to
support general nesting to be useful.  In fact I'd be highly surprised
if the Haskell STM implementation doesn't already support it.

We'll need this, because a "transparent" object persistence layer won't
want data to mismatch the database in the event of a rollback, as
Tangram takes some effort to ensure now in Perl 5.  So it will be doing
its own atomic { } stuff that will all "commit" to memory on the
successful database commit, or undo changes in the event of a rollback.

The end goal is to be able to give the DB layers enough hooks that we
can say a well written one Just Works™ in the face of atomic { }.

Does that seem relevant to the point you were making?

Sam.


Re: Subroutine and Method Introspection

2005-07-24 Thread Sam Vilain

chromatic wrote:

A12 and S12 describe introspection on objects and classes.  The
metaclass instance has the method getmethods() which returns "method
descriptors".  The design specifies several traits queryable through
these descriptors.

   [...]

Currently, there's no way to query these traits through introspection,
nor is there a description of the descriptors beyond indicating that
they're some sort of object.
I have no strong feeling as to what type of object they should be, but
they ought to support some sort of traits() method to return a list of

   [...]

Well, arguably Stevan's perl5/Perl6-MetaModel is the best place to
prototype such interfaces.

Getting traits requires deeper introspection.  You need to ask the
Meta-Objects themselves what properties they support.  In other words,
by looking at .meta.meta you should be able to see this.  Even though
we're aiming to avoid the Smalltalk '72 problem[1] of
meta-meta-meta-meta-model madness.  There is some early rantings of it
in modules/Perl-MetaModel/docs/perl6_meta_model.pod

Quite how far the "turtles all the way down" principle works will be an 
interesting test of the design, I think.  I wouldn't expect making 
changes to .meta objects 3-4 levels deep to work, and that they should 
be like a "reciprocal" (or a metaclass that can be its own metaclass).


Sam.

1. Piers Cawley drew the prior art connection here.  I forget the exact 
years, but there were two Smalltalk language versions, the first where 
each meta-model layer was independant, and the second where they had 
figured out how to make the system close back on itself simpler.  Maybe 
someone can give a better description than this.




Re: Exposing the Garbage Collector

2005-07-24 Thread Sam Vilain

Piers Cawley wrote:

Let's say I have a class, call it Foo which has a bunch of attributes, and I've
created a few of them. Then, at runtime I do:
   eval 'class Foo { has $.a_new_attribute is :default<10> }';
Assuming I've got the syntax right for defaulting an attribute, and lets assume
I have, the Perl runtime needs to chase down every instance of Foo or its
subclasses and add an attribute slot (adding a method to a class is nowhere
near as interesting, because every instance of the class shares a single class
object). 


But adding an attribute is simply defining a new method in the Class' 
instance methods.  And you don't need to chase down the objects for that.


What you wrote could be implemented as;

  class Foo {
 has $a_new_attribute is :default(10);
 sub a_new_attribute is accessor
:FETCH{ $a_new_attribute },
:STORE -> $val { $a_new_attribute = $val },
 }
  }

So this way the extra attribute can be lazily added.  The other ways of 
finding out that the property should be there, such as the visitor 
pattern interface, will "trip" the part that adds the slot to the object.


However I think this is somewhat besides your original point.

Sam.


Re: Do I need "has $.foo;" for accessor-only virtual attributes?

2005-07-24 Thread Sam Vilain

Stevan Little wrote:

This is extended into the other sigil types;
  has %.foo;
is sugar for this:
  has Hash $foo;   # or has %foo, but really, the point is it's
   # an implementation detail, right?
  method foo is rw {
  return Proxy.new( :FETCH{ $foo },  # or a facade
:STORE -> Hash $x { $foo = $x },
  )
but {
method post_circumfix:<{}>($key) is rw {
return Proxy.new( :FETCH{ $foo{$key} },
  :STORE -> $x { $foo{$key} = $x },
);
}
};
  }
I am not sure if it makes sense to handle whats inside the hash with the 
accessor. I think that is the responsibility of either the hash 
container type itself, or what you really need here is some kind of 
object to wrap your hash and get such fine grained control. But that is 
just my gut reaction.


This is what the monkey-but syntax is about.  The returned Proxy object
must behave like a Hash for the property to behave like a hash, which
(minimally) means implementing the post_circumfix:<{}>($key) method.

Quite what that looks like in the metamodel is another question; the above
makes it look like monkey-but can make anonymous sub-classes that derive
new methods, which I inducted as being potentially legal syntax from the
examples of monkey-but I've seen so far.  Ideally this wouldn't have to
happen every time the attribute is accessed ;).


So, if you want a "visitor pattern", you grab a visitor iterator
via the Meta-Objects, right?  Which could also solve the 
STORABLE_freeze/STORABLE_thaw / Pixie::Complicity / etc problem by 
unifying the way that "foreign" objects can marshall themselves to 
Perl objects when required.
You mean for persistence operations? Where you need to thoroughly 
inspect the object to save it to disk/DB/etc.


Yes, that sort of thing.  Sending objects between processes in some
marshalled format, like YAML, XML, binary/Storable, etc.  But there
are plenty of other applications of the visitor pattern; I think a
nice tidy split would be to either allow walking at the public attribute
or the private attribute level.

In the face of AUTOMETH, the public "attibutes" of a Class might not be
trivial to find, or indeed be infinite.  So the class needs to have a way
to tell the visitor iterator which public attributes are considered to
represent the entire state of the object.

Of course, the same problem doesn't apply for visiting private attributes,
which are either there or not.  I can see arguments for walking at both
levels for certain tasks.

I think the ideal way to write something like that would be to write is 
as a metaobject. Meaning using the Persistent metaclass. As opposed to 
using something on the "user" side of things to interogate the "meta" 
side of things. But this may be because I am too deep into the meta side 
if things right now.


Yes, I imagine that the iterator will be returned from a metaobject
method, with gratuitous use of callbacks to make the simple uses really
simple; including the logical equivalent of $File::Find::prune = 1.

Sam.

ps. Monkey-but Monkey-but Monkey-but


RE: $object.meta.isa(?) redux

2005-08-10 Thread Sam Vilain
On Wed, 2005-08-10 at 21:00 -0400, Joe Gottman wrote:
>Will there be an operator for symmetric difference?  I nominate (^).

That makes sense, although bear in mind that the existing Set module for
Perl 6, and the Set::Scalar and Set::Object modules for Perl 5 use % for
this (largely due to overloading restrictions, of course).

There is no unicode or mathematical operator for symmetric difference,
it seems.

Sam.



Re: Time::Local

2005-08-15 Thread Sam Vilain
On Mon, 2005-08-15 at 16:33 -0700, Larry Wall wrote:
> : I would assume that you would choose time 0.0 =  Jan 1, 2000 at 00:00:00.0
> : TAI (December 31, 1999 at 23:59:29.0 UTC), making the whole thing free of
> : any UTC interferences.  But there is an argument for making the zero point a
> : recognizable boundary in civil time.
> That's my leaning--if I thought it might encourage the abandonment of
> civil leap seconds, I'd be glad to nail it to Jan 1, 2000, 00:00:00.0 UTC.

If we're going with TAI, can't we just nail it to the epoch it defines,
instead?

Sam.



Re: Time::Local

2005-08-16 Thread Sam Vilain
On Mon, 2005-08-15 at 22:24 -0700, Larry Wall wrote:
> : > That's my leaning--if I thought it might encourage the abandonment of
> : > civil leap seconds, I'd be glad to nail it to Jan 1, 2000, 00:00:00.0 UTC.
> : If we're going with TAI, can't we just nail it to the epoch it defines,
> : instead?
> Because I'm a megalomaniac, silly dilly.  Plus I like round numbers.
> Not to mention the fact that it makes it really easy to calculate days
> since 2000, give or take a squishy leapsecond or three.
> But the best part is that if we abandon UTC leap seconds for civil time,
> we don't have to remember leap seconds going forward, only backward from
> 2000.

Why on earth would you want to encourage such a short sighted
programming practise?  The earth wobbles like a spinning top.  In fact
its speed increased after the two major Earthquakes in Antarctica and
Indonesia last December.  Subtle adjustments are necessary to track
this; perhaps including the possibility that the Earth's rotational
speed might change by more than one second per day.  Just why were the
Mayan, Babylonian and Aztec calendars 360 days long, anyway?  Were days
20 minutes longer then?  These are questions I've been wondering as an
old machine I have loses about this amount ... it would certainly
explain it if the machine was actually so old it used a Mayan timer
chip.  (Sometimes the impossible has a coherency to it that the merely
improbable simply lacks...)

How about killing the argument by saying the epoch is only guaranteed by
the language to be relative to the same value within the lifetime of a
script, relative to 0.0 TAI in 1958 or whenever it was.  Then Perl 6
implementations are free to pick their own epoch, and possibly also
annotate the time via traits/properties as not being confirmed to be NTP
synced, etc.  Date modules (which, really, people should be using) then
have something sensible to work with and can easily provide the
alternate times.  Environments that really can't guarantee an absolute
epoch can simply return unanchored times and let the modules throw
exceptions when you try to convert them to real times or times with
impossible levels of accuracy.

Sam.



Re: Time::Local

2005-08-17 Thread Sam Vilain
On Wed, 2005-08-17 at 01:28 -0500, Dave Rolsky wrote:
> > Why on earth would you want to encourage such a short sighted
> > programming practise?  The earth wobbles like a spinning top.  In fact
> It's hardly short sighted to want leap seconds to be abandoned (not in 
> Perl but world wide).  The few people who _really_ care about syncing to 
> midnight can still have them, but the rest of the world would be just fine 
> with a leap hour every couple hundred years.

Well, right now one of the great things about looking at the wall to
read the clock and see the time, is that you know that based on the time
of day and the time of year, and where you are, roughly how far through
the actual solar day it is.  It's crude, but useful.  Just ask a Dairy
Farmer.

What else do you want the time of day to represent?  You would prefer it
something completely arbitrary, just to make it easier to program with?

That we don't just use a straight solar clock is probably down to the
fact that it was technically infeasible to have one without a sundial,
which obviously doesn't work at night or in England.

> > alternate times.  Environments that really can't guarantee an absolute 
> > epoch can simply return unanchored times and let the modules throw 
> > exceptions when you try to convert them to real times or times with 
> > impossible levels of accuracy.
> Great, so now code that works in one environment throws a "cannot find an 
> up-to-date leap seconds table" exception in another?  Eek!

Well, only if you try to do something silly like ask for the number of
seconds between two points of time in different days a long time in the
future, where those times were composed from Gregorian components.  If
you were to ask for the number of minutes, or not cross the boundary of
when leap seconds are allowed, then it would still be OK.

I would expect a similar exception if I tried to calculate the number of
hours between two dates in an unknown timezone.

Of course feel free to consider this all worthless heckling, given the
lack of time I've been putting towards an implementation of all this ;).

Sam.



Complex types

2005-10-12 Thread Sam Vilain
Hi all,

Is it intentional that S09 lists unboxed complex types, but equivalent
Boxed types are missing from the "Types" section in S06?

Sam.



Re: new sigil

2005-10-20 Thread Sam Vilain
On Thu, 2005-10-20 at 08:45 -0700, Larry Wall wrote:
> More info.  ¢T is a scalar variable just like $T, but enforces a
> class view, so you can use it as a class parameter, and pass any
> object to it, but only access the classish aspects of the object.
> The only other big difference is that you can use it in the class
> syntactic slot, so it's legal to say ¢T $x where it would be illegal
> to say $T $x.

Is this necessary?  Isn't putting a variable before another variable
like that in the correct context (subroutine declaration, in this case),
enough to imply that the variable "does Class" ?

While I'm not arguing against another sigil type, I think this would
distinguish it from the other sigils % and @, which are just an implicit
(does Hash) / (does Array), as well as being a part of the unique name,
as I understand it so far.

This makes me wonder which language feature is used to describe sigils
themselves.  Can I define my own sigils with their own type
implications?

Sam.

ps, X11 users, if you have any key bound to "AltGr", then "AltGr" + C
might well give you a ¢ sign without any extra reconfiguration.





Re: Why submethods

2005-10-30 Thread Sam Vilain
On Sat, 2005-10-29 at 17:30 -0400, Stevan Little wrote:
> However, it could also be that the creator of Foo did not intend for  
> subclasses to be able to "Just Work", and that the whole idea of Foo  
> is to do a "Template Method" style pattern in which subclasses must  
> implement the &help_process_data submethod in order for things to  
> work. This is an entirely valid usage for a submethod, and in fact, I  
> think it is an excellent way for implementing the "Template Method"  
> pattern.

Hmm.  I think I much prefer;

  method you_must_implement { ... }

or a trait, perhaps

  method you_must_implement is required;

I think that methods disappearing out of scope in subclasses is just
Nasty And Wrong™, for the exact reason Luke outlined.  Side-effects like
that are just asking for trouble IMHO.

> It is also possible that we could bring over the role idea of  
> "required methods" and have the same basic principle relate to  
> classes and submethods. If marked as such, a submethod is required to  
> be implemented by a subclass, or class composition fails.
> I think that could be a useful feature which would allow very safe
> re-use along those lines.

Good point, which is why the "is required" as above would be better.

It seems to me that there's an awful lot of specification going into
these varied types of methods.

  Method Type  Purpose   DispatchVisibility
 ---|--|---|
  $.method()|  external API|  MMD  |  all
  $.submethod() |  refactoring |  package  |  single
  $:private()   |  internal API|  package  |  single

I must admit I also fail to see the difference between submethods and
private methods.  And what do I use for methods that I don't want to
make visible to "the world"?

Perhaps a more useful definition might be that submethods are only
available on $?SELF (and are still subject to normal dispatch).

Sam.



Re: $_ defaulting for mutating ops

2005-11-02 Thread Sam Vilain
On Wed, 2005-11-02 at 11:46 -0700, John Williams wrote:
> It is not so much an operator, as it is a subroutine with really strange
> syntax, and the side-effect of changing the $_ variable.  You need to use
> an operator to get it to affect a different variable.

operators _are_ subroutines.  There is no difference.

 multi sub *infix:<*> (Set $one, Set $two) returns Set {
 $one.intersection($two);
 }

Sam.



Re: $_ defaulting for mutating ops

2005-11-02 Thread Sam Vilain
On Wed, 2005-11-02 at 09:03 -0500, Rob Kinyon wrote:
> I think the difference comes from the Principle of Least Surprise. The
> various operators being discussed in this thread are all operators
> which are in languages that have common use - C, C++, Java, the .Net
> stack, etc. Regexen and the various built-ins are generally considered
> to be Perl-specific, so if they're weird, this is just a Perl-ism. The
> PoLS doesn't apply.
> 
> Yes, from a consistency point of view, ALL operators should default to
> $_ or some other sensible item ($*STDIN for <>, etc). However, the
> PoLS does need to guide our decisions.

I think the PoLS should be applied firstmost and foremost to a person
who is learning the language without any preconceptions of how previous
languages work.  The logical building blocks of how the language works
should build on each other; the fewer exceptions relative to *those
foundations* the better.

Specifically, catering for the preconceptions of how the language
behaves as a whole to those trained in lower order languages like you
mention (though is .net a language?) should probably be avoided.

That being said, there are probably other more pressing reasons that ops
should not accept $_ as default; I would guess, for a start, it makes
determining semantics very difficult.  Does  ++; mean &postfix:<++> or
&prefix:<++> ?

Sam.



Re: scalar/array contexts in perl5 vs. perl6

2005-12-04 Thread Sam Vilain
On Sun, 2005-12-04 at 13:10 -0500, Mike Li wrote:
> what is a good translation of the following C into perl6?
> 
 [...]
>int x = 0; int y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; y[x++]++; /* line
> that matters */
 [...]
> 
> 
> in perl5, i would've written something like:
> 
> my $x = 0; my @y = 1..9; @y[$x++]++; print "$x\n"; print "@y\n"
> 

Note that when you run this in perl 5:

$ perl -we 'my $x = 0; my @y = 1..9; @y[$x++]++; print "$x\n";
print "@y\n"'
Scalar value @y[$x++] better written as $y[$x++] at -e line 1.
1
2 2 3 4 5 6 7 8 9

You've already used a Perl6-ism!

> but in perl6, the '@' sigil always means list context, so should i
> write the following?
> 
> 
> my $x = 0; my @y = 1..9; [EMAIL PROTECTED]; print "$x\n"; print "@y\n"
> 

I'm not sure what you're trying to do with all those derefs, but the
only change you need to make to your original code is to put the @y
interpolation inside a block;

{ my $x = 0; my @y = 1..9; @y[$x++]++; print "$x\n"; print "{ @y }\n" }

Try downloading and installing pugs; it's great for trying out this sort
of thing!

Sam.



Re: Some thoughts on threading

2005-12-11 Thread Sam Vilain
On Thu, 2005-12-08 at 17:16 +0100, Ron Blaschke wrote:
> The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software."
> [1] He starts with "The biggest sea change in software development since
> the OO revolution is knocking at the door, and its name is Concurrency."

Perhaps have a read of:

http://svn.openfoundry.org/pugs/docs/AES/S17draft.pod

Two non-traditional methods of concurrency are discussed;

  * atomic blocks - an atomic { } guard around a block that, assuming
the block performs no I/O, will guarantee atomic
success or failure of the block.

  * co-routines - essentially co-operative multitasking between
  'blocking' threads that actually switch tasks when
  they block (or yield).

There is also some stuff there on other types of timesharing and
multiprocessing - Threads, Processes and Multiplexing (like Ruby).

Sam.



Re: handling undef - second draft

2005-12-18 Thread Sam Vilain
On Sat, 2005-12-17 at 17:27 -0800, Darren Duncan wrote:
> 3. A flag that says we know that some operation failed, such as would 
> be exploited in the " err " 
> situations.
> This concept is like an exception which isn't thrown but returned.

"Dropping" an exception, perhaps?  :)

> 1. I accept the proposal that we just make another class that 
> implements the SQL concept of a null value, perhaps named Null or 
> SQL::Null, rather than having this behaviour in the core language, so 
> that should simplify the rest of the discussion.  If someone wants 
> undefs to propagate through expressions like SQL's NULLs do, rather 
> than failing or defaulting, then this can be done with the new class. 
> A Null object would be defined but false.  It would overload standard 
> operators so that most expressions involving it would propagate a 
> Null object, or compare unequally as desired.  Therefore, this sort 
> of behaviour will be isolated and standard data types won't behave 
> this way by default.

I think this is out of scope; if a module chooses to use "undef" as a
well defined part of its interface, that's its call.

> 2. Modify the 'Exceptions' section of S04 so that built-in functions 
> return a 'error' or 'failure' or 'exception' if they fail, instead of 
> an "interesting value of undef".  The behaviour and handling of or 
> response to these is essentially unchanged, but the value is called 
> something more distinctive and it is not called 'undef'.  Instead of 
> testing for .defined(), invoke a different method like .failed() or 
> .error() instead; invoking .defined() on an error should perhaps 
> return true instead of false.  Perhaps update err() to activate on 
> the error rather than or in addition to undef.

I'm not sure what this adds.  You ask for a system call, you don't get a
result.  In other words, the result is undefined, and it has a
supplemental error.

It just seems a bit silly to make the "err" operator have to call *two*
methods in sequence, it would be a hack just for system calls.

Besides, aren't all these values just "undef but { .error = '...' }"
etc?

> 3. Have the functionality of 'use fatal' turned on by default in 
> large programs, though not one-liners, and it can be turned off 
> otherwise.  It is safer to have them brought to your attention where 
> you make a conscious effort to respond to or dismiss them.
>
> 4. An expression or statement having an 'err' would impose a 
> try-block around the expression it is attached to, so the right thing 
> still happens when errors are thrown by default.  And 'err' is a 
> conscious effort to deal.
>
> 5. Autovivification in larger programs should not happen by default, 
> unless you have something like 'use autovivify;'.  But with 
> one-liners it would work by default.
>
> 6. Attempts to use undef where a defined value is expected, such as 
> wherever they currently generate warnings, should be upgraded to a 
> stricture and fail by default in larger programs.  But like with 
> other strictures, this would be turned off by default in one-liners. 
> If the DWIM behaviour is wanted in larger programs, one can say 'no 
> strict undefs;' or such.

I think we need to be very careful not to impose too many good practice
measures on the developer.  All of the situations you describe (except
perhaps autovivification) can potentially be picked up by the compiler,
and warnings generated.

> There may be remaining holes in my suggestions, but hopefully I dealt 
> with the worst ones from the preceeding first draft.

FWIW, I didn't read the first thread.

Sam.



Re: Obsoleting "require 'Some/Module.pm'"

2005-12-19 Thread Sam Vilain
On Mon, 2005-12-19 at 14:58 +0200, Gaal Yahas wrote:
> Can we make this work?
> 
>  my $mod = "Some::Module";
>  require $mod;

What about casting it to a package;

  require ::{$mod};

(not sure if the syntax is quite right)

Sam.



Re: Another dotty idea

2006-04-10 Thread Sam Vilain
Damian Conway wrote:

>I'm not enamoured of the .# I must confess. Nor of the #. either. I wonder 
>whether we need the dot at all. Or, indeed, the full power of arbitrary 
>delimiters after the octothorpe.
>  
>

Agreed.

>What if we restricted the delimiters to the five types of balanced brackets? 
>And then simply said that, when any comment specifier (i.e. any octothorpe) is 
>followed immediately by an opening bracket, the comment extends to the 
>corresponding closing bracket?
>
>Then you could have:
>
>   #[ This is a comment ]
>   #( This is a comment )
>   #{ This is a comment }
>   #< This is a comment >
>   #« This is a comment »
>  
>

This does mean that if you comment out blocks with s/^/#/, you mess up on:

#sub foo
#{
#  if foo { }
#}


>That would also mean that # is *always* the comment introducer
>(and the *only* comment introducer).
>  
>

I agree with this goal.

I propose this form: #*   *#

As a leading * on a line is unusual, and it also has visual similarity
to multi-line comments in C.

>As for gappy dotting, that would become:
>
>   $x#[  ].foo()
>  or:
>
> $x.#<  >foo()
>  
>

For comparison:

$x#*  *#.foo()
  or:

$x.#*  *#foo()





Re: Another dotty idea

2006-04-10 Thread Sam Vilain
Larry Wall wrote:

>On Tue, Apr 11, 2006 at 12:26:13PM +1200, Sam Vilain wrote:
>: This does mean that if you comment out blocks with s/^/#/, you mess up on:
>: 
>: #sub foo
>: #{
>: #  if foo { }
>: #}
>
>Well, actually, that still works.  
>  
>

Oh, true :-)

But this fragment dies:

 #sub foo
 #{
 #  bar { } unless baz
 #}


Unless you consider the idea of balancing the {}'s inside the comment,
which I think would be just plain nasty.

The #* .. *# form actually has a natural follow-on I didn't think of before:

#[ This is a comment ]#
#( This is a comment )#
#{ This is a comment }#
#< This is a comment >#
#« This is a comment »#

While technically the same thing applies to code that uses these delimited, it 
means that the block I gave is now a parsefail.  #-comments directly following 
closing braces are probably sufficiently uncommon for this not to be such a 
problem.

>To be certain though, you could always
>use s/^/##/ or s/^/# /.  
>  
>

I guess that works, but it breaks convention of # somewhat.

>Even better is:
>
>=begin UNUSED
>sub foo
>{
>  if foo { }
>}
>=end UNUSED
>
>And I don't really care if that's not what people are used to.
>The whole point of Perl 6 is to change How Things Work.
>  
>

Sure, but there is still the principle of least surprise to worry about.

Sam.



Re: Another dotty idea

2006-04-10 Thread Sam Vilain
Larry Wall wrote:

>: But this fragment dies:
>: 
>:  #sub foo
>:  #{
>:  #  bar { } unless baz
>:  #}
>I don't see how that's different at all from the first example.
>  
>

“#sub foo” is parsed as a comment token
“#{
# bar { }” is the next comment token

then we get “unless baz”

Unless you are balancing {}'s inside the # blocks, like q{ } does.

Sam.


Re: using the newer collection types

2006-05-04 Thread Sam Vilain
Darren Duncan wrote:

>Speaking a little more technically, a Relation has 2 main components, 
>its heading and its body.  The heading is a set of 0..N keys (called 
>"attributes" in relation-land), and the body is a set of 0..N 
>Mappings (called "tuples" in relation-land), where they set of keys 
>of each Mapping is identical to the Relation's heading.  Its very 
>likely that a language-embedded Relation implementation would 
>actually not repeat the keys for each member Mapping, but we can 
>conceptualize as if they were present for simplicity.
>  
>

I don't think this terminology or these restrictions are particularly
useful.

I do think that a Pair should be a sub-type of a more general "Tuple"
type, with the 'where' clause being { .items == 2 } or something like that.

I think that the most flexible arrangement is to define;

- a Collection as a Bag of Tuples
- a Relation as a Collection where the tuples have a shape and no
duplicate tuples are allowed (but Relation does not need to be a core type)

Then, Mappings, Sequences, etc, become sub-types of one of the above two
types. For instance, a sequence is a Collection of (Int, Any) where the
first Int is unique across the collection. Similarly a Mapping is a
Collection of (Any, Any) where Unique(0).

something like

role Tuple { has @.items };
role Collection { has Tuple @.tuples };
subset Pair of Tuple where { .items.items == 2 };
subset Bag of Collection where { ! .tuples.grep:{.items > 1 } }
subset Set of Bag where {
all( .tuples.map:{ .items } ) == one( .tuples.map:{ .items } )
}
subset Mapping of Collection where { ! .tuples.grep:{ .items != 2 } }
subset Array of Mapping where { .tuples.grep:{ .items[0].isa(Int) } }
subset Hash of Mapping where { .tuples.grep:{ .items[0].does(Str) } }

The above should probably all be written in terms of parametric roles
(see S12), but for now the above run-time checking versions should
hopefully express the relationships between the core collection-like
types as I see them.

That sounds like it might bite, but you wouldn't normally access an
Array as a Collection of (Int, Any), you'd access it as an Array, so you
get the nice .post_circumfix:<[ ]> method that makes array access easy.
You don't care that it has this higher order type as a parent class, and
you certainly wouldn't care for the 'bare' Collection interface (as for
one, you don't want to have to deal with the Integer keys). And it is
probably all backed by native methods.

I'm prototyping much of this using Moose in Perl 5, however Hubris is
delaying its release :-)

>Moreover, the Relation type has these 
>operators that the Set type doesn't have: rename(), project(), 
>restrict(), extend(), join(), divide(), summarize(), group(), 
>ungroup(), wrap(), unwrap(), matching(), etc.
>

Is there a reference for the meaning of these methods?

>1.  Are Sets or Junctions allowed to contain undefined elements?  Can 
>undef be a key of a Mapping or Hash?
>  
>

undef.isa(Object), so you should be able to use it as you would any
other object. I would definitely not think of it as the absence of a
value in this context.

>2.  What actually is the practical distinction between a Set and a 
>Junction?  Why would someone use one over the other?  I recognize 
>that the use of Junctions is supposed to make parallelism easier, as 
>iterating through one is known to be order independent.  But, 
>conceptually a Set and a Relation are exactly the same;  you could 
>process their members in any order and/or in parallel as well.  So is 
>the use of a Junction effectively like a compiler flag to make 
>certain kinds of Set ops faster at the expense of others?
>  
>

Well one side effect at the moment is that Junctions are immutable,
whilst Sets are mutable. This is perhaps a deficiency in my original
Set.pm design; all of the mutating functions should be in a seperate
role, really (or just not be mutators).

>6.  Can I declare with named Set (or Junction) and Mapping typed 
>variables and/or parameters that their members are restricted to 
>particular types, such as Str, as I can with Arrays and Hashes, so 
>that Perl itself will catch violations?  Eg, can I say as a parameter 
>"Set of Str :$heading?" or "Set of Mapping(Str) of Any :$body?" so 
>Perl will check that arguments are suchwise correct?
>  
>

These are variously called "Generics" (ada I think, Java 1.5+),
"Parametric Types", "Higher Order Types" (Pierce et al), "Generic
Algebraic Data Types" (Haskell)

In Perl 6 they are parametric roles (as in S12 mentioned above)

>7.  Can we add some operators to Mapping that are like the Relation 
>ones, so that implementing a Relation over Mappings is easier (or, 
>see the end of #8)?  Eg, these would be useful: rename(), project(), 
>extend(), join().  In particular, implementing join() into Mapping 
>would help save CPU cycles:
>  
>

Again, a reference to a prototype of the behaviour would be useful.

Sam.


Re: using the newer collection types

2006-05-05 Thread Sam Vilain
Darren Duncan wrote:

>>>Is there a reference for the meaning of these methods?
>>>  
>>>
>>There are many written references to these methods; just type 
>>"relational algebra" into Google.
>>
>>
>
>I will add that the first hit on such a search, the Wikipedia page on 
>relational algebra ( http://en.wikipedia.org/wiki/Relational_algebra 
>), is a perfectly good primer on what relational algebra is and what 
>its importance is.
>  
>

Thanks for the pointer.

>While this may not actually change anything, I should point out that 
>every collection type can also be expressed in terms of a Relation 
>definition and/or they can all be implemented over a Relation (whose 
>members are actually always unique).  For example:
>
>1. A Set of Any is a Relation with one Any attribute.
>2. A Bag of N Any attributes is a Relation of N+1 attributes, where 
>the extra attribute is an Int (constrained >= 1) that counts 
>occurrances of the distinct other attributes.
>3. A Mapping can be a Relation of 2 Any attributes.
>4. A Hash is a Relation of 2 attributes, Str (key) and Any (value), 
>where the key has a unique constraint.
>5. A Seq is a Relation of 2 attributes, typed Int (>= 0) and Any, 
>where the first shows their ordinal position and the second is the 
>actual value; the first has a unique constraint.
>6. An Array is the same, assuming it is a sparse; if it is not 
>sparse, there is an additional constraint that the greatest Int value 
>is the same / one less than the count of Relation members.
>  
>

I don't know if anyone will care, but you can't emulate the raw
"Collection" type with this fixed Relation type. That is, a collection
of tuples, each of which may be of differing length and type.

This is what leads me to think that Collection is the more generic role.
I'm not saying Relations are not useful, perhaps they are more useful
than Collections in the practical case, but they are a sub-type.

Also, I don't agree with the notion of a "header" of each relation. It
has a type for each tuple item, sure, but "header" just sounds like the
sort of thing you want in a ResultSet, not a Relation.

Sam.


Re: using the newer collection types

2006-05-07 Thread Sam Vilain
Darren Duncan wrote:

>>Also, I don't agree with the notion of a "header" of each relation. It
>>has a type for each tuple item, sure, but "header" just sounds like the
>>sort of thing you want in a ResultSet, not a Relation.
>>Sam.
>>
>>
>A relation's heading is essentially the definition of the relation's 
>structure, and is not redundant if the relation has no tuples in it, 
>which is valid.
>  
>

The Relation has a type, which is a Relation of Tuples of something. The
"Header" you refer to is the higher order part of the Tuple, the
"something".

Sam.


Re: ACID transactions for in-memory data structures

2006-05-17 Thread Sam Vilain
Rob Kinyon wrote:

>On 5/15/06, Audrey Tang <[EMAIL PROTECTED]> wrote:
>  
>
>>Rob Kinyon wrote:
>>
>>
>>>I'm pretty sure it wouldn't be very feasible to do this natively in
>>>P5. But, would it be possible to do it natively in P6? As in,
>>>supported within the interpreter vs. through some sort of overloading.
>>>  
>>>
>>Look at "is atomic" in S17draft, and Software Transaction Memory in general?
>>
>>
>
>Would there be a way for me to say "Yes, I understand that Perl may
>not generically understand how to revert this outside resource, such
>as a database, but I do." and do a catch-type block for the revert?
>  
>

There was discussion about this on one of the dbi2 lists at some point. 
I think a minimal API was even fleshed out - but it probably died there
and would love someone to pick it up.

Sam.


Re: packages vs. classes

2006-05-22 Thread Sam Vilain
Larry Wall wrote:

>'Course, I left out everything about prototype objects there...
>
>The name Foo also (in context) represents an uninitialized object of
>the class in question.  Any object, initialized or not, can get at
>its type handlers by saying
>
>Foo.meta
>$foo.meta
>
>and, in fact, the Foo.^bar syntax is just short for Foo.meta.bar.
>  
>

Perhaps saying it is like:

Foo.meta.get_attribute("bar")

Would be safer. Don't want to stomp on the meta-objects.

>[...]
>of the actual magic being defined elsewhere.  It would be possible
>to access classes et al. only via the mechanisms supplied by the
>metaobject protocols, but that would be kind of like the bad old
>[...]
>  
>

Right, but we should really ship with at least a set of Meta Object
Protocol Roles, that covers the core requirements that we will need for
expressing the core types in terms of themselves;

- classes and roles
- attributes and methods
- subsets (ie constraints/subtypes)
- generics (including, by induction, nested generics)

I *think*, at this point, that's all that are necessary. They are
actually quite a useful set for the concerns I raised earlier about
automatically inferring relational information from the metamodel (if
only I knew these terms back then... ;))
http://groups.google.com/groups?threadm=200303042358.56560.sam%40vilain.net

People can instantiate the roles that cover all that to an actual
metaclass in whatever way they like (eg,
Moose::Meta::Class->isa(Class::MOP::Class)), but not having to detect
the type and then figure out how to talk to it for at least the core of
the object system would be good.

People can diverge completely with completely incompatible metaclasses
that don't .do those roles, the only side effect of which being that
people who write code for the standard Perl 6 metamodel will be
incompatible, and maybe some ways of setting up the class won't work
without another layer of trickery. I *think* that's what you're getting
at. Of course, it shouldn't be prohibited just because it smells.

On different note, there should be nice, per-class ways to make type
constraints not simply code blocks - otherwise too much reverse
engineering will be required to do the final stage of compiling typesafe
code, where you close the classes and discard all the runtime type checks.

An easy example of this is generics. With "where", this is what you
write (ignore the syntax errors for now):

class "Array of Str" is Array where { $_.isa(Str) for @$_ }

But that sucks, because that information about the type of the container
is buried deep within the code reference, is slow, and we can't build
our methods with the right signatures. So, we write;

role Array[::T] { ... }
class "Array of Str" does Array[Str];

Great. Now that information is available to Array in a structured manner
and the signatures can be built correspondingly. But to represent the
core types like Mapping or Set, we also need, for instance, the "unique"
constraint to be represented as an object, not a code block:

For instance,

role Mapping[::T1, ::T2] does Coll[::T1, ::T2] where Unique(0);

The "where Unique(0)" is the important bit. What is "Unique", and who
uses it? In my prototypes, I've been considering it being the job of the
composing class or role to handle that, as a meta-object method call.

So, the above might call Coll.meta.Unique(0) (look, I'm stomping all
over the meta-object now) during the composition of the "Mapping" role,
and it uses this to affect the methods that it builds until you get
something that behaves not entirely quite unlike a Mapping.

However feel free to continue to handwave for now. Personally I'd like
to see this synoptic before the Perl 6.0 release, to avoid the mistakes
of other (*cough* C# *cough* Java 1.5 *cough*) languages that slipped on
getting the generics in their libraries, to their ultimate detriment.

Sam.


Re: hyp-op examples of a Bag type in S03

2006-05-22 Thread Sam Vilain
Darren Duncan wrote:

> $bag1 >>-<< 1; # Bag(2,7,[1,Seq(8,2)],7)
> $bag2 >>-<< (1,1,1,1); # probably the same
> $bag3 >>-<< (1,1,2,1); # ?
>  
>

Bag's won't .does(Array) or .does(Coll[Seq,...]), so that hyperoperator
won't work - if anything it would try to add the (1,1,1,1) list to all
of the elements of the bag. You'd need to put the bag in something that
does imply ordering first.

This applies to any unordered collection, bags or sets.

Sam.


Re: [svn:perl6-synopsis] r9307 - doc/trunk/design/syn

2006-05-25 Thread Sam Vilain
[EMAIL PROTECTED] wrote:

>+In either case this sets the C property of the container to C.
>+Subroutines have a variant of the C property, C, that
>+sets the C property instead.  The C property specifies
>+a constraint to be checked upon calling C that, unlike the C
>+property, is not advertized as the type of the routine:
>

It doesn't have to be run-time; it could also merely alter the signature
of the (implied or explicit) return() function within that sub.

Sam.


Re: Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Sam Vilain
Jonathan Lang wrote:

>How does an atomic block differ from one in which all variables are
>implicitly hypotheticalized?  I'm thinking that a "retry" exit
>statement may be redundant; instead, why not just go with the existing
>mechanisms for successful vs. failed block termination, with the minor
>modification that when an atomic block fails, the state rolls back?
>  
>

State rolling back automatically is the key feature of STM.

However, it can only cover pure perl state; any time that you enter a
function that performs I/O of any kind, then you are forcing bad things
to happen.

With Haskell this is sorted out by making the default "pure", and
everything else must be in a Monad.  However we're not into bondage here
so "is pure" is not default.  Instead we just die and rollback just
before I/O is attempted.  In principle, the compiler could automatically
attach "pure" traits to all functions and methods that it can prove will
never perform I/O and warn about this at compile time.

It might be possible for clever classes to circumvent this and carefully
call special unsafeIO() methods, and be passed messages about the STM
and hope that they do the right thing.  I don't know that anyone's
explored this area in depth in Perl 6 space.

>Also, what can "retry_with" do that testing the atomic block for
>failure can't?
>

I think the answer lies in the "checkpointing" references in that
document.  I don't know whether that's akin to a SQL savepoint (ie, a
point mid-transaction that can be rolled back to, without committing the
entire transaction) or more like a continuation that when resumed can
see the atomic changes, and when exiting finally applies them (or rolls
back).  Perhaps someone else will have more of a clue.

Sam.


Re: Concurrency: hypothetical variables and atomic blocks

2006-05-31 Thread Sam Vilain
Daniel Hulme wrote:

>>How does an atomic block differ from one in which all variables are
>>implicitly hypotheticalized?
>>
>>
>I assume that the atomicness being controlled by some kind of lock on
>entry, it also applies to I/O and other side-effecty things that you
>can't undo.
>

The lock on entry approach will only be for non-threaded interpreters
that don't know how to do real STM.

Sam.


Re: Perl5 -> Perl 6 Translations Design Document

2006-06-05 Thread Sam Vilain
Sage La Torra wrote:

>Hello all,
>
>I'm the student picking up on the translation work lwall started. Since the
>perl 5 parser is more or less complete, I've headed straight to the
>translation work. I'm going to be taking on the translations a few at a
>time, starting with the easiest translations and moving to the more complex.
>I've got a design document detailing the first few translations I'll be
>handling, and I'd greatly appreciate feedback and advice. Larry already took
>a good crack at it, catching a few things I had stupidly thought were
>simpler then they are, and now it's ready for general review.
>
>The current version can be found at
>http://infohost.nmt.edu/~slatorra/conversionstageone.txt
>
>Any advice/comments/criticism on the document and even ideas on
>implementation would be greatly appreciated.
>  
>

Looks like a reasonable starting point.

I assume that the "AST" will include comment nodes etc?

Sam.


Re: easier duck typing in .can

2006-06-17 Thread Sam Vilain

Yuval Kogman wrote:

Since CANDO is a multimethod, IMHO this can be safely extended to
allow:

$object.can(Class);
$object.can(Role);

to better support duck typing.
  


Why would you not use .does or .isa there?  Are you wanting this to go 
through all of the Class/Role's methods and check that the $object.can() 
them?


I think that perhaps .can($Method) (where $Method.isa(Meta::Method)) 
would be acceptable, then .can(Role) can either be defined to be 
.can(all(Role.get_methods)), or we just leave the user to use that 
snippet - after all, such extreme duck typing is expensive and shouldn't 
be  huffmanised overly IMHO.  We want people to use the Role objects 
unless they have a really good reason, and besides you can always just 
wrap things up in a Facade if you have to.


Sam.



Re: lvalue functions and lvalue parameters

2006-06-20 Thread Sam Vilain
Jonathan Scott Duff wrote:
>> sub cond(Bool $c, $a, $b) is rw {
>>   if $c return $a else return $b;
>> }
>>
>> Will this fail because $a and $b are not rw? If so, will it fail at run-
>> or compile-time? What about this:
>> 
> That looks like it should be a compile-time failure to me.
>   

Depends on the interpreter of course, but ideally, yes, compile time.

>> sub cond(Bool $c, $a is copy, $b is copy) is rw {
>>   if $c return $a else return $b;
>> }
>>
>> Is it allowed, and if so is the behaviour to return a writeable copy of
>> $a or $b? I imagine that in any case
>> 
> I'd expect a compile-time failure here too, or at the very least a
> warning.  Besides, returning a local copy each time hardly seems
> useful, except perhaps as a way to leak memory.
>   

It doesn't have to be a real copy, that's up to the implementation to
apply whatever COW mechanism it likes. The type of $a and $b in this
case is compatible with the return type of the function, so it should be
fine.

This example is a bit useless - cond($x, $a, $b) = $foo won't store the
result anywhere. So this could be a warning along the lines of "useless
use of variable in void context" (but more tailored to this condition)

>> sub cond(Bool $c, $a is rw, $b is rw) is rw {
>>   if $c return $a else return $b;
>> }
>>
>> will do what I want. 
>> 
> That is what I would expect too.
>   

Right.

>> my Int $a is constant = 0;
>> my Int $b is constant = 0;
>> (cond(True, $a,$b))++;
>> 
>
> We have a "constant" declarator now, so that would be 
>
> constant Int $a = 0;
> constant Int $b = 0;
> (cond(True, $a,$b))++;
>
> and that should fail at compile time because the compiler knows that
> $a and $b are constant and can't be rw.
>   


Indeed it should, with the same disclaimer as above re: compile/runtime

Sam.


Re: features of and declaring Mapping|Set|Hash values|variables

2006-06-29 Thread Sam Vilain
Darren Duncan wrote:
> 1. Looking at the language in Synopsis 6 for data types, I see:
>
>  Set Unordered Seqs that allow no duplicates
>  JunctionSets with additional behaviours
>  PairSeq of two elements that serves as an one-element Mapping
>  Mapping Pairs with no duplicate keys
>
> I would like to know if Mapping.does(Set) and whether I could use the 
> full range of Set operators on them, as I would like to do?
>
> My impression is that it be reasonable to define a generic Mapping as 
> being a Set whose elements are all constrained to be Pairs, and 
> further that all keys of those pairs are distinct; eg:
>
>subset Mapping of Set where {
>  all(.members).does(Pair) and +all(.members.map:{.key}) == +all(.members)
>};
>   

Hmm. I still think a more generic Collection makes this more correct.

subset Set of Collection where {
all(.members) =:= one(.members);
}

subset Mapping of Collection where {
all(.members).does(Pair) and
all(.members).key =:= one(.members).key;
}

ie, being a Set is introducing a constraint, which is then duplicated in
the Mapping type. Now, you could argue that the Set constraint is
"shadowed" by the Mapping constraint and the constraints analysis system
could prove it does not need to be applied, but that's quite a high
level thing to expect the compiler to do at this point, I think.

However the above definitions, in my opinion, miss the potential of
parametric roles.

> If this is true, then I suggest rewording the above line in Synopsis 
> 6 to better clarify the situation, like this:
>
>  Mapping Set of Pairs that allow no duplicate Pair keys
>
> It would be very useful to employ Set operations like subset() or 
> union() or difference() etc on Mappings, that return Mappings.  
>
> 2. Similarly, I would like to know if Hash.does(Mapping) and so that 
> we can therefore use all the Set and Mapping operators on Hashes, but 
> that their output is Hashes.  Likewise very useful.
>   
How about;

Mapping Collection of Pairs that allow no duplicate Pair keys.

If "Collection" is parametric it must be a role, which means that we
can't directly subset it; we use role composition instead (I'm assuming
that we can use where{} during role composition).

role Set of Collection[Item] where { all(.members) =:= one(.members) };

# one of these
role Mapping of Collection[Pair] where {
all(.members).key =:= one(.members).key
};

# what is a pair, anyway?
role Pair of Seq[Item,Item] {
method key of Item { &.item(0) }
method value of Item { &.item(1) }
};

role HEK of Seq[Str, Item] does Pair;

role Hash of Collection[HEK] does Mapping;

role ArrayItem of Seq[Int, Item] {
method index of Int { &.item(0) }
method value of Item { &.item(1) }
};

role Array of Collection[ArrayItem] where {
all(.members).index == one(.members).index;
} {
method post_circumfix:<[ ]>(Int $index) of Item {
my $seq = first { .index == $index } &.members;
$seq ?? $seq.value :: undef;
}
}

There are some problems with the above, notably "Pair" could be
parametric, and the Array post_circumfix method should be an lvalue return.

I'm terribly sorry I haven't dedicated more time to developing this into
a working prototype module for Perl 5. RSN I hope.

> 3. I missed the syntax for declaring anonymous Set or Mapping in the 
> Synopsis.  Has it been defined yet?
>
> Something that is distinct from:
>
>[1,2] # Array
>(1,2) # Seq
>{1=>2,3=>4} # Hash
>(1=>2) # Pair in positional context
>1=>2 # Pair in named context
>all(1,2,3) # Junction
>
> Eg, do we need to use keywords:
>
>set(1,2,3)
>mapping(1=>2,3=>4)
>
> Or can this be accomplished without such keywords?
>
> I am assuming we don't have to invoke some new() because these are 
> built-in basic types.
>   

I don't see a problem with .new() for these types, which some might
consider arcane.

set() doesn't work for the Perl 5 prototypes, too many modules want to
use $object->set().

Users who want a shorthand can use a module that lets them write ⟦ ⟧ etc
(say).

> 4. Since they are already known to be unique, is it possible to get 
> an actual Set returned when invoking something akin to .keys or 
> .pairs or a Mapping or Hash?  Or do we need to always construct such 
> ourself by wrapping the call with a set() or all(), in order to use 
> set operations on them?  Would the latter case be inefficient or 
> verbose?
>   

Interesting idea. I guess that there are many places where a list or
array type is specified where it should be a set.

> 5. I'm wondering about syntax for using Sets like Junctions.  Eg, if 
> I want to see if one set is a proper subset of another, can I say 
> this:
>
>all($s1) === any($s2)
>
> Or do I have to rewrap their members into explicit Junctions first like this:
>
>all($s1.members) === any($s2.members)
>
> I am ignoring for the moment that Set probably declares named 
> operators that let me do this:
>
>$s2.subset($s1)
>
> I don't want to have

Re: binding operators and related introspection

2006-07-17 Thread Sam Vilain
Darren Duncan wrote:
> But I would also like to have an easy way to change all bindings to 
> the same variable at once to point to the same new variable. 
> [...]
>my $x = 'foo';
>my $y = 'bar';
>my $z := $x;# $x and $z point to same 'foo', $y to a 'bar'
>$z.rebind_all_aliases_to( $y ); # $x and $y and $z all point to 'bar'
>   

Maybe we need ruby's Object.all or whatever it is. Then you can write
something like

Object.all.grep:{ $_ =:= $z }.map{ $_ := $y };

Sam.




Re: META vs meta

2006-09-12 Thread Sam Vilain
Larry Wall wrote:
> : There is currently a mismatch between S12 and Pugs.  The former specifies 
> $obj.META, the latter has implemented $obj.meta.
>
> .META is more correct at the moment.
>   

Does making it all upper caps really help? It's still a pollution of the
method space, any way that you look at it...

What about this form:

# $o.?meta
# $o.?type
# $o.?var
# $o.?id

> Only that I'm thinking of renaming all the meta-ish methods to use
> interrogative pronouns:
>
> .META ->  .HOW
> .SKID ->  .WHO
> .PKG  ->  .WHAT
> .VAR  ->  .WHERE
>   

Oo-er. Well, you're the linguist ;)

Sam.


Re: Capture sigil

2006-09-21 Thread Sam Vilain
Larry Wall wrote:
> Okay, I think this is worth bringing up to the top level.
>
> Fact: Captures seem to be turning into a first-class data structure
> that can represent:
>
> argument lists
> match results
> XML nodes
> anything that requires all of $, @, and % bits.
>   

Also;

  role type parameters

Sam.


Nitpick my Perl6 - parametric roles

2006-09-25 Thread Sam Vilain
Anyone care to pick holes in this little expression of some Perl 6 core
types as collections?  I mean, other than missing methods ;)

  role Collection[\$types] {
   has Seq[$types] @.members;
  }
 
  role Set[::T = Item] does Collection[T] where {
  all(.members) =:= one(.members);
  };
 
  role Pair[::K = Item, ::V = Item] does Seq[K,V] {
  method key of K { .[0] }
  method value of V { .[1] }
  };
 
  role Mapping[::K = Item, ::V = Item] does Collection[Pair[K,V]] {
  all(.members).does(Pair) and
  all(.members).key =:= one(.members).key;
  }
 
  role Hash[Str ::K, ::V = Item] does Mapping[K, V]
  where { all(.members).key == one(.members).key }
  {
  method post_circumfix:<{ }> (K $key) of V|Undefined {
  my $seq = first { .key == $key } &.members;
  $seq ?? $seq.value :: undef;
  }
  }
 
  role ArrayItem[::V = Item] does Seq[Int, V] {
  method index of Int { .[0] }
  method value of Item { .[1] }
  };
 
  role Array of Collection[ArrayItem]
  where { all(.members).index == one(.members).index }
  {
  method post_circumfix:<[ ]> (Int $index) of Item {
  my $seq = first { .index == $index } &.members;
  $seq ?? $seq.value :: undef;
  }
  }

I'll take the feedback I get, and try to make a set of Perl 6 classes in
the pugs project that look and feel just like regular Perl 6 hash/arrays
but are expressed in more elementary particles.

Cheers,
Sam.


Re: Nitpick my Perl6 - parametric roles

2006-09-25 Thread Sam Vilain
TSa wrote:
>>   role Collection[\$types] {
>>has Seq[$types] @.members;
>>   }
> This is a little wrapper that ensures that collections have got
> a @.members sequence of arbitrary type. This immediately raises
> the question how Seq is defined.
> [...and later...]
> Are you sure that the underlying Seq type handles the one and
> two parameter forms you've used so far?

Ah, yes, a notable omission.  I understood a Seq as a list with
individual types for each element, which are applied positionally.  The
superclass for things like Pair.

Here's a quick mock-up of what I mean:

   role Seq[ \$types ] {
   submethod COMPOSE {  # a la BUILD for classes
   loop( my $i = 0; $i < $types.elems; $i++ ) {
   # assumption: "self" here is the class
   # we're composing to, and "has" is a class
   # method that works a little like Moose
   self.has( $i++ => (isa => $types.[$i]) );
   }
   }
   my subset MySeqIndex of Int
   where { 0 <= $_ < $types.elems };

   method post_circimfix:<[ ]>( $element: MySeqIndex ) {
   $?SELF.$element;
   }
   }

Seq is certainly interesting for various reasons.  One is that it is a
parametric role that takes an arbitrary set of parameters.  In fact,
it's possible that the type arguments are something more complicated
than a list (making for some very "interesting" Seq types); the above
represents a capture, but the above code treats it was a simple list.

>>   role Set[::T = Item] does Collection[T] where {
>>   all(.members) =:= one(.members);
>>   };
> 
> Nice usage of junctions! But how is the assertion of
> uniqueness transported into methods that handle adding
> of new values?

I haven't defined any mutable state yet; it's still "pure".

I'd expect mutability to be a different role, and a set of primitives
that work on this level by returning a new set with the changes made.
In fact the mutable Set could re-use those primitives, by just having a
Set as a member (that 'handles' the Set role methods), and automatically
changing that member each time a change is made, to point to the new Set
with the new contents.

Which all sounds very inefficient and scary until you realise what
happens inside generative GC VMs that support STM.

>>   role Mapping[::K = Item, ::V = Item] does Collection[Pair[K,V]] {
>>   all(.members).does(Pair) and
>>   all(.members).key =:= one(.members).key;
>>   }
> 
> I guess this is a typo and you wanted a where clause. The first
> assertion of the members doing the Pair role should be guaranteed
> by using Pair as the type argument when instantiating the Collection
> role.

Well spotted; yes, that is superfluous.

>>   role Hash[Str ::K, ::V = Item] does Mapping[K, V]
> 
> Will the Str assertion not be too specific for non-string hashes?

Another assumption I make here is that there is a basic type "Hash",
which as its name suggests, is all about hashing strings, and that the
more general form is called "Mapping" where any object can be the
source, not just Str subtypes.

Thanks for your other nitpicks and comments - much appreciated!

Sam.


>>   where { all(.members).key == one(.members).key }
>>   {
>>   method post_circumfix:<{ }> (K $key) of V|Undefined {
> 
> Nice union type as return type. But isn't the type name Undef?
> 
>>   my $seq = first { .key == $key } &.members;
> 
> Wasn't that @.members?
> 
>>   $seq ?? $seq.value :: undef;
> 
> Ternary is spelled ?? !! now.
> 
> 
>>   }
>>   }
>>  
>>   role ArrayItem[::V = Item] does Seq[Int, V] {
>>   method index of Int { .[0] }
>>   method value of Item { .[1] }
>>   };
> 
> Here we see the two parameter version of Seq at work.
> 
> 
>>   role Array of Collection[ArrayItem]
>>   where { all(.members).index == one(.members).index }
>>   {
>>   method post_circumfix:<[ ]> (Int $index) of Item {
>>   my $seq = first { .index == $index } &.members;
> 
> Is this first there a grep-like function? Shouldn't it then
> read 'first { .index == $index }, @.members'?
> 
> 
>>   $seq ?? $seq.value :: undef;
>>   }
>>   }
>>
>> I'll take the feedback I get, and try to make a set of Perl 6 classes in
>> the pugs project that look and feel just like regular Perl 6 hash/arrays
>> but are expressed in more elementary particles.
> 
> This might be very useful in future debates about these types. But
> I think everything hinges on the basic Seq type.
> 
> 
> Regards, TSa.



Re: Mutability vs Laziness

2006-09-25 Thread Sam Vilain
Aaron Sherman wrote:
> Carried over form IRC to placeholder the conversation as I saw it:
> 
> We define the following in S06 as immutable types:
> 
> ListLazy Perl list (composed of Seq and Range parts)
> Seq Completely evaluated (hence immutable) sequence
> Range   Incrementally generated (hence lazy) sequence
> Set Unordered Seqs that allow no duplicates
> JunctionSets with additional behaviours
> PairSeq of two elements that serves as a one-element Mapping
> Mapping Pairs with no duplicate keys
> 
> It seems to me that there are three core attributes, each of which has
> two states:
> 
> Laziness: true, false
> Mutability: true, false
> Ordered: true, false

I don't think "Ordered" is an attribute of a collection other than in
the abstract, user-centric sense - it is a type parameter difference
(though also there are method differences etc).  Things that are not
ordered map from items to presence (or themselves, if you prefer).
Things that are ordered map from array indices to items.

> There are, thus, eight types of containers, but two (unordered, mutable,
> lazy/eager) don't really work very well, so let's say 6:

Mutable sets don't work?  I don't see why not.

> Ordered,   Immutable, Eager:  Seq
> Ordered,   Immutable, Lazy:   Range and/or Seq of Range?
> Ordered,   Mutable,   Eager:  ?
>  Ordered,   Mutable,   Lazy:   Array
> Unordered, Immutable, Eager:  Set
> Unordered, Immutable, Lazy:   x and/or Set of x?
> 
> In that last example, x is "an unordered range",

Sounds a bit like an iterator.

Sam.


Re: Nitpick my Perl6 - parametric roles

2006-09-26 Thread Sam Vilain
Miroslav Silovic wrote:
> TSa wrote:
>   
>>>   role Set[::T = Item] does Collection[T] where {
>>>   all(.members) =:= one(.members);
>>>   };
>>>   
>> Nice usage of junctions!
>>
>> 
>
> But buggy - one means *exactly* one. So for an array of more than 1 
> element, all(@array) never equals one(@array) - if they're all the same, 
> it's more than 1, otherwise it's 0.
>
>   

perl -MPerl6::Junction=one,all -le '@foo=qw(1 2 3 4); print "yes" if
(all(@foo) eq one(@foo))'
yes

Didn't test on pugs yet.

Sam.

> all(.members) =:= any(.members) would also not work, as it will try to 
> match each member with some other or same member of the array. It will 
> always return true, in other words, as each element of the array is 
> equal to itself.
>
> This leaves all(.members) =:= .members[0], possibly extra with 
> non-emptiness test.
>
> Miro
>
>
>   



Re: Nitpick my Perl6 - parametric roles

2006-09-26 Thread Sam Vilain
Darren Duncan wrote:
> Unless I'm mistaken, you may be going about this the wrong way.
>
> Within a system that already has an underlying 
> set-like type, the Junction in this case, a test 
> for uniqueness is (pardon any spelling):
>
>all(@items).elements.size === @items.size
>
> The all() will strip any duplicates, so if the 
> number of elements in all(@items) is the same as 
> @items, then @items has no duplicates.
>   

Perhaps, but then Junctions might not assume elements have equality or
identity operations defined.  To do that you need to require this (and
which identity operator would you like to use today?), and that would
also have the side effect of making creating a junction an O(N^2) operation.

I think that the S06 definition needs re-wording.  It's more like a Bag
than a Set AIUI.

Sam.


Re: Nitpick my Perl6 - parametric roles

2006-09-26 Thread Sam Vilain
TSa wrote:
> HaloO,
>
> Sam Vilain wrote:
>   
>> perl -MPerl6::Junction=one,all -le '@foo=qw(1 2 3 4); print "yes" if
>> (all(@foo) eq one(@foo))'
>> yes
>> 
>
> But does it fail for duplicates? I guess not because junctions
> eliminate duplicates and you end up testing unique values as
> above. E.g. all(1,1,2) == one(1,1,2) might actually give the
> same result as all(1,2) == one(1,2).
>   

Neither Pugs nor Perl6::Junction behaves like this.

pugs> for ([1,2,3], [1,1,2,3]) -> $x { my @x = @$x; my $all_unique = (
all(@x) == one(@x) ); print "{ $x.join(",") } became ", $all_unique; say
" (which is { $all_unique ?? "TRUE" !! "FALSE" })" }
1,2,3 became all(VJunc one(VBool True)) (which is TRUE)
1,1,2,3 became all(VJunc one(VBool False,VBool True),VJunc one()) (which
is FALSE)

Sam.


Re: Nitpick my Perl6 - parametric roles

2006-09-26 Thread Sam Vilain
Darren Duncan wrote:
>> Perhaps, but then Junctions might not assume elements have equality or
>> identity operations defined.
>> 
> As I recall, every type in Perl 6 has an equality and identity 
> operation defined because the Object superclass provides one.  If 
> nothing else, the type's equality and identity are the same as =:= 
> and .WHERE.
>   

Ok, seems reasonable.

>>  and that would
>> also have the side effect of making creating a junction an O(N^2) operation.
>> 
> Not if the type uses a hash-like index internally; then creating a 
> junction (or set) is more like O(N).
>   

Oh, yes, good point.

>> I think that the S06 definition needs re-wording.  It's more like a Bag
>> than a Set AIUI.
>> 
> I don't know what part you are reading, but the list of types that I 
> see says that a Junction is "Sets with additional behaviours".
>   

We're on the same page. It's just not the way that any of the prototypes
have behaved to date.

Sam.


Re: class interface of roles

2006-10-01 Thread Sam Vilain
TSa wrote:
> HaloO,
>
> is this subject not of interest? I just wanted to start a
> discussion about the class composition process and how a
> role designer can require the class to provide an equal
> method and then augment it to achieve the correct behavior.
> Contrast that with the need to do the same in every class
> that gets the equal method composed into if the role doesn't
> have a superclass interface as described in the article.
>   

This will be the same as requiring that a class implements a method,
except the method's name is infix:<==>(::T $self: T $other) or some such.

Sam.


Re: Junctions - feedback and desires

2005-03-10 Thread Sam Vilain
Rod Adams wrote:
I do not believe that is possible.
This is the "filtering" or "unification" behavior that people keep 
wanting junctions to have, which they do not.
Aww!  But what about all the great problems that could be expressed
with them?  I know of two languages that consider this to be a core
feature now (Prolog, Oz[1]).
A given junction always has all of the values it was made with. No more, 
no less. If you want something else, you have to make a new junction. 
Consider that it's been decided that :

   $j = 11|0;
   10 < $j < 1
Is true. $j retains the 0 even after the 0 failed a test.
I can't see how this can be possible with the possibility of
autothreading as described in [2].  Maybe the example you suggest is
true, if both comparisons happen "simultaneously", but what about this
one?
if ($j < 10) {
if ($j < 1) {
say "$j took on two values at once";
}
}
Let's say that the implementation chose to implement the first if() by
auto-threading.  The first thread where $j == 11 succeeds.  The second,
where $j == 1 fails.  In the second thread, $j == 11 fails.
It is by this assumption that the example in [3] was built.
But wait, isn't (10 < $j < 1) likely to produce the same opcode tree
as if($j<10){if($j<1){}} ?
> As for the "current" value, there is only a current value during
> threading.
Isn't the threading conceptual, and actual threading invoked only when
the optimiser has finished using available logic / set theory operations
to prevent absurd numbers of threads being made that exit immediately?
Sam.
References:
1. http://xrl.us/fehh (Link to www.mozart-oz.org)
   A representation of send+more=money in Oz
2. http://dev.perl.org/perl6/synopsis/S09.html
Some contexts, such as boolean contexts, have special rules for dealing
with junctions. In any scalar context not expecting a junction of values,
a junction produces automatic parallelization of the algorithm. In
particular, if a junction is used as an argument to any routine (operator,
closure, method, etc.), and the scalar parameter you are attempting to
bind the argument to is inconsistent with the Junction type, that
routine is "autothreaded", meaning the routine will be called
automatically as many times as necessary to process the individual scalar
elements of the junction in parallel.
3. An implementation of send+more=money using Perl 6 Junctions
   http://svn.openfoundry.org/pugs/examples/sendmoremoney.p6
   http://xrl.us/feis (revision at time of writing this message)


SEND + MORE = MONEY (works now in pugs with junctions!)

2005-03-10 Thread Sam Vilain
Rod Adams wrote:
And as one who recently proposed a way of getting Prolog like features 
in Perl (through Rules, not Junctions), I understand the appeal 
completely. Junctions are not the way to that goal. They are something 
different.
> Taking multiple values at once is what junctions are all about.
> People seem to forget the role the predicate plays in junction
> evaluation. You thread over the different values, gain a result, and
> then use the predicate to recombine the results into a single scalar.
> That assumption is in err, and the example does not generate the
> solutions desired
I've changed examples/sendmoremoney.p6 in the pugs distribution to use
junctions correctly to demonstrate that they *can* be used to solve these
sorts of problems, and that it is just a matter of semantics and writing
code correctly.
However, poor semantics can make the task of writing optimisers
unnecessarily difficult or impractical, as Bourne demonstrated.
in short, it seems people want this:
  my $a = any(1..9);
  my $b = any(1..9);
  my $c = any(0..9);
  if ( $a != $b && $b != $c && $a != $c &&
   ($a + $b == $a * 10 + $c) ) {
  print "$a + $b = $a$c";
  }
To mean this (forgive the duplication of collapse() here):
  sub collapse($x, $sub) { $sub.($x) }
  sub collapse($x, $y, $sub) { $sub.($x,$y) }
  my $a = any(1..9);
  my $b = any(1..9);
  my $c = any(0..9);
  collapse($a, $b, -> $a, $b {
  ($a != $b) &&
  collapse($c, -> $c {
  if ( ( $b != $c ) && ( $a != $c ) &&
   ($a + $b == $a * 10 + $c) ) {
  say "$a + $b = $a$c";
  }
  });
  });
(and YES THAT WORKS ).
However, the former keeps the optimisation out of the algorithm, so that
when someone comes along later with a nice grunty optimiser there is more
chance that it gets a go at the entire solution space rather than having
to fall back to exhaustive searching.
(which might have to find ways to prove associativity of &&, etc, to make
`real' optimisations).
I'm trying to see a way that these two ways of using junctions are
compatible.  As I see it, people want to stretch out the time that the
junction is "true", to something non-zero, without having to explicitly
create all those closures.
Getting the old behaviour would be easy, just set a variable in the `if'
clause:
  my $j1 = any(1..5);
  my $j2 = any(5..9);
  my $they_equal;
  if ($j1 == $j2) {
  # intersection of sets - $j1 and $j2 are any(5), any(5)
  $they_equal = 1;
  } else {
  # symmetric difference of sets - $j1 and $j2 are now
  #   any(1..5), any(5..9) (where $j1 != $j2 :))
  }
  if ($they_equal) {
  }
Now, the `where $j1 != $j2' bit there, which looks like it's on crack, is
a way of representing that instead of actually calling that second branch
24 times, it could be calling it with two junctions which are `entangled'
(or, if you prefer, `outer joined').  $j1 and $j2 appear almost untouched
- except any test that uses $j1 and $j2 together will not see the
combination of ($j1 == 5) and ($j2 == 5).
I mean, wouldn't it really be nice if you could write stuff like this:
  my @users is persistent("users.isam");
  my @accounts is persistent("accounts.isam");
  my $r_user = any(@user);
  my $r_account = any(@account);
  if ( $r_account.user == $r_user ) {
  say("That junction is:", $r_user);
  }
$r_user at that point represents only the users which have at least one
object in @accounts for which there exists an $r_account with a `user'
property that is that $r_user member[*].
The closure would then either be run once, with $r_user still a junction
(if the interpreter/`persistent' class was capable of doing so), or once
for every matching tuple of ($r_account, $r_user).  We're still talking in
terms of Set Theory, right?
One last thing - that comment about any(@foo) == one(@foo) not
checking for uniqueness in a list is right - the correct version
is:
  all(@foo) == one(@foo)
Sam.
Footnotes:
 * - any relational database `experts' who want to remind me of which
 normalisation form rules this breaks, please remember that RDBMSes
 and normalised forms approximate Set Theory, which this is trying to
 do as well, so I believe such discussion is irrelevant.



Re: [Fwd: Re: [RFC] A more extensible/flexible POD (ROUGH-DRAFT)]

2005-03-17 Thread Sam Vilain
Aaron Sherman wrote:
Sam "mugwump" Vilain refers to each of these syntaxes as /Pod dialects/.
He is working on more formally defining the common model or "AST" that
these dialects map to.
Why? Seriously, why on earth do you want to encourage the proliferation
of variant markup languages?! There aren't enough?
My effort here was to try to PREVENT the proliferation (e.g. by Kwid and
POD butting heads and ending up in a stalemate). The only problem is
that, presented with a compromise, the Kwid folks seem to be content to
ADD it to the list of variants rather than, in fact, compromise and
collapse the list.
I'll continue only as far as is needed to propose this in full as an
example parser / converter, and then I'm going to stop. My goal is not
to proliferate the number of markups further, and I'd MUCH rather see
Perl 6 rely on POD than fragment the SINGLE MOST IMPORTANT TASK in
creating code to share with the world: documentation.
Well, I don't think anyone wants to see as many POD dialects as there
are wiki text formats (BBCode, anyone?).  Maybe there will be something
very close to the original POD, but with a verbose way of making tables,
and an enhanced linking syntax.  But otherwise identical to the original
Perl 5 POD.
Note that POD dialects, and differing POD conventions already exist in
Perl 5 and are in common use.  They were designed in the original POD
with the =for tag.  At the moment, tools like `pod2html' have to be
heavily aware of the POD dialect, which I think is sub-optimal when it
comes to some of the really interesting things people have achieved
with POD.  Look at MarkOv's OODoc, or Test::Inline, for instance.
All I'm trying to do is giving these beasts a name, and defining a
mechanism by which they can be used by tools that only know how to deal
with "standard" documents - thus giving users the freedom to define a
local convention if one of them doesn't quite fit their needs.
Using a local Subversion repository, and Request Tracker, and want to
be able to put hyperlinks in POD to refer to these entities?  No
problem, just extend the dialect and add a link style.  Then select
from a dozen output tools or variants to see which one works for you.
Sam.


Re: [Fwd: Re: [RFC] A more extensible/flexible POD (ROUGH-DRAFT)]

2005-03-17 Thread Sam Vilain
Damian Conway wrote:
[No, I'm not back; I'm just passing by. But I feel that I need to 
comment on this whole issue]
Thanks!  This message has lots of useful information that I would have 
otherwise probably missed.

It seems that the basic premise of the POD document object model gels 
well with that early design document, so I look forward to being able to 
flesh out the details.

Using ^=\s to delimit a line starting with a = will interfere with the 
Kwid method of:

 = Heading
 foo
Which I was imagining would be converted to a DOM tree that when 
represented in the "Normative XML" would look like:

 
   Heading
   foo
 
That's sort of DocBook style, and in fact I was thinking that for the 
internal representation, DocBook node names could be used where there is 
no other better alternative.  Of course, non-documentation things like 
Test fragments or inclusions of external entities, like UML diagrams 
won't have a representation in DocBook :-).

The uses of a leading = in a paragraph are fairly uncommon.  For 
instance, when quoting POD you would simply indent it a bit to make it 
verbatim and there is no issue.

I see a middle ground; that is, `=` quoting is only is allowed if it 
directly follows the initial POD marker;

 =head1 Foo
 =
 = =head1
 = =
 = = =head1 That's just getting ridiculous
Which I see as represented by;
 
   Foo
   =head1
 =
 = =head1 That's just getting ridiculous
 
Which of course would lose the ='s.  But that's OK, because if you 
wanted verbatim you could have just indented the block.

If you wanted to lead a normal paragraph with it, you'd just use the 
normally implicit =para (equivalent to =pod):

 =para
 =
 = = This is what a Kwid =head1 looks like
As for going with =kwid to denote the starting of kwid, I have so far 
been pessimistically assuming that something like `=dialect kwid`, or 
`=use kwid` (as described in the design doc you attached) would be 
required.  However, we could allow `=unknown`, where `unknown` is an 
unknown keyword, to try to load Pod::Dialect::unknown, and hope like 
hell it provides the Role of Pod::Dialect.

While the `^=` escaping is “active”, the presence or absence of 
whitespace following the initial `=` will delimit breaks in paragraphs. 
 This has to be so, otherwise the previous example would have been:

 
   Foo
 =head1
 =
 = =head1 That's just getting ridiculous
 
 
Which is just plain silly.  This follows what people are used to with 
POD - blank lines must be empty, not just no non-whitespace characters 
(an increasingly vague concept these days).

So, the POD processing happens in 3 levels (note: the first isn't really 
mentioned in perlpodspec.kwid, which is a bug);

=list
- chunkification from the original source, into POD paragraphs, which 
may or may not include an initial `^=foo` marker.  At *this* level, the 
only escaping that happens is the `^=` escaping.

That's all that needs to happen while the code is being read, and for 
most code that is how the POD will remain, in memory, somewhere 
intermingled with the Parse Tree for the code, so that the code can 
still be spat back out by the P6 equivalent of `B::Deparse`

- parsing of these raw chunks into a real POD DOM.  Please, tired XML 
veterans, please don't get upset by the use of the term "DOM", I think 
the last thing anyone wants is to have studlyCaps functions like 
`getElementById` and `createTextNode`.  It is the tree concept itself 
which is important, and this pre-dates XML anyway.

Strictly speaking, this step actually converts POD paragraph chunk 
events into POD DOM events.  These can be used to build a real DOM, for 
instance if you need to do an XPath style query for a link (I was amazed 
that someone's actually gone and built Pod::XPath!), or they might 
simply be passed onto the next stage by an output processor with no 
intermediate tree being built.

So, at this point, dialects get hooks to perform custom mutation of POD 
paragraph events into DOM events, and the arbitrator of this process 
ensures that the output events are well "balanced" by spitting out 
closing tags where it has to.  They can store state in their parser 
object, but none of this state will be preserved past the parsing state.
However, the nodes that they "spit out" after this point may still not 
be "core" POD, such as for includes or out-of-band objects.  These hooks 
will be sufficient to allow them to hijack subsequent chunks that would 
otherwise be served to other dialects, ie, they can choose to 
"arbitrate" subsequent chunks.

I'm aiming to make it so that it is possible for dialects to be "round 
trip safe", by being able to go back from this DOM state to the original 
POD paragraph chunks.  This would require dialects to "play nice" of 
course, but is a potential option to help make things like smart text 
editors be able to automatically syntax highlight POD dialects :).

Linking will be in terms of this intermediate tree, so you won't be able 
to link to included portions of m

Re: identity tests and comparing two references

2005-03-31 Thread Sam Vilain
Darren Duncan wrote:
Now I seem to remember reading somewhere that '===' will do what I want, 
but I'm now having trouble finding any mention of it.
So, what is the operator for reference comparison?
As someone who wrote a tool that uses refaddr() and 0+ in Perl 5 to 
achieve the same thing, I agree with the need for such an operator.

I think that =:= compares *lexical* identity is fairly clearly spelled 
out in S03.  However, we need a way to compare *value* /identity/ (not 
equality or equivalence), without being subject to overloading etc.

Of course, actually comparing two `ref' or `Ref' objects for pointing
to the same place is achieved via `==' (or, if === is used, ${$ref1} === 
${$ref2} or the P6 equivalent :) )

Sam.


Re: Documentary annotations: $what doc

2005-04-01 Thread Sam Vilain
Luke Palmer wrote:
Supposing I had a "doc" trait, could I say:
   sub f2c (Num $temp doc)
   doc
   {...}
Or would I be forced to spell it  doc('stuff')  ?
Well, first you need an `is` somewhere in there.  And after that I think
you'll need to do it in doc('stuff') form.  If we did allow doc<>, then
this:
A word of warning...
Perldoc[*] will eventually support this sort of thing, for sure.  But it
will lead to the unfortunate side effect that your code needs to at
least compile without syntax errors, and without too many obscene
mistakes - so that these traits are accessible by the dialect that
interprets them into a Perldoc tree.
That's if you care about seeing the information presented nicely when
you use `perldoc Foo', of course.
Sam.
* - the project aiming to provide dialect-agnostic inline documentation
for Perl 5 and Perl 6.  The Perl 5 prototype is on CPAN... still in
early stages.


Re: :=: (OT)

2005-04-04 Thread Sam Vilain
Juerd wrote:
For some reason, I keep typing :=: instead of =:=. Do other people
experience similar typo-habits with new operators?
One of my other Perl 6 typo-habits is <<^H^Hargh!^H^H^H^H^H«, but that's
because I like how « and » look, but can't yet easily type them.
Juerd
«»«»«»«»«»«»«»«»«»«»«»«»«»!  :-þ
an excerpt from my xkb config...
key  {
symbols[Group1]= [   z,   Z ],
symbols[Group2]= [   guillemotleft,less ]
};
key  {
symbols[Group1]= [   x,   X ],
symbols[Group2]= [  guillemotright, greater ]
};
xkb
(keyboards that fail, leading to making it easier for me to enter «» and 
þ than )--

Sam.


Re: Whither "use English"?

2005-04-13 Thread Sam Vilain
Juerd wrote:
According to Wikipedia there are around 400 million native English speakers 
and 600 million people who have English as a second language. Should the 
remaining ~5.5 billion humans be exluded from writing perl code just so that 
we English speakers can understand all the code that is written?
Yes.
So, you gladly invite the curse of semantic fixation.
æäé
As we will know exactly what are symbols and what is code, it should
even be possible to automatically perform L10N on source code, without
breaking it.
So stop being empirical!
TIA,
Sam.


Macros [was: Whither "use English"?]

2005-04-14 Thread Sam Vilain
Larry Wall wrote:
(B> Well, only if you stick to a standard dialect.  As soon as you start
(B> defining your own macros, it gets a little trickier.
(B
(BInteresting, I hadn't considered that.
(B
(BHaving a quick browse through some of the discussions about macros, many
(Bof the macros I saw[*] looked something like they could be conceptualised
(Bas referring to the part of the AST where they were defined.
(B
(Bie, making the AST more of an Abstract Syntax Graph.  And macros like
(B'free' (ie, stack frame and scope-less) subs, with only the complication
(Bof variable binding.  The ability to have recursive macros would then
(Brelate to this graph-ness.
(B
(BWhat are the shortcomings of this view of macros, as 'smart' (symbol
(Bbinding) AST shortcuts?
(B
(BThe ability to know exactly what source corresponds to a given point on
(Bthe AST, as well as knowing straight after parse time (save for string
(Beval, of course) what each token in the source stream relates to is one
(Bthing that I'm aiming to have work with Perldoc.  I'm hoping this will
(Bassist I18N efforts and other uses like smart editors.
(B
(BBy smart editors, I'm talking about something that uses Perl/PPI as its
(Bgrammar parsing engine, and it highlights the code based on where each
(Btoken in the source stream ended up on the AST.  This would work
(Bcompletely with source that munges grammars (assuming the grammars are
(Bworking ;).  Then, use cases like performing L10N for display to non-
(BEnglish speakers would be 'easy'.  I can think of other side-benefits
(Bto such "regularity" of the language, such as allowing Programatica-
(Bstyle systems for visually identifying 'proof-carrying code' and
(B'testing certificates' (see http://xrl.us/programatica).
(B
(Bmacros that run at compile time, and insert strings back into the
(Bdocument source seem hackish and scary to these sorts of prospects.
(BBut then, one man's hackish and scary is another man's elegant
(Bsimplicity, I guess.
(B
(B* - in particular, messages like this:
(B- http://xrl.us/fr78
(B
(Bbut this one gives me a hint that there is more to the story... I
(Bdon't grok the intent of 'is parsed'
(B- http://xrl.us/fr8a

Re: Sun Fortress and Perl 6

2005-04-27 Thread Sam Vilain
Luke Palmer wrote:
`is pure` would be great to have! For possible auto-memoization of
likely-to-be-slow subs it can be useful, but it also makes great
documentation.
It's going in there whether Larry likes it or not[1].  There are so
incredibly many optimizations that you can do on pure functions, it's
not even funny.  Haha.  Er...
How about the one that goes further and also implies that the function
is strictly typed throughout;
  is ML
He'd love that, for sure!
:)
Sam.


Re: Threading in Parrot vs Perl

2005-04-28 Thread Sam Vilain
Rod Adams wrote:
I would be dismayed if autothreading used threads to accomplish it's 
goals. Simple iteration in a single interpreter should be more than 
sufficient.
For sure.  No point in doing 10_000 cycles to set up a scratch area
for a single boolean test that might take 10 cycles.
A software transaction (atomic { } block) behaves in many ways like
setting up a new interpreter thread and exiting at the end.  I expect
these will be more lightweight than a real thread... in some cases
able to be reduced to no-ops.
So, implementing autothreading using STM as the 'localizing' engine
is another possibility within a single process/thread.
Sam.


Re: S29: punt [pwned!]

2005-05-12 Thread Sam Vilain
Rod Adams wrote:
It looks like I'm going to have to punt on finishing S29.
On behalf of pugs committers, we will gladly adopt this task, which is in
the pugs repository already at docs/S29draft.pod, as well as having a set
of foundation classes that correspond to all these object methods in
docs/src/ (of course, most of the actual code is in src/Pugs/Prim.hs etc)
I'm finding myself in a perpetual state of either no time to work on it, 
or when there is time, having insufficient brain power left to properly 
assimilate everything that needs to be considered to do any of the 
functions justice. Looking ahead, I do not see this state changing for 
the better in the foreseeable future.
Drop the feeling of guilt for not having written enough and it will already
be better.  Thanks for what you have done, it is an outstanding achievement!
It's my hope that someone none(@Larry) can and will pick this effort up. 
I will give whatever assistance I can to anyone choosing to do so. Drop 
me a line.
If you could make sure your last revision corresponds to what is in the
pugs repository, that will be more than enough...
Sam.


Re: Quick question: '1.28' * '2.56'

2005-05-17 Thread Sam Vilain
Rob Kinyon wrote:
If that's the case, then if I change a variable that isa Str (that isa
Num), does it change what it inherits from?
Please don't use "inherits" when talking about these core types.  Classical
inheritance just doesn't work with the varied sets of numbers.  All those
stories you were told about Classical Inheritance being able to describe any
problem were naïve lies.  Roles-based inheritance (or Traits-based if you
like Smalltalk, or Haskell's Classes) is a superset of classical inheritance.
In fact it seems reasonable to me at this point in time that a Perl 6 Class
is a subtype of a Role.  The distinctions seem minor enough not to matter.
See also http://svn.openfoundry.org/pugs/docs/src/number-types.png
Sam.


Re: Quick question: '1.28' * '2.56'

2005-05-17 Thread Sam Vilain
Larry Wall wrote:
: pugs> '1.28' * '2.56'
: 3.2768
: What is (or should be) going on here here?
: [1] role NumRole {
:   method infix:<*> returns Num (NumRole $x, NumRole $y: ) { ... }
: }
: Str.does(NumRole);
: [3] multi sub prefix:<+> (Str $x) returns Num { ... }
: multi sub infix:<*> (Num $x, Num $y) returns Num { ... }
: multi sub infix:<*> (Any $x, Any $y) returns Num { +$x * +$y }
I tend to think of it most like [3], but it's possible that it's the
same as [1] if the role is supplying the coercion assumed in [3].
I like #3, because it doesn't have any nasty implications to the type
calculus.
I don't really have the theoretical or practical knowledge to really be
able to back this up, but I have a strong hunch that value-based type
shifting is the type system equivalent of $&.
Sam.


Re: Default precedence level of user defined infix ops

2005-05-18 Thread Sam Vilain
Luke Palmer wrote:
And how do I explicitly define the precedence?
Using the `tighter`, `looser`, and `equiv` traits.  You specify
precedence in terms of the precedence of other existing ops.
sub infix:<.>(&f, &g) is looser(&infix:<+>) {...}
This is interesting.  So, infix:< > is similar to Haskell's
() circumfix operator, like ((+) 1 2) â (1 + 2).
Which method does &infix:<+> refer to, if you have;
 multi sub infix:<+>(Num $i, Num $j) { $i.add($j) }
 multi sub infix:<+>(Set $i, Set $j) { $i.union($j) }
?
Are these automatically locked to the same level, in fact, does it
make sense for any 'operator' (ie, the sub's short name) to exist
in multiple precedence levels at once?
Or is it simply a major ParseF*** to have to determine precedence
/after/ determining types of operands?
Sam.


Re: reduce metaoperator on an empty list

2005-05-19 Thread Sam Vilain
Edward Cherlin wrote:
Here is the last answer from Ken Iverson, who invented reduce in 
the 1950s, and died recently.
file:///usr/share/j504/system/extras/help/dictionary/intro28.htm
  [snip]
Thanks for bringing in a little history to the discussion.  Those links
are all local to your system; do you have internet reachable versions of them?
Cheers,
Sam.


Re: reduce metaoperator on an empty list

2005-05-19 Thread Sam Vilain
Stuart Cook wrote:
In Haskell, there is a distinction between foldl and foldl1 (similar
remarks apply to foldr/foldr1[1]):
The former (foldl) requires you to give an explicit 'left unit'[2],
which is implicitly added to the left of the list being reduced. This
means that folding an empty list will just give you the unit.
i.e.
foldl (+) 0 [a,b,c] = ((0+a)+b)+c
foldl (+) 0 [] = 0
The latter (foldl1) doesn't use a unit value, but this means that you
can't fold empty lists.
i.e.
foldl1 (+) [a,b,c] = (a+b)+c
foldl1 (+) [] = ***error***
sure.  Maybe the identity values could be supplied by making the reduce 
operator
for them a curried version of reduce, where reduce requires a list with at least
one element (or DIES :))
eg, something similar to; (sorry for the psuedo-perl6, corrections welcome :))
  sub prefix:<[+]> ([EMAIL PROTECTED]) ::= &reduce.assuming(func => &infix:<+>, 
first => 0);
  sub prefix:<[*]> ([EMAIL PROTECTED]) ::= &reduce.assuming(func => &infix:<*>, 
first => 1);
This would mean that unless the operator specifically defines a curried reduce
version of itself, then the [] version of it on an empty list will be a hard 
run-time
error.
Then again, maybe an identity trait is more elegant and covers the varied ways
that multiple operators combine inside reduce..
> You /could/ try to do something 'sensible' and return 0 or undef, but
> this seems likely to result in more confusion.
Personally I think returning an undef for this kind of situation would be as 
wrong
as returning undef for 0/0.
Sam.


Re: Complex Arithmetic

2005-05-19 Thread Sam Vilain
Edward Cherlin wrote:
There was a discussion of the principal value of square root on 
this list some time back, making the point that for positive 
   [...]
It turns out that the domain and range and the location of the 
cut lines have to be worked out separately for different 
functions. Mathematical practice is not entirely consistent in 
making these decisions, but in programming, there seems to be 
widespread agreement that the shared definitions used in the 
APL, Common LISP, and Ada standards are the best available.
Do we want to get into all of this in Perl6?
pugs currently has "Complex" as a built-in type, though it isn't explicitly
listed in S06.  I can't see any tests for them yet, though.
So, testing the Complex number functionality as well as detailed
exploration of the corner cases, and alignment with best practice will
surely be appreciated by people looking at doing Complex math in Perl 6.
I think this applies regardless of whether it ends up a "core" type
(whatever that means) or not.  Personally I don't think that Complex numbers
are so bizarre an entity that you wouldn't want sqrt(-1) to return one
out of the box.
It's likely that very little implementation changes will need to be done,
as no doubt the mathematically minded folk that write GHC will have been
through that before.  But it will be invaluable in testing compliance of
the different run-time engines.
I suggest you come to the IRC channel at #perl6 on irc.freenode.net, and
ask for a committer account.
Sam.


Re: [S29] uniq

2005-05-19 Thread Sam Vilain
Mark Overmeer wrote:
'uniq' differs from 'sort' because there is no order relationship between
the elements.  A quick algorithm for finding the unique elements in perl5
is
   sub uniq(@)
   {  my %h = map { ($_ => 1) } @elements;
  keys %h;
   }
...and an even quicker one is:
 use Set::Object;
 sub uniq(@)
 {
 set(@_)->members;
 }
or
 use v6;
 use Set;
 sub uniq([EMAIL PROTECTED])
 {
 set(@items).members;
 }
Sam.


Junctive and Higher order Types

2005-05-19 Thread Sam Vilain
Hi all,
While trying to convert Haskell statements like this to Perl 6:
 data Cxt = CxtVoid -- ^ Context that isn't expecting any values
  | CxtItem !Type   -- ^ Context expecting a value of the specified type
  | CxtSlurpy !Type -- ^ Context expecting multiple values of the
-- specified type
 deriving (Eq, Show, Ord)
I'd like to be able to write it something like this:
 type Cxt is CxtVoid
   | CxtItem of Type
   | CxtSlurpy of Type
  does (Eq, Show, Ord);
To be a shorthand for:
 type CxtVoid;
 type CxtItem of Type;
 type CxtSlurpy of Type;
 type Perl::Cxt is CxtVoid | CxtItem | CxtSlurpy
does Eq does Show does Ord;
Is this overloading the 'of' operator too far?
For many there will be a lot of new concepts there.  For a start, I'm assuming that "of" is being used as a higher order type 
definition, much like "Array of Wotsits" would declare.  Also, there is a type there - CxtVoid - which is nothing but a Type!  No 
representation.  Of course, if you have a variable of type Cxt, and it is a CxtVoid, then that will need to be represented in some 
way.  But you generally wouldn't care how.

An alternative might be to try to shoe-horn the concepts into Roles etc.  Who 
knows, perhaps they'll even fit!  :-)
Sam.


Re: Sets

2005-05-26 Thread Sam Vilain

Patrick R. Michaud wrote:
> The continuing exchanges regarding junctions, and the ongoing tendency
> by newcomers to think of them and try to use them as sets, makes
> me feel that it might be worthwhile to define and publish a standard
> C class and operations sooner rather than later in Perl 6

I agree.  See pugs/ext/Set.

It presents a set-like interface to Junctions.

eg,

  use Set;

  my $low = set( 0..4 );
  my $odd = set( (0..4).map:{ $_ * 2 + 1 } );

  say ($low ∩ $odd).members.join(",");  # 1,3
  say ($low ∪ $odd).members.join(",");  # 0,1,2,3,4,5,7,9

  # difference - not this is not a backslash, it's U+2216
  say ($low ∖ $odd).members.join(",");  # 0,2,4
  say ($odd ∖ $low).members.join(",");  # 5,7,9

  # symmetric difference - union of the above
  say ($low % $odd).members.join(",");  # 0,2,4,5,7,9

  # test for membership
  say $low ∋ 4;   # true
  say $low ∌ 5;   # true
  say $odd ∋ 4;   # false
  say $odd ∌ 5;   # false

  # set relations
  say ( $low ∪ $odd ) ⊇ $low;   # true

Well, actually the above doesn't work yet.  But there are ASCII versions
and english methods for those that like coding something that actually
works today ;).

Here's a directed graph traversal that handle cycles correctly; this is
largely why I'd like to see a common Role to all containers... so that
.values can be expected to DTRT.  OTOH, maybe Maps with object keys would
"miss out" in this algorithm so another method name is more appropriate.

  use Set;
  my @stack = ($root);
  my $seen = set(@stack);

  while (my $item = shift @stack) {
  # do something with $item

  if $item.can("values") {
  push @stack, $item.values.grep:{ $seen.insert($_) };
  }
  }

Caveats for the above probably abound, but you get the picture.

Note that the Set::Object module for Perl 5 is useful for the same thing
(assumes that $root is a ref):

  use Set::Object qw(set);
  use Scalar::Util qw(reftype blessed);
  use Perl6::Junction qw(any);
  my @stack = ($root);
  my $seen = set(@stack);

  while (my $item = shift @stack) {
  # do something with $item

  if (blessed $item and $item->can("members")) {
  push @stack, grep { ref $_ && $seen->insert($_) } $item->members;
  }
  if (reftype $item eq "HASH") {
  push @stack, grep { ref $_ && $seen->insert($_) } values %$item;
  }
  elsif (reftype $item eq "ARRAY") {
  push @stack, grep { ref $_ && $seen->insert($_) } @$item;
  }
  elsif (reftype $item eq any(qw(REF SCALAR)) ) {
  push @stack, $$item if $seen->insert($$item);
  }
  }

As you can see, this sort of thing ends up an anti-design pattern.

Sam.


Re: function signatures?

2005-05-29 Thread Sam Vilain

Ingo Blechschmidt wrote:

Are signatures going to be an exposed first class object in Perl 6?

I hope so, too.
  ~&foo.signature;
  # Signature objects should stringify to a canonized form, e.g.:
  # ~sub (Str $bar, CoolClass $z where {...}) {...}.signature ==>
  # 'Str $bar, ANONCLASS(0xDEADBEEF)'
  # (BTW, I don't think it's possible to display anonymous subtypes more
  # friendly, as the where-clause may contain arbitrary code, and Code
  # objects are not (yet?) fully introspectable -- i.e.
  # &foo.statements[3].line doesn't work.)

  +&foo.signature.required_args;
  # Number of required args
  &foo.signature.required_args;
  # Hash name -> class

  &foo.signature.positional_args;
  &foo.signature.named_args;
  # etc.
Thoughts?


Translations of the corresponding Pugs types into Perl 6 code is at:

  ext/Perl-MetaModel/lib/Pugs/VCode.pm

However they are mostly still sketches.  If you have specific ideas about
the Code::Signature signature in Pure Perl terms, place it in;

  ext/Perl-MetaModel/lib/Code/Signature.pm

These objects will eventually be what you get from &foo.meta, etc.  Or at
least I assume that the way to get to the object's signature will be .meta.
Maybe the "Code" class will define a ".signature" method as an alternative
to .meta.signature.

Sam.


Re: Strongly typed containers?

2005-05-30 Thread Sam Vilain

Yuval Kogman wrote:
> We already have the Set class, how do we say what it contains?
> class Set {
>has $.type;
>method members returns $.type () { ... }
> }
> my Set of Int $s = Set.new; # is this how you call it?

You are describing "Higher Order" types, also called Generic Algebraic Data 
Types (GADTs) in Haskell.

Please refer to the earlier discussions

 Parts 1 and 2 of http://xrl.us/f9re

I also started a similar post on a related note that was "warnocked", though the post was more to demonstrate an apparent syntax 
isomorphism between Haskell and Perl 6 than posing a particular question (probably why it was unanswered).


  http://xrl.us/f9rg

I think there has probably been other discussions, including one where Autrijus specifically asked this question for the Set module, 
but I can't find that one.


Sam.


Re: Unicode Operators cheatsheet, please!

2005-05-31 Thread Sam Vilain

Rob Kinyon wrote:

I would love to see a document (one per editor) that describes the
Unicode characters in use and how to make them. The Set implementation
in Pugs uses (at last count) 20 different Unicode characters as
operators.


I have updated the unicode quickref, and started a Perlmonks discussion node
for this to be explored - see http://www.perlmonks.org/index.pl?node_id=462246

Sam.


Re: date and time formatting

2005-05-31 Thread Sam Vilain

Rob Kinyon wrote:

What I'm trying to get at isn't that DateTime's API should be
preserved. I'm saying that the concept of DateTime should be ported.
Core or not core - it doesn't matter. When use'd (or installed), it
should override now() (and anyone else we can think of) to return an
object that DWIMs, plus provides the interface you've outlined below.


I've made a start on this.  See ext/Date in pugs.  I don't think that
your views are necessarily contrary.

The biggest reason I didn't use DateTime was that I found it awkward
for the common case; most of the time I just want to stuff in an
ISO8601 date.  I also don't like implicit normalisation to seconds
underneath the hood when I'm doing basic date calculations, and
the way that the "DateTime" base class is inherantly based on the
Gregorian calendar.

The "Date" and "Duration" roles are extremely minimal; see

   http://svn.openfoundry.org/pugs/ext/Date/lib/Date.pm
   http://svn.openfoundry.org/pugs/ext/Date/lib/Duration.pm

The major API is described at:

   http://svn.openfoundry.org/pugs/ext/Date/lib/Date/Gregorian.pod

This module is supposed to be somewhere between DateTime and
Class::Date, with built-in ISO-8601 support (as it's the standard ;)).

With a bit of luck, all Date implementation can share this `Date'
Role, and Gregorian calendar modules share the `Date::Gregorian' Role,
so that the multitude of implementations that crop up will be mutually
exchangable, and the simple case fast, efficient and useful.

Sam.


Re: "returns" and context

2005-05-31 Thread Sam Vilain

Rod Adams wrote:

How do I specify the signature of a context-sensitive function?
sub foo() returns (what?) {
return want ~~ Scalar ?? cheap_integer_result :: List_of_Sheep;
}

I suspect a typed junction would look like : "Junction of Int|Str".


Not quite.  AIUI that means a Junction of which the members are Int or Str.

This is how I've been writing it:

  sub foo() returns Scalar|List {
  return want ~~ Scalar ?? cheap_integer_result :: List_of_Sheep;
  }

I think the default return type of unlabeled subs would be:

  returns Void|Scalar|List

but of course $?SELF =:= none(@Larry) ;)

Sam.


Re: What the heck is... wrong with Parrot development?

2005-06-06 Thread Sam Vilain

Fagyal Csongor wrote:
With all respect, I think this is a very important thing which needs 
attention, and I hope that you will help us to clarify the situation. I 
am pretty sure Dan did not leave because he had a bad day - we know he 


Dan's position was very stressful, he had people from all sides trying to
tear him down, even though many were also propping him up and he has a
great level of skill.

However, to altercate on the hows and whys of his action is premature; I
suggest a moratorium on such debate for at least as long as he was the
project leader, for correct perspective.

Please honour his decision to bow out gracefully without turning it into
a childish battle of egos.

In the meantime let us celebrate 5 years of Dan Sugalski's contribution
to the Parrot and Perl 6 project.

Three cheers for Dan!

Sam.


Re: reduce metaoperator on an empty list

2005-06-06 Thread Sam Vilain

Roger Hale wrote:
This is why I would rather the o -> [o] circumfixion left [o] an infix, 
not prefix operator.  I would rather be explicit about my identity:

$product = 1 [*] @array;


Hmm.  Not all operators *have* an identity.

You'd have to write, in that case;

  @array[0] [ƒ] @[EMAIL PROTECTED]

Which isn't great IMHO.

Sam.


Re: reduce metaoperator on an empty list

2005-06-06 Thread Sam Vilain

Damian Conway wrote:

What you want is:
$product = ([*] @values err 0);
Or:
$factorial = ([*] 1..$n err 1);


The "err" operator bind only to the point on the instruction it is
attached to, ie it's not a shortcut for eval(), right?

I'm just seeing some edge cases here for custom defined operators; you
don't want exceptions getting silently converted to default values...

Sam.


Re: reduce metaoperator on an empty list

2005-06-07 Thread Sam Vilain

Luke Palmer wrote:

< and > still don't make sense as reduce operators.  Observe the table:
# of args   |   Return (type)
0   |   -Inf
1   |   Num  (the argument)
2   |   bool
... |   bool


Let's look at the type of one of the many `reduce' variants in Haskell;

  foldr1 :: (a -> a -> a) -> [a] -> a

This is the Perl6ish;

  sub reduce( ::Code{( ::(someType), ::(someType) ) returns ::(someType)} $func,
  Array of ::(someType) ) returns ::(someType);

ie, the function $func supplied must take and return arguments of a single
type.  So you have come to the same conclusion as the FP folk :-).

Here I'm using ::(foo) as a coined syntax for a parametric type to the
definition.  `someType' need not be defined anywhere else, but must be
the same within the application of a definition.

IMHO we still need to make some movements towards a specification for how
this sort of thing is specified...

>  I just think we have to give
> nonhomogeneous operators like < some special treatment.  So, from our
> somewhat lexical definition of reduce, I don't think an identity input
> is what we're looking for.  We really want an identity output.

When I last looked, in pugs, functions that return "bool" types are
currently setup to return one or the other argument when used with reduce;
like there is a similar;

  multi
  sub reduce( ::{Code( ::(someType) $a, ::(someType) $b ) returns bool} $func,
  Array of ::(someType) ) returns ::(someType);

This gives meaning to operators like [>], which would return the maximum
value from a list.

Sam.


Re: reduce metaoperator on an empty list

2005-06-09 Thread Sam Vilain

TSa (Thomas Sandlaß) wrote:

I'm not sure but Perl6 could do better or at least trickier ;)
Let's assume that < > <= >= when chained return an accumulated
boolean and the least or greatest value where the condition was
true. E.g.
  0 < 2 < 3   returns  0 but true
  1 < 2 < 1   returns  1 but false
  4 < 5 < 2   returns  2 but false


An interesting idea, but seems a bit heavy..


Is it correct that [min] won't parse unless min is declared
as an infix op, which looks a bit strange?
if 3 min 4 { ... }


Sure.  Again there is a Haskell example to heed closely here; for instance, the 
function:

   divMod :: (Integral a) => a -> a -> (a, a)

Can be written as either;

   divMod 42 9

or:

   42 `divMod` 9

The reverse direction is ();

   (+) :: (Num a) => a -> a -> a

   (+) 7 5

   7 + 5

Sam.


AUTLOAD and $_

2005-06-19 Thread Sam Vilain

From S10;

  In any case, there is no longer any magical $AUTOLOAD variable. The
  name being declared or defined can be found in $_ instead. The name
  does not include the package name. You can always get your own package
  name with $?PACKAGENAME.

So, what is the prototype of AUTOLOAD?  It is clearly called from the
relevant (package dispatcher & type & perl5_compat(stash) ) object, but
how?

 sub AUTOLOAD($_ = $CALLER::$_, [EMAIL PROTECTED]) {
 ...
 }

In a way, $_ forms part of the prototype definition, but is "out of band"
to the regular arguments on @_; it can't interfere with positional
characteristics, or you have to "shift" it off before you goto the right
sub.

OK, we could play tricks with localization of variables, but in the face
of continuations and coroutines, localization falls apart.  This is fine
for people writing `ordinary´ code (perhaps), but for a core language
feature it should be resolved IMHO.

Out-of-band arguments seem to have been a hot topic in the past;

   http://xrl.us/ggt7 - Long (50+ posts) thread

   http://xrl.us/ggua - suggestion from Damian;

 $foo = sub { print $_ } is given($_);

I actually quite like that syntax, or at least the idea of using a trait
of some kind to specify non-positional arguments.  It keeps them well
out of the way of `safe´ programming conventions :).

In fact, it has to do wierder things than just accept it out of band to
parameters - ideally it would not also interfere with another sub that
uses $CALLER::_.

Perhaps to avoid that mess, the AUTOLOAD function is simply expected to
call &func.goto if it wants all the effects of the presence of the
AUTOLOAD sub to go away.  Assuming that the prototype is re-checked on a
goto, to ensure that type guarantees specified in the function signature
are honoured, then the necessary side effects should just happen.

Sam.


Re: AUTLOAD and $_

2005-06-20 Thread Sam Vilain

Juerd wrote:

I think there exists an even simpler way to avoid any mess involved.
Instead of letting AUTOLOAD receive and pass on arguments, and instead
of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its
thing, and then have *perl* call the sub?
sub AUTOLOAD ($w) { return our &::($w) := get_subref_for $w }


I like that.  Makes it more consistent with the AUTOSCALAR, etc methods -
returning a reference to the result (variable ref/code ref/sub name) rather
than the actual result (variable value/calling the sub).

After all, presumably the compiler might sometimes call the AUTOLOAD at
compile time; to get its signature.  So, for instance, you could AUTOLOAD
all the methods you optionally export, which are all pulled in at once when
a module imports a function and tries to use it in some code (as the
signature will need to be checked then).  I was going to bring that up
next, but I think this has already answered it.

Sam.


Re: AUTLOAD and $_

2005-06-20 Thread Sam Vilain

chromatic wrote:

Who says AUTOLOAD will always either call a loaded sub or fail?


Maybe it should be passed a continuation too, then?  Then it could
choose exactly what to do with it.

Sam.


AUTOLOAD, this time distinct from AUTOSUB etc (and spelt correctly)

2005-06-20 Thread Sam Vilain

OK, that last discussion was productive, but I think we all (including
myself) overlooked the fact that the AUTOLOAD and AUTOSUB methods are
implied to have different calling conventions;

  There is still an AUTOLOAD hook that behaves as in Perl 5.

  The (AUTO*) routines are expected to return a reference to
  an object of the proper sort (i.e. a variable, subroutine,
  or method reference), or undef if that name is not to be
  considered declared.

So, here are the prototypes of the (new) AUTO* methods:

  subtype Symbol of Str;

  sub AUTOSCALAR( Symbol $sym ) returns Ref of Scalar;
  sub AUTOARRAY ( Symbol $sym ) returns Ref of Array;
  sub AUTOHASH  ( Symbol $sym ) returns Ref of Hash;
  sub AUTOSUB   ( Symbol $sym ) returns Code;
  sub AUTOMETH  ( ::$type: Symbol $sym ) returns Code(::$type: *);

uh-oh, another sticky one; the implication is that AUTOMETH has an
invocant, which is either a Type or the object, and is expected to
return a sub whose signatute has the right type, but we don't care
to type check anything more than the invocant type.  And that's even
before we look at MMD, so for now we'll think of it as;

  sub AUTOMETH  ( Symbol $sym ) returns Ref of Code;

So, those are all well and good.  They can still do anything,
including return little micro-subs that perform arbitrary munging
of the argument stack before passing them on, or define the
sub/variable that was referred to, to avoid the AUTOFOO call the
next time around.  And they're being invoked at compile time so that
we can get their signatures, but that isn't a problem with people
doing selective loading because they're clever enough to know what
to do.  Great, we can all start using those.

But what about AUTOLOAD?  It has to "behave as in Perl 5", which had
different calling conventions and expected you to make the loaded
function call yourself.

This has some side-implications; the signature used for a Class'
AUTOLOAD will be used as the signature for all unknown function calls;
so, defining;

 sub AUTOLOAD {
 ...
 }

Will forfeit your right to apply signatures to the arguments of an
auto-loaded method, which is probably an acceptable penalty for someone
who is just expecting P6 to work like P5 did.  Method calls, too.

It seems these requirements are still in conflict;

   - Preserving AUTOLOAD thou-shalt-make-the-call semantics
   - Keeping the new $AUTOLOAD off the argument stack for AUTOLOAD()
   - Use of $_ as an out-of-band way of passing arguments to a function
 cannot be localised due to the non-stack-like characteristic of
 the call stack, in the face of continuations and coroutines
   - disallowing "explicit" out-of-band arguments

Time to re-think the out-of-band arguments idea?

Sam.


Re: AUTOLOAD, this time distinct from AUTOSUB etc (and spelt correctly)

2005-06-20 Thread Sam Vilain

Rod Adams wrote:
I never liked the idea of out-of-band arguments. Either something is 
passed, is available due to being in a broader scope, or can be gleamed 
from introspection.


ok.  First of all, I agree with the basic sentiment.

However, to play devil's advocate and re-interpret what you just said, it
does imply that there are some implicit lexicals being passed around -
? twigil variables.

These are effectively out-of-band arguments to a function, but not user-
modifyable.

So what we're saying is that out-of-band arguments must be passed via
language/grammar special variables, so to do that from Perl code you'll
have to extend the interpreter, quite a challenging task at present.
That'll stop them being used Where We Don't Want Them To Be Used™.  :->

In this case, I think introspection is the answer. Hang the info off 
&?SUB or caller. Something like "&?SUB.Invocation" or "caller.call" 
could be made to return something useful, I think. Also makes the info 
available for more than just AUTO.* methods, which opens the door up for 
all kinds of useful perversions, especially in the age of bindings and 
such.


Sure.  Structurally, and architecturally, I like this too.
But syntactically, $?LASTQUOTEDPARA.idea is a little overweight.  But no
big problem.

Perhaps the problem here is that sometimes you want to explicitly
specify which available lexical variable the topic refers to on an
arbitrary block.

Personally I'm of the leaning that there is no global $_ at all. There is
no such thing as a global topic of a program, after all.  I don't think
I'm contradicting the Synopses there, either.  ie, in the main program $_
should not be in scope.

In this manner, $_, instead of actually being a real variable, is simply
an alias which always has lexical scope and happens to be normally bound
to $?SELF in method calls, and to @_[0] in bare blocks, and an anonymous
temporary variable in for loops.

And in AUTOLOAD blocks, it's bound to the $?SUB.called_as (or whatever)
lexical, out-of-band variable.

But how does that happen?  What makes the AUTOLOAD sub special to get
this action?

Clearly, we don't want people to have to explicitly say so in their
AUTOLOAD signature:

  sub AUTOLOAD($_ = $?SUB.called_as) {

  }

Plus, the above still wouldn't do what we want because it's still
specifying a positional argument.

I'm seeing something like this; however it's still a bit awful for
various reasons.

  package Package;
  sub dispatcher {
  ...
  %symtable::.assuming($_ = $method)(@args);
  ...
  }

Perhaps it is simply a mistake to assume that the package dispatcher
will itself be simple, accessible Perl like that.

Anyone got any bright ideas?  :)

Sam.


Magic mutators and my $var is Proxy( ... );

2005-06-26 Thread Sam Vilain

To me it is a trivial case that you want to provide a fake attribute
which for all intents and purposes behaves exactly like there was a real
attribute there, backing against another attribute.

A Date object is a classic example of this; you want to provide 0-based
and 1-based attributes, which you want to present as equivalent to each
other.

So, we've got this "my $var is Proxy( ... )" construct in A06.
Say you've got this class:

  class MagicVal {
 has Int $.varies is rw;

 method varies returns Int is rw {
return my $var is Proxy ( :for($.varies),
  :FETCH{ $.varies += 2 },
  :STORE{ $.varies = $_ + 1 },
);
 }
  }

Firstly, would this be correct syntax?  In particular, what should
I call $.varies inside the :FETCH and :STORE subs?  Would they close
over $?SELF, too?

If they did, doesn't this mean that $var will be a new Proxy attribute
every time that the attribute is read, and will have side effects?

Such as;

 my $foo = MagicVal.new();
 $foo.varies = 5;# sets to 6;
 say $foo.varies;# says 8
 say $foo.varies;# says 10
 my $var = $foo.varies;  # $var is proxy for attribute
 say $foo.varies;# says 12
 say $var;   # says 14

It seems to me that the only time I'd want to actually return a
Proxy object is when taking a reference to the fake attribute.  In
all other situations, you'd simply want to dispatch to either an
accessor or a mutator, depending on the context.

ie, I'd like the design of this feature to be sufficient that most
of the time, the Proxy object need never be constructed, and instead
the relevant closure could be bound to that method instead.

In particular, I think this would mean making Proxy objects
automatically call FETCH when returned, unless in reference context.

In fact, I think I'd rather see the proxy as a closure trait;

  class MagicVal {
 has Int $.varies is rw;

 method varies returns Int is Proxy( :FETCH(&get_varies),
 :STORE(&set_varies) );

 method get_varies { $.varies += 2 };
 method set_varies { $.varies = $^v + 1 };
  }

Of course this wouldn't preclude the possibility of using the syntax
in A06 where it is more suited to the problem at hand.  Also, in the
case where you do take a reference of a $foo.varies, then a Proxy object
could be constructed to DTRT based on the information there.

This would make the "is Proxy()" construct effectively a compile-time
want() switch.

Any opinions on this?

Sam.


Re: Magic mutators and my $var is Proxy( ... );

2005-06-26 Thread Sam Vilain

Sam Vilain wrote:

To me it is a trivial case that you want to provide a fake attribute
which for all intents and purposes behaves exactly like there was a real
attribute there, backing against another attribute.

A Date object is a classic example of this; you want to provide 0-based
and 1-based attributes, which you want to present as equivalent to each
other.


FWIW, I think this question also applies to fetching members from a hash
collection.

For example, if you have a function;

  sub foo($foo) { $foo || "bar" }

And you call it, passing it a hash slot;

  foo(%hash);

Then it will be auto-vivified, as in Perl 5; because a reference to the
slot had to be taken.  Actually there is no reference taken; it's a
read-only binding of the hash slot.  But either way, it is a read-only
point in the signature that is affecting the input argument, which is
arguably (right^wrong).

By returning a Proxy object 'tied' to the slot, then this autovivification
could be circumvented and the straightforward implementation - passing
bound variables as transparent references, continues to be acceptable.
Albeit requiring that the Hash::postcircumfix:<{ }> method is a Proxy
method, too.

Sam.


Re: AUTLOAD and $_

2005-06-26 Thread Sam Vilain

Piers Cawley wrote:

For myself, I'd like to see AUTOLOAD with a signature along the lines of:
   sub AUTOLOAD (Symbol $sym, ArgumentCollection $args, Continuation $cc)
 returns (Code | Pair)
   {
 ...
   }
This presupposes a deal of support infrastructure, but also provides
flexibility. For the 'NullObject' case, you'd simply do C<$cc()> to return
directly to the caller, skipping over whatever Perl is up to.


That's an excellent suggestion.  After your very enlightening discussion
about continuations in IRC, this popped to mind as an interesting application
for them, along with exception handlers.

This would be great for at least AUTOSUB and AUTOMETH.

However, for AUTOLOAD we're looking for simple Perl 5 alikeness.  And in
Perl 5, the sub name was passed out of band.

So, we need a compromise somewhere, please @cabal.pick:

  - just go for old AUTOLOAD + $AUTOLOAD interface and spit warnings
profusely
-OR-
  {
  - allow topic to refer to variables in lexical scope, but not in @_
(and pick a good name for $?SUB.called_as)
-OR-
  - allow generic out-of-band parameters to be passed in
  }
  implies {
  - there needs to be a special subroutine calling method, similar to
.assuming that lets you do this
-OR-
  - the method prototype, and specify some way that methods
defined without a signature can inherit it from somewhere else.
  }
-OR-
  - declare the topic to be the only out-of-band parameter that does this.
To avoid it being an accidental global, it would need to be declared with
"my $_" when used in this manner (of course, other methods like for, given,
etc that set it have the declaration implicit).
-OR-
  - scrap complete AUTOLOAD interface compatibility
-OR-
  - insert solution here ;)

Sam.



  1   2   >