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


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


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:

#meta $o.?meta
#ref $o.?type
#var $o.?var
#id $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: 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: 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 to use the second syntax if I don't have to, 
 since I like consistency with Junction syntax.

Re: easier duck typing in .can

2006-06-18 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: 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: 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: 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: 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: 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: 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-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: 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: 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: 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 failing-expr err deal-with-it-or-die 
 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: 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: 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?
 code
 [...]
int x = 0; int y[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; y[x++]++; /* line
 that matters */
 [...]
 /code
 
 in perl5, i would've written something like:
 code
 my $x = 0; my @y = 1..9; @y[$x++]++; print $x\n; print @y\n
 /code

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?
 
 code
 my $x = 0; my @y = 1..9; [EMAIL PROTECTED]; print $x\n; print @y\n
 /code

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: $_ 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: 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: 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.





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



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-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: $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: Database Transactions and STM [was: Re: STM semantics, the Transactional role]

2005-07-24 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 :default10 }';
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: 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-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-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 the automobile, you wouldn't want to have to 

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: 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 unspecifiedunimportant location.

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-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-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-05 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), :driverSQLite );

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 (overprematuremisguided)-optimisation to avoid using the
full module name in an internal hash or something like that.  But then
maybe (Iwenone(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-04 Thread Sam Vilain

Richard Nuttall wrote:

  - support for automatically pulling database DSN information from a
~/.dbi (or similar) file.  This is constantly re-invented poorly.
Let's just do a connect by logical application name and let the
SysAdmins sort out which DB that connects to, in a standard way.
This reminds me one one thing I hate about DB access, and that is having 
the DB password

stored in plain text.


Sadly, there is really nothing that can be done about this, other than
casual obscuring of the real password like CVS does in ~/.cvspass

However, making it in a file in $HOME/.xxx means that the sysadmin can
set it up to be mode 400 or something like that, to ensure other users
can't access it if someone forgot to set the permissions right on the
application code (or, hopefully, configuration file).

Of course, for more secure access schemes like kerberos, etc, the file
is really just being a little registry of available data sources.

On a similar note could be allowing overriding the data source used by
an application by setting an environment variable.  That way, the
SysAdmin has got lots of options when it comes to managing different
production levels - Oracle has this with TWO_TASK, and while it's a
PITA when it's not there (no doubt why DBD::Oracle allows this to be
specified in the DSN string), it's also useful for what it's intended
for - switching databases from an operational perspective.

Sam.


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 = %sthssome_query_id;
  $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( :driverRosetta );   # means DBD::Rosetta
  $dbh = DBI.new( :driverRosetta::Emulate::DBD ); # specify full package
  $dbh = DBI.new( :driver(Rosetta::Emulate::DBD) ); # pass type object
  $dbh = DBI.new( :driver(DBD::SQLite.new(:foobar)) ); # pass driver object

Sam.


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

2005-07-03 Thread Sam Vilain

Hey Tim.

 I've kept an eye on Perl 6 and Parrot developments but I'm no expert in
 either. What I'd like *you* to do is make proposals (ideally fairly
 detailed proposals, but vague ideas are okay) for what a Perl 6 DBI API
 should look like.
 Keep in mind that the role of the DBI is to provide a consistent
 interface to databases at a fairly low level. To provide a *foundation*
 upon which higher level interfaces (such as Class::DBI, Tangram, Alzabo
 etc. in Perl 5) can be built.

OK, well based on my experience, here's a few things that would be nice;

  - optional treatment of the statements as an AST, similar in concept to
SQL::Routine, or Tangram::Expr.  Death to SQL templating systems!

Ideally there should be no need for a module like DBD::CSV or even,
eventually, DBD::SQLite to actually generate SQL strings for queries;
the AST is enough for them to go away and run the query.

It should be possible to use either, though - and use /named/
placeholder arguments for either, something like:

use DBI-2;
my $dbi = DBI-connect(...);
my $sth = $dbi-prepare(select * from foo where bar = :bar);
$sth-execute(:bar($bar));

my $table = $dbi-table(foo);
my $sth = $dbi-select
(:all
 :from($table),
 :where($table.bar == $dbh.placeholder(bar))
);
$sth-execute(:bar($bar));

Virtually every major DB abstraction tends to build this, whether or
not they know they're doing it ;).

  - support for automatically pulling database DSN information from a
~/.dbi (or similar) file.  This is constantly re-invented poorly.
Let's just do a connect by logical application name and let the
SysAdmins sort out which DB that connects to, in a standard way.

  - object-oriented modelling of core database objects, so that schema
operations can be made portable, a la Rosetta.  This should really
just constitute re-thinking the existing interfaces, and leaving it
up to the DBD authors to finish them up.

This may also open the door for unifying the way that relationships
such as foreign key constraints, etc are dealt with.

  - make it easier to get ACID right; steal Tangram's `tx_do` transaction
interface; though I'd suggest a name including the perl6-ish `try'

 $dbh.tx_try {

 # ... transaction ...

 };

in fact, if you were to wrap the closure in an atomic{ } block, then
you could probably easily support replaying the transaction in the
event of a forced rollback (so long as the code in the closure has no
side effects ... g)

Also there is the nested transction interface;

$dbh.tx_start;
$dbh.tx_start;
$dbh.tx_commit;
$dbh.tx_commit;  # commit happens here

Some databases can even support nested transactions internally via
SQL SAVEPOINTS.

  - asynchronous/event-based processing of queries, so that we don't need
yet another sub-process when in POE-like environments (which might
include a standard Perl 6 event programming system).

In terms of making things Perl6-ish, you probably want to look at technology
such as coroutines for cursors, and continuations for exception handling, for
their implications to writing transactional applications.

Perl 6 will be able to serialise continuations and probably also coroutines,
so it should be possible for a continuation serialised with an active cursor
in a coroutine to automatically resume itself once the continuation is thaw'ed.

This might happen by simply leaving the transaction open (I hear screams!) in
a single threaded context, or by rolling back, replaying the transaction's
queries on the continuation resume and checking all the database responses
match what was previously read.  At the first sign of discrepancies, the
next database operation would throw a fake ROLLBACK; which would even be
caught and the application transaction replayed from the beginning, if they
used .tx_try :retry(3), :{ ... }

This would make some of the old problems, such as object versioning,
potentially a lot easier to solve.

Allow me to illustrate with some application code;

  my $mvc;

  if ($mvc.controller.action eq edit) {
 my $id = $mvc.controller.edit_id;
 my $object;
 $dbi.tx_try {
$object = $fetch_query.select_only(:id($id));

$mvc.view(:state(edit), :object($object))
   until $mvc.controller.action eq commit;

$update_query.execute(:id($id));

CATCH {
$mvc.view(:state(error),
  :message(object modified by another!));
}

 }, :retry(3);
 $mvc.view(:state(edit), :object($object));
  }

So, depending on the MVC system in use, when you wrote $mvc.view(), it
will have done one of the following things;

Session-based continuations:

1. Serialise the continuation - when it comes across the DBH with an
   active transaction, it creates 

Re: SMD is for weenies

2005-06-30 Thread Sam Vilain

Yuval Kogman wrote:

As I understand it SMD is now not much more than a mechanism to
place a constraint on the MMD, saying that there can only be one
method or subroutine with the same short name.
Why is this the default?


Otherwise you lose this quite useful warning if the signatures didn't
match;

   method foo redefined at ...

I agree with you MMD is very cool, and I use it a lot.  But I don't
mind clarifying the intent with multi; this overloading is
considered by some to be surprising to new programmers.

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(%hashkey);

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.



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::AUTOLOAD.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.


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


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

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: 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: 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: 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: 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
 CSet 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: 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: 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: 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: 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: 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: 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.


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


Re: Documentary annotations: $what docwhy

2005-04-01 Thread Sam Vilain
Luke Palmer wrote:
Supposing I had a doc trait, could I say:
   sub f2c (Num $temp docTemperature in degrees F)
   docConvert degress F to degrees C
   {...}
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: 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: [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:

 sect1
   titleHeading/title
   parafoo/para
 /sect1
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;
 sect1
   titleFoo/title
   para=head1
 =
 = =head1 That's just getting ridiculous/para
 /sect1
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:

 sect1
   titleFoo
 =head1
 =
 = =head1 That's just getting ridiculous
 /title
 /sect1
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 

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($j10){if($j1){}} ?
 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 g).
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: Object spec [x-adr][x-bayes]

2003-03-07 Thread Sam Vilain
On Sat, 08 Mar 2003 06:58, Dan Sugalski wrote:
 At 2:08 PM +1300 3/7/03, Sam Vilain wrote:
 As long as mechanisms are put in place to allow modules to bypass
  object encapsulation and private/public constraints, and given that
  Parrot will have no XS,

 It wouldn't be wise to jump from Parrot won't do perl 5's XS scheme
 to Parrot won't have a way to write code for it in C. It will,
 arguably, be *easier* in parrot to write parts of your program in C,
 thus making it more likely that less of an object will be guaranteed
 to be done entirely in parrot-space.

OK.  Perhaps those structures should have a method/PMC that they must 
export which will dump their internal state into a near equivalent Parrot 
data structure rather than just having serialisation methods, for the sake 
of the tools that want to traverse it rather than just freeze/thaw it to a 
stream.  ie, something that extracts their state and can be passed to 
`bless' et al to reconstruct the original object.  The structure freezer  
heater can ask objects to present themselves as core types for 
serialisation.  I think this would be a great debugging win as well.
-- 
Sam Vilain, [EMAIL PROTECTED]

Real computer scientists like C's structured constructs, but they are
suspicious of it because its compiled.  (Only Batch freaks and
efficiency weirdos bother with compilers, they're s un-dynamic.)


Re: Object spec [x-adr][x-bayes]

2003-03-06 Thread Sam Vilain
 this.

In the store, you would serialise the object's immediate properties and
attributes as normal, along with any unblessed data structures.  For
associations, the collection hashes/arrays used to implement the
associations as a normal hash/array, but replace the value with the object
id (probably a combination of the object type, so you know which hash to
look in, and its ID).  For references, no collection is needed, just an
object ID.

The Hash mapping engine would need to know the structure of the
relationships to know when to interpret a structure it is thaw'ing as a
value, and when to interpret it as an object reference (to avoid messy
in-band signalling).  And when it is freeze'ing, where to stop in its
traversal of the input data structure.

3. Serialisation.

Relatively easy :-).  I don't think I can say anything here that people
wouldn't already guess.

As long as mechanisms are put in place to allow modules to bypass object
encapsulation and private/public constraints, and given that Parrot will
have no XS, this allows for all manner of serialisation tools - including
tools that allow you to pass a tree describing which nodes you want to
serialise, important for XML and persistence option number 2, above.

 Will the absence of associations force us to rely on attributes and
 convention to serialize an object's associations? I.e.,  as I thought you
 were implying, a messy hack that'll come back to haunt us?

Yes and no.  It is a messy hack that has already engulfed everyone.

I really mean this - I see an awful lot of code in the world that is 
manually dealing with associations.  I've found having ready-to-go 
associations is absolutely whipuptitudalicious.

[ poop-group list members: this is your cue to highlight the inadequacies 
in what I have just stated, so that we can all model the input to our 
object persistence tools in the same way in Perl 6.  Speak now or hold 
your peace for another generation of Perl. ]

-- 
Sam Vilain, [EMAIL PROTECTED]

Two Commandments for the Molecular Age
   1. Thou shalt not alter the consciousness of thy fellow men.
   2. Thou shalt not prevent thy fellow man from altering his or her
  own consciousness. 
 - Dr. Timothy Leary, Pd.D.


  1   2   >