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

2006-11-30 Thread TSa

HaloO,

[EMAIL PROTECTED] wrote:

$_  $xType of Match ImpliedMatching Code
==  = ==
+   Set Set   members identicalmatch if $_ === $x

 +   Array   Set   array equivalent to set  match if Set($_) === $x

Isn't it better to define these in terms of Bags? I mean with
Bag a supertype of Set the dispatch should go to cases 
infix===:(Bag,Bag), infix===:(Bag,Set), infix===:(Set,Bag)

and infix===:(Set,Set).

Regards, TSa.
--


Re: beg for Bag

2006-11-30 Thread TSa

HaloO,

Jonathan Lang wrote:

Would (1,2,2,3,4,4) be a Seq or a Bag?


Comma constructs a Seq, of course.



 IMHO, the _only_ way this
could work would be if it's a Bag: if it's a Seq, I see no way that
one could resolve '(1,2,3) ∪ (3,1,2)'.


This is not any different from '3' + '4' resulting in numeric 7.
It is the operator that builds Bags from (1,2,3) and (3,1,2) and
then calculates the union.



Mind you, I'm still not sold on the idea of performing set operations
on Seqs - it may be technically feasible to do so, but it strikes me
as fundamentally unintuitive.


But you have no problem with doing numeric stuff? E.g. (1,2,3) + (3,4)
actually means +(1,2,3) + +(3,4) == 3 + 2 == 5. It is the operator that
indicates Set/Bag operations. And 'Seq does Bag' comes in handy here.
Actually, no set operation is performed on Seq. The Seq is just used to
build a Bag. This is like there is no string concatenation for numbers,
arrays etc. They are stringified first.

One could also write @a (|) @b and the two arrays would be flattened to
Seq and then used to build a Bag. The only drawback with Bag being the
Seq supertype is that people might want @a (|) @b to mean Set(@a) (|)
Set(@b). The Set enforcement could also come after the Bag union:
Set(@a (|) @b). Perhaps @a (|) @b delivers the result in an Array
instead of a Bag value.

So in general the parens ops should not be called set ops but unordered
ops because this is their core meaning. They are overloaded for Bag and
Set.



I'm still bothered by the idea that you have to wrap _every_ ASCII
representative of a set operation in parentheses - something which is
only necessary when you start applying the full range of set
operations to non-Set entities.  In particular, I want 'Set - Set' to
produce the difference of the two Sets.


But that should be the numeric difference of the cardinalities of the
Sets. Plain - means numeric. It's the same thing that we don't do string
concatenation with + but have a stringish ~ for the task. Hence it works
to say 3 ~ 4 and end up with '34'.



If set operations also apply to Seq, then (=) is not the same as ===.
The former ignores the order of the terms; the latter only does so for
Sets and Bags.  In a way, this is what started the whole debate.


You are correct. This emphasizes the need for (=).



You mention a single disjoint union operator: is it supposed to be
the disjoint union comparison operator (i.e., it returns true if the
sets are disjoint), or the disjoint union composition operator
(which returns a Set of Pairs, with each element being keyed according
to the Set that it was originally in)?


Perhaps we need both. I've chosen (/) for it's visual similarity with
(|) like || and //. We could use (/?) for the disjointness test. Or
doing visual games again: (%). You see the disjoint sets in the glyph.
(:) might work, too.



Saying that complement is difficult is an understatement.  I suppose
you _could_ get it to work by having a 'complemented Set' would keep
track of which elements it _doesn't_ have; but this opens a can of
worms that I really don't think we want to get into (e.g., A ∪
(!)B).  And the notion of a complement with regard to the surrounding
set is already handled by the difference operator.


Isn't that similar in semantics to the none junction? If you have e.g.
a Set of Int (1,2,3) you can express (!)(1,2,3) as Set(*..0,4..*).
But I agree that it is difficult in general. Well, (!)$x might actually
create a large set of almost all currently known objects in some scope.
This might just be written as * (-) $x. IOW, Set(*) means all known
objects. As long as a program is not wielding large data sets complement
might just work---and the complement of a large set is small, of course.

Note that $a (-) $b is equivalent to $a () (!)$b, you have it as the
union. Or did you mean $a (|) (!)$b === (!)($b (-) $a)?

Hmm, how is Bag complement defined in the first place? Is it just
complementing the set and goes for multiplicities of 1?



You did highlight some things - for instance, a Set of Pairs is _not_
a Hash: a Hash has a further requirement that every key must be
unique, whereas a Set of Pairs allows for duplicate keys (but not
duplicate key-value pairs; go with a Bag of Pairs for that).


Correct.

Regards, TSa.
--


Interrogating closures

2006-11-30 Thread Yuval Kogman
Hi,

I think a partial unification of objects and code refs in userspace
is going to be a nice features.

Closures allow people to put arbitrary complexity into a very simple
api that is, in OO terms, just one method (the actual function
call).

Consequentially the closure may never reveal any information about
it's actual behavior.

I think the convenience of closures can be enhanced by allowing
closures to declare that certain captured variables are in fact
instance data (see below for ideas on how).

A trivial example:

my @callback_list;
$some_object.register_callback(sub { for @callback_list - f { f() } 
});

sub add_callback (f) {
push @callback_list, f;
}

This allows to register a number of callbacks to $some_object using
a simple combinator.

The problem is that without writing the add_callback api we lose the
ability to modify this list, effectively forcing us to create an
api.

Perhaps a better approach is to create a callbackregistry class:

class CallbackRegistry {
has @callbacks;

method trigger {
for @callbacks - f { f() };
}

method make_meta_callback {
sub { self.trigger }; # interesting question here... 
can we close over lexical subs like self?
}
}

Then we make a callback registry, and do something like

$some_object.register_callback( $registry.make_meta_callback());

Essentially what this is doing is reimplementing the concepts of
closures in OO terms.

This layer could be removed by doing something like this:

# first we define the API of the closure
class ListOfCallbacksCallback isa Closure {
has @callbacks;
}


my @callbacks;
sub { @callbacks } but ListOfCallbacksCallback; # not quite sure of this

Essentially this would overload sub capture, and make it into a
constructor call of some sort. Variable renaming facilities would be
nice, but even just a capture containing the body and all the
closed over variables would be cool.

This keeps things concise and lightweight, but does add the ability
to inspect (via a well defined api) what a closure is encapsulating,
etc.

-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgpiHn7ODKbF4.pgp
Description: PGP signature


Re: beg for Bag

2006-11-30 Thread Jonathan Lang

TSa wrote:

Jonathan Lang wrote:
 Would (1,2,2,3,4,4) be a Seq or a Bag?

Comma constructs a Seq, of course.


The context of the question was that you provided the above as the
result of unioning two Seqs; as such, I was trying to find out whether
you meant that the union of two Seqs should be a Seq, or if that was
an unintended artifact of the way you said it.


  IMHO, the _only_ way this
 could work would be if it's a Bag: if it's a Seq, I see no way that
 one could resolve '(1,2,3) ∪ (3,1,2)'.

This is not any different from '3' + '4' resulting in numeric 7.
It is the operator that builds Bags from (1,2,3) and (3,1,2) and
then calculates the union.


IOW, you're going with the notion that Seqs should be treated like
Bags when you apply set operations to them - that is, the order of
their elements becomes irrelevant.


 Mind you, I'm still not sold on the idea of performing set operations
 on Seqs - it may be technically feasible to do so, but it strikes me
 as fundamentally unintuitive.

But you have no problem with doing numeric stuff? E.g. (1,2,3) + (3,4)
actually means +(1,2,3) + +(3,4) == 3 + 2 == 5.


I didn't say that.  For the record, I _do_ have a problem with saying
that '(1,2,3) + (3,4)' should be equivalent to '+(1,2,3) + +(3,4)'.
It's counter-DWIMish, and I'd rather see the compiler complain about
the former than to do the latter when that's not what I wanted.  As a
general rule of thumb, I do _not_ want data types being coerced behind
my back.  '3' + '4' producing 7 should be an exception to the rule,
not the basis for it; and the reason for the exception is that the
fact that '3' is supposed to mean the same as 3 is not very hard to
spot.  Stating that (1,2,3) is supposed to mean the same as 3 is
considerably more murky.


 I'm still bothered by the idea that you have to wrap _every_ ASCII
 representative of a set operation in parentheses - something which is
 only necessary when you start applying the full range of set
 operations to non-Set entities.  In particular, I want 'Set - Set' to
 produce the difference of the two Sets.

But that should be the numeric difference of the cardinalities of the
Sets. Plain - means numeric. It's the same thing that we don't do string
concatenation with + but have a stringish ~ for the task. Hence it works
to say 3 ~ 4 and end up with '34'.


Plain '-' means numeric when the terms are scalars - and possibly not
even then.  Perl 6 allows for operator overloading, and it does so
because sometimes it makes more sense to have the same operator mean
different things depending on what it's operating on.  The interplay
between Strings and Nums shouldn't be taken as indicative of how
everything should work.


 If set operations also apply to Seq, then (=) is not the same as ===.
 The former ignores the order of the terms; the latter only does so for
 Sets and Bags.  In a way, this is what started the whole debate.

You are correct. This emphasizes the need for (=).


...or for allowing explicit conversion of Seqs to Bags or Sets, and
demanding that it be done before set operations are permitted.


Note that $a (-) $b is equivalent to $a () (!)$b, you have it as the
union. Or did you mean $a (|) (!)$b === (!)($b (-) $a)?


No, I goofed and meant A ⋂ !B when I said A ∪ !B.


Hmm, how is Bag complement defined in the first place? Is it just
complementing the set and goes for multiplicities of 1?


Conceptually, it would be going for multiplicities of Inf.  Even if
you define Set complement, you probably don't want to define Bag
complement.

--
Jonathan Dataweaver Lang


Re: Interrogating closures

2006-11-30 Thread Larry Wall
If I follow what you're saying (and this is by no means a certainty :)
I would tend to look more for a declarative solution than a callback
solution, so I'm imagining that any closure could have a declarator
that explicitly captures an outside lexical and makes it available
as an attribute.  I don't quite want to use has though, but it
something possessive.

my $x = 42;
f := sub {
have $.x;
say $x;
...
}
say f.x;

Here I'm using the plural possesive to indicate that $x is shared, in
the same sense that our is indicating something that's shared, only
in this case it's a shared lexical rather than a shared package variable.

Then you'd just use some variant of ordinary introspection to find
these methods.

But I've probably missed your meta-point entirely...

Larry


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

2006-11-30 Thread Larry Wall
On Thu, Nov 30, 2006 at 09:43:40AM +0100, TSa wrote:
: HaloO,
: 
: [EMAIL PROTECTED] wrote:
: $_  $xType of Match ImpliedMatching Code
: ==  = ==
: +   Set Set   members identicalmatch if $_ === $x
:  +   Array   Set   array equivalent to set  match if Set($_) === $x
: 
: Isn't it better to define these in terms of Bags? I mean with
: Bag a supertype of Set the dispatch should go to cases 
: infix===:(Bag,Bag), infix===:(Bag,Set), infix===:(Set,Bag)
: and infix===:(Set,Set).

I think that most Perl programmers would rather view Sets and Bags through
the Hash lens, so I think I'm going to try to avoid mentioning Sets and Bags
in the smartmatching table entirely, and only differentiate KeyHash, if
we differentiate anything.  In this view all of Set, Bag, KeySet and KeyBag
are really KeyHash, which is a Hash that is being used primarily for its
keys.  Set and Bag just happen to be constant values of KeySet and KeyBag
that also happen to override === and .WHICH to provide value rather
than object semantics.

I think a consequence of this view is that (x) ops are all key-based set
ops unless you explicitly make sure both sides are bags.  But it's still
early enough in the morning that I've not thought this through entirely...

What I do know this early is that we can't turn the hardwired
smartmatch table into a complete crossbar of every type combination
we can think up now and in the future.  For learnability we've got
to keep it linear somehow.  That's my main motivation for trying to
smash Set and Bag into being variants of the Hash role.

Larry