RFC: general feedback on module port

2005-03-10 Thread Darren Duncan
If any of you are willing, I would appreciate any general feedback on 
my first complete module port to Perl 6, including test suite, 
particularly if any parts don't look like proper Perl 6.

I haven't tried executing it yet, since Pugs lacks some features. 
But it will be easier on them if what they try to execute is correct 
in the first place.

I am referring to any file in the Pugs version control under this directory:
/modules/Locale-KeyedText
You can browse the whole Pugs source tree on the web here:
http://rt.openfoundry.org/Foundry/Project/Source/index.html/pugs/browse/
Alternately, the core module itself is visible here:
http://rt.openfoundry.org/Foundry/Project/Source/index.html/pugs/checkout/modules/Locale-KeyedText/lib/Locale/KeyedText.pm
I have already applied or considered everything said on this list in 
answer to my questions.

On a side note, I also decided to apply one of Larry's style 
preferences to all of my Perl 5 modules (and the above Perl 6 
module), which is to not use parenthesis with 'return'.

I will start porting another module that is about 25 times larger in 
a week or two; any feedback I get meanwhile may also aid that task 
being done correctly.

Thanks to the rest of you who are working on driving Perl 6 in some 
fashion; we're much better off for your contributions.

Have a good day. -- Darren Duncan


Re: MMD as an object.

2005-03-10 Thread Miroslav Silovic
[EMAIL PROTECTED] wrote:
It would behave like a tied sub (or method), with a .dispatch method 
to decide which of the contained routines should be called this 
particular time. Manhattan would be the default. However, one can 
override the dispatch logic; implementing Luke's Patterns idea, for 
example.

Hmm, that ties into my wishlist item. Would it be possible to implement 
method combinators (or rather, multimethod combinators) from Common LISP 
in addition to this? The only CLOS feature that A12 doesn't mention, 
can't let that happen. ;)

class A { ... }
class B is A { ... }
1 multi foo ($a) is before { ... }
2 multi foo (B $a) { ... next METHOD; ...}
3 multi foo (A $a) { ... }
4 multi foo ($a) is after { ... }
5 multi foo ($a) is around { ... next METHOD; }
6 multi foo ($a) is before { ... }
 and this runs all 5 methods, in order 5  1  2  6  3  (returns 
to 2)  4  (returns to 5)
And yes, 6 and 1 do have the same signature. The rule is to run all 
before methods in order of the currently selected distance (ties broken 
in random order ;) ), and all after methods in the reverse order.

Oh, and the reason why around methods are useful?
multi foo ($a) is around {
   CATCH { ... }
   next METHOD;
}
Note that this catches the exceptions thrown by any version of foo, even 
though at this point you don't know whether foo will be specialised. 
before methods aren't useful for this since their stack frame and 
handler blocks don't linger during the executions of other methods.

Common LISP references:
Standard method combination (before, after, around)
http://www.lispworks.com/documentation/HyperSpec/Body/07_ffb.htm
Other method combinations (+, and, etc)
http://www.lispworks.com/documentation/HyperSpec/Body/07_ffd.htm
Creating your own method combinations (define-method-combination)
http://www.lispworks.com/documentation/HyperSpec/Body/m_defi_4.htm
Come to think of this, it seems that the only thing that'd need to be 
modified to accomodate both Rod's and mine proposal is to move CALLONE 
and CALLALL from the class to be MMD object somehow. Perhaps

multi CALLONE ($obj, $method where { $_ == func }, [EMAIL PROTECTED]) { ... }
Hmm, but this syntax strikes me as icky.
   Miro


Re: MMD as an object.

2005-03-10 Thread Leopold Toetsch
Rod Adams [EMAIL PROTECTED] wrote:
 It seems to me that there are several advantages to making a group of
 multi with the same short name a single object, of type
 MultiSub|MultiMethod, which internally holds references to the all the
 various routines that share that short name.

Discussion seems to have went off into esoteric cases of locally
overriden dispatcher policies and what not.

What I'd like to know is more basic things:

1) is there a MultiSub object with one short name that holds all
possible long names (and function references)?
If yes, who is creating it: the Perl6 compiler emits code to do so or
it's up to Parrot to do the right thing?

2) namespaces of (multi) subs.

A non-multi method is in the classes' namespace. In Parrot terms that's
currently:

  %globals{\0class_name}{method_name}

I'm not quite sure, if the method hash shouldn't live inside the class.

A multi method is similar, except that their can be more then one
with the same short name (which probably means that there has to be a
MultiSub object holding the long names)

What about multi subs? They can be defined everywhere. Given:

  multi sub *foo(A $a, B $b) {...}

Is this something like:

  %globals{foo}  --  MultiSub{foo_A_B = Sub, ...}

What about a not so global multi:

  multi sub foo(A $a, B $b) {...}

Thanks for clarifying,
leo


Re: MMD as an object.

2005-03-10 Thread David Storrs
On Wed, Mar 09, 2005 at 03:38:52PM -0600, Rod Adams wrote:

 There lingers the case of:
   
use Foo; # from above, exports bar is MMD::Random
 
multi sub bar {...}
 
 Does this generate an error, since one could expect this particular bar 
 to be Manhattan? Or does it assume Random, since there's already a bar 
 in existence? In my head, it currently makes sense to say that the new 
 bar inherits the Random policy. Only something like:

This seems like action-at-a-distance to me; I use some random module,
define a couple of multis without realizing that they also exist in
the module, and am baffled as to why I don't get the dispatch behavior
I expect.

--Dks


Re: some misc Perl 6 questions

2005-03-10 Thread Thomas Sandlaß
Larry Wall wrote:
That's...sick...  I love it.  *Please* don't tell Damian.
whisper
Well there are some people who consider it quite sane :)
http://www.cduce.org/papers/icalp04.pdf
Abstract:
This paper studies the problem of matching sequences against
regular expressions in order to produce structured values.
To me handling XML data is an area where Perl 6 could|should|will excel!
I think Perl 5 already does.
/whisper
MfG
--
TSa (Thomas Sandlaß)



Junctions - feedback and desires

2005-03-10 Thread Terrence Brannon
I gave a talk on Perl 6 Junctions at the Thousand Oaks Perl Mongers
meeting last night

   http://www.hcoop.net/~terry/perl/talks/p6-junctions/index.html 
 
and two questions/desires came out of it: 
 
1: will it be possible to know which element of a junction is 
currently being used? E.g.: 
 
my @first_set = qw(1 1); 
my @new_set = qw(1 1.4 1 1 8 1 1 1 0.8); 
 
my $any_new_set = any(@new_set); 
my $any_first_set = any(@first_set); 
 
if ( (abs($any_first_set - $any_new_set))  0.5) { 
  a variation in the readings is too large.say; 
  printf we we examining %d and %d when it happened, 
  $any_new_set.current, $any_first_set.current ; # desired feature
  
} 
 
2: Unless the array of values can be specified lazily, it will not be 
practical to use Perl 6 Junctions on large datasets. For example  I
might like to be able to specify a sub ref/closure whose execution yields a
new array value or undef when no more values. I.e.:

sub mynext {
my($age) = $sth-fetchrow_array;
$age
}

my $junction = any(\mynext) ;

3: Do junctions short circuit? I.e., whenever the condition is met,
does it continue immediately. Using the example from point #1, can we assume
that the body of the then branch will fire when 8 of @new_set is
encountered?


Re: MMD as an object.

2005-03-10 Thread Miroslav Silovic
[EMAIL PROTECTED] wrote:
What about multi subs? They can be defined everywhere. Given:
 multi sub *foo(A $a, B $b) {...}
Is this something like:
 %globals{foo}  --  MultiSub{foo_A_B = Sub, ...}
What about a not so global multi:
 multi sub foo(A $a, B $b) {...}
Thanks for clarifying,
leo
 

Uh, the real problem is the interaction between multisubs and modules. 
If you import a multi with the same short name from another module, you 
get a real issue that needs resolving. Especially if they do 
fundamentally different things and you don't expect a clash. Like

module Users;
multi get(Stream $f, UserDescriptor $u) {...}
...
module FileTransfer;
multi get(Server $s, File $f) {...}
Even if this is easy to fix by renaming, the error message would take a 
while to track down and it'd be annoying distraction during development. 
I believe the DWIM thing to do would be to merge multis into the same 
MMD object on module load. This would have to happen during runtime, 
since that's when the module load can occur.

   Miro


Re: Adding linear interpolation to an array

2005-03-10 Thread Thomas Sandlaß
HaloO Luke,
you wrote:
The words 'covariant' and 'contravariant' in this context seem like
voodoo math.  Please explain what you mean.
'Co' means together like in coproduction. And 'contra' is the opposite
as in counterproductive. With instanciating parametric types the question
arises how a subtype relation between instanciating types propagates
to the template. E.g with Int : Num, covariance would result in
Array[Int] : Array[Num]. Referential classes are actually quite difficult
because upon write they are contravariant and covariant when read!
So a third case of uncomparable types is needed as well, or it is the default
if nothing else is specified.

That's not true.  I don't believe it would be an error to specify
all nine combinations.
Ohh, sorry. Of course implementing all is fine as well. But a bit
tedious for larger collections of classes.
MfG
--
TSa (Thomas Sandla)



Re: Adding linear interpolation to an array

2005-03-10 Thread Michele Dondi
On Thu, 10 Mar 2005, [UTF-8] Thomas Sandla~_ wrote:
'Co' means together like in coproduction. And 'contra' is the opposite
  
  
'Streaming of digestive byproducts'? ;-)
Sorry for the OT - couldn't resist! This pun first occurred to me wrt 
(cathegorical) coproducts...

Michele
--
SILVIO CLEPTOMANE
- Scritta su un muro,
  Via F. Sforza, Milano

Re: Adding linear interpolation to an array

2005-03-10 Thread Doug McNutt
At 17:53 +0100 3/10/05, Thomas Sandlaß wrote:
'Co' means together like in coproduction. And 'contra' is the opposite
as in counterproductive. With instanciating parametric types the question
arises how a subtype relation between instanciating types propagates
to the template. E.g with Int : Num, covariance would result in
Array[Int] : Array[Num]. Referential classes are actually quite difficult
because upon write they are contravariant and covariant when read!
So a third case of uncomparable types is needed as well, or it is the default
if nothing else is specified.

A word of caution:

Just as in  vector operators had their names changed to pacify the 
mathematicians - thank you - there is a conflict in terms. Covariant and 
contravariant tensors are the meat of Einstein's  formulation of relativity. It 
all has to do with transformations being in the same direction or the opposite 
direction as the coordinate differentials. Perhaps there is some similarity.

Einstein's presentation is a whole lot easier to understand than the one above.

--
-- Marriage and kilo are troubled words. Turmoil results when centuries-old 
usage is altered in specialized jargon --.


Re: Adding linear interpolation to an array

2005-03-10 Thread David Storrs
 At 17:53 +0100 3/10/05, Thomas Sandlaß wrote:
[request for clarification of 'covariant' and 'contravariant' usage]
 'Co' means together like in coproduction. And 'contra' is the opposite
 as in counterproductive. With instanciating parametric types the question
 arises how a subtype relation between instanciating types propagates
 to the template. E.g with Int : Num, covariance would result in
 Array[Int] : Array[Num]. Referential classes are actually quite difficult
 because upon write they are contravariant and covariant when read!
 So a third case of uncomparable types is needed as well, or it is the default
 if nothing else is specified.

Thomas,

I appreciate you attempting to explain this, but it remains clear as
mud, at least to me.  Could you please try again, using very short,
very non-technical words and not assuming a mathematical or
scientific background on the part of your reader?

Something that would help: We could all look the words up in a
dictionary, so we don't need a definition.  What we need is a
clarification, in simple terms, of what *you* mean by them, in this
context. 

Thank you.

--Dks


Re: Junctions - feedback and desires

2005-03-10 Thread Rod Adams
Terrence Brannon wrote:
I gave a talk on Perl 6 Junctions at the Thousand Oaks Perl Mongers
meeting last night
  http://www.hcoop.net/~terry/perl/talks/p6-junctions/index.html 

and two questions/desires came out of it: 

1: will it be possible to know which element of a junction is 
currently being used? E.g.: 

my @first_set = qw(1 1); 
my @new_set = qw(1 1.4 1 1 8 1 1 1 0.8); 

my $any_new_set = any(@new_set); 
my $any_first_set = any(@first_set); 

if ( (abs($any_first_set - $any_new_set))  0.5) { 
 a variation in the readings is too large.say; 
 printf we we examining %d and %d when it happened, 
 $any_new_set.current, $any_first_set.current ; # desired feature
 
}

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.

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.
As for the current value, there is only a current value during 
threading. In this example, the threading is fully contained in C 
(abs($any_first_set - $any_new_set))  0.5 . By the time the printf 
comes, the threading is long past.

If you wish to change the behavior, you're welcome to put out some 
proposals. But I'll warn you from experience that Damian is rather 
stubborn about the current behavior. =)

 
2: Unless the array of values can be specified lazily, it will not be 
practical to use Perl 6 Junctions on large datasets. For example  I
might like to be able to specify a sub ref/closure whose execution yields a
new array value or undef when no more values. I.e.:

sub mynext {
   my($age) = $sth-fetchrow_array;
   $age
}
my $junction = any(\mynext) ;
 

You now have a junction whose only value is a coderef.
I do not believe that you can create a 'lazy junction'. But I don't 
recall the topic coming up before, so we'll have to wait for Damian to 
come back unless someone else knows for certain.

3: Do junctions short circuit? I.e., whenever the condition is met,
does it continue immediately. Using the example from point #1, can we assume
that the body of the then branch will fire when 8 of @new_set is
encountered?
 

Yes, they short circuit.
However, your second statement might be a bit misleading. When the 8 is 
encountered, the evaluation of the junctions terminates, and then 
processing moves on to the next statement, in this case the say. What 
you said might be construed as the junctions were still being threaded 
when the the say and printf occurred.

HTH,
-- Rod Adams


Re: MMD as an object.

2005-03-10 Thread Rod Adams
David Storrs wrote:
On Wed, Mar 09, 2005 at 03:38:52PM -0600, Rod Adams wrote:
 

There lingers the case of:
 
  use Foo; # from above, exports bar is MMD::Random

  multi sub bar {...}
Does this generate an error, since one could expect this particular bar 
to be Manhattan? Or does it assume Random, since there's already a bar 
in existence? In my head, it currently makes sense to say that the new 
bar inherits the Random policy. Only something like:
   

This seems like action-at-a-distance to me; I use some random module,
define a couple of multis without realizing that they also exist in
the module, and am baffled as to why I don't get the dispatch behavior
I expect.
 

Well, if you were not expecting Foo to export some bar's, then you're 
in for a surprise regardless of dispatch when you call bar in your code 
and one of Foo::bar gets called instead of one of yours, because it was 
a closer match.

I would say that people should know what they are getting into when they 
C use  something. In Perl 6, that use could conviently swap the 
meanings of all the + and - signs, and not say a word. In my head, this 
extends to knowing what it exports, and if there's anything weird about it.

If I am consciously adding more multi's into something a package 
provided, to extend it's functionality, I would think that keeping the 
original dispatch system would make sense. Otherwise  the imported 
methods could fail to work properly.

-- Rod Adams



sub and method name overlap.

2005-03-10 Thread Rod Adams
Given:
   class Foo {
  method Bar () {...};
   }
   sub Bar (Any $x) {...};
   my Foo $f;
   Bar $f;
Is that last line the same as:
   Bar.($f);
or
   $f.Bar;
Does it matter if we change C sub Bar  to C multi sub Bar ?
Is there some form of implicit multi sub that gets created to make C 
Bar $f;  C $f.Bar ? Or does it only work if there is no C multi? sub 
bar  in sight?

-- Rod Adams


Re: MMD as an object.

2005-03-10 Thread Rod Adams
Leopold Toetsch wrote:
Rod Adams [EMAIL PROTECTED] wrote:
 

It seems to me that there are several advantages to making a group of
multi with the same short name a single object, of type
MultiSub|MultiMethod, which internally holds references to the all the
various routines that share that short name.
   

Discussion seems to have went off into esoteric cases of locally
overriden dispatcher policies and what not.
 

I don't think it's as esoteric as you might think. Consider:
   package Foo;
   use MMD::Random;
   our bar is MMD::Random is export(DEFAULT);
   multi sub bar ($x) {...};
   multi sub bar ($x) {...};
   multi sub bar ($x) {...};
 
   ==

   use Foo;
  
   multi sub bar ($x) {...};

Note that they all have the same signature. The Manhattan policy would 
complain about this, since it's looking for the closest parameter match. 
The Random policy does not care. It's going to randomly pick any member 
method for each call.

So what we then fall into is the problem of which policy is in effect 
for a given multi can affect what's in scope at a given point. If the 
later file included:

   sub baz {
 my multi sub bar ($x) {...};
 bar(5);
   }
A Manhattan policy would have the local bar mask the package bar with 
the same signature. A Random policy would temporarily add it into the mix.

Since the main goal of treating multis as an object was to be able to 
override the dispatch policy, I think how a user defined policy 
interacts with different localities is very much on topic.

What I'd like to know is more basic things:
1) is there a MultiSub object with one short name that holds all
possible long names (and function references)?
 

As for whether such a thing is visible at the Perl level, I think that 
depends on if we allow user defined dispatch policies or not. If not, 
it's just an introspection tool that could be addressed in other ways.

Even without custom policies, p6c may decide to go the MultiSub object 
route at the compiler level. But I can't speak to that, nor on the 
Compiler - Parrot interaction.

What about multi subs? They can be defined everywhere. Given:
 multi sub *foo(A $a, B $b) {...}
Is this something like:
 %globals{foo}  --  MultiSub{foo_A_B = Sub, ...}
What about a not so global multi:
 multi sub foo(A $a, B $b) {...}
 

This can be seen as questioning how to keep track of what multi's are in 
scope at any given point in time, because you must dispatch amongst all 
the multi's visible, regardless of the differing scope.  Method dispatch 
has a similar issue with hunting down all the C isa s for possible 
method's to include in dispatch. So far, I think this issue has been 
politely ignored as p6c's problem, not p6l's.

However if you have multi's from a mix of different sources and scopes, 
all with the same short name, which policy decides how to dispatch 
amongst them at a given calling locality is very much at issue, and is 
roughly where we are in the discussion.

Thanks for clarifying,
 

Sorry I couldn't clarify more.
-- Rod Adams


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)


Re: Junctions - feedback and desires

2005-03-10 Thread Dave Whipp
Rod Adams wrote:
I do not believe that you can create a 'lazy junction'. But I don't 
recall the topic coming up before, so we'll have to wait for Damian to 
come back unless someone else knows for certain.
My understanding is that all lists are conceptually lazy. any(2..Inf) 
is perfectly valid.


Re: Junctions - feedback and desires

2005-03-10 Thread Rod Adams
Sam Vilain wrote:
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]).
I'm not disputing that it would be powerful. I'm simply saying that as 
currently defined, junctions do not behave in this fashion. It also does 
not make a lot of sense to filter out restricting values in a none() 
junction.

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.


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].
because it gets interpreted as:
   10  $j  1
   -- (10  $j)  ($j  1)
   -- (10  any(0, 11))  (any(0, 11)  1)
   -- any(10  0, 10  11)  any(0  1, 11  1)
   -- any(false, true)  any(true, false)
   -- true  true
   -- true.
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;
}
}
The Csay would occur, even with the first condition as C $j  10 , 
as you likely intended it to be.
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.

If instead I had said:
   $j = 11  0;
   10  $j  1
it would be false, because C all( true, false)  is false.
$j itself never changes. It is always a collection of values with a 
predicate. If you wish to have a junction with different values in it, 
you have to create a new one.

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.
Except that the threadings are indendent of each other.
   $j = any(0,11);
   $j != $j;
is true.
   $j != $j
   -- any(0,11) != any(0,11)
   -- any(0 != any(0,11), 11 != any(0,11))
   -- any(any(0 != 0, 0 != 11), any(11 != 0, 11 != 11))
   -- any(any(false, true), any(true, false))
   -- any(true, true)
   -- true
Similarly:
  
   $j = all(0,11);
   $j == $j;

is false.
It is by this assumption that the example in [3] was built.
That assumption is in err, and the example does not generate the 
solutions desired
See my response to it in  
http://www.nntp.perl.org/group/perl.perl6.language/19428

But wait, isn't (10  $j  1) likely to produce the same opcode tree
as if($j10){if($j1){}} ?
Well
   if 10  $j  1 { ... }
   if 10  $j { if $j  1 { ... }}
Could easily wind up with the same opcodes. Unless the optimizer saw 
something in the first one where it could prove C $j  1  is false.

 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?
The optimizer can skip threading over values that it can prove will not 
affect the outcome. That's short circuiting.

But asking the optimizer to know in advance what is absurd is a tall order.
Even without junctions, someone could make $j an object with an 
overloaded set of compare operators against Num. And there's no way for 
the compiler to know if those operators are consistent and transitive. 
(One could hope they were, but you never know).

I would not call the threading conceptual. It's a very real thing.
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.
In the cases above, the routine being threaded over is the comparison 
operator, not the surrounding code block that contains it.

-- Rod Adams


Re: Junctions - feedback and desires

2005-03-10 Thread Rod Adams
Dave Whipp wrote:
Rod Adams wrote:
I do not believe that you can create a 'lazy junction'. But I don't 
recall the topic coming up before, so we'll have to wait for Damian 
to come back unless someone else knows for certain.

My understanding is that all lists are conceptually lazy. 
any(2..Inf) is perfectly valid.


The list being fed into the junction can be lazy. But I believe that the 
list gets iterated over completely in the creation of the junction, so 
C any(2..Inf)  is valid, but melts your processor similar to C sort 
2..Inf .

My impression has been that after the creation of a junction, the values 
that junction has are set in stone. Allowing some form of lazy list to 
add values at will seems a bit counter to me. But if @Cabal think it's 
okay to have lazy junctions, I won't argue with them.

-- Rod Adams


Re: Junctions - feedback and desires

2005-03-10 Thread Uri Guttman
 RA == Rod Adams [EMAIL PROTECTED] writes:

   
   My understanding is that all lists are conceptually
   lazy. any(2..Inf) is perfectly valid.
   
   
  RA The list being fed into the junction can be lazy. But I believe that
  RA the list gets iterated over completely in the creation of the
  RA junction, so C any(2..Inf)  is valid, but melts your processor
  RA similar to C sort 2..Inf .

i was under the impression that junctions could be smart about ranges
like that and do it correctly. sort can't possibly handle that but some
junctions and ranges would work fine. it isn't hard to convert that
(with the proper boolean) to a boolean expression internally.

  RA My impression has been that after the creation of a junction, the
  RA values that junction has are set in stone. Allowing some form of lazy
  RA list to add values at will seems a bit counter to me. But if @Cabal
  RA think it's okay to have lazy junctions, I won't argue with them.

lazy only when you can actually cheat IMO.

uri

-- 
Uri Guttman  --  [EMAIL PROTECTED]   http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs    http://jobs.perl.org


Re: MMD as an object.

2005-03-10 Thread David Storrs
On Thu, Mar 10, 2005 at 02:22:20PM -0600, Rod Adams wrote:
 David Storrs wrote:
 On Wed, Mar 09, 2005 at 03:38:52PM -0600, Rod Adams wrote:
   use Foo; # from above, exports bar is MMD::Random
   multi sub bar {...}
 
 Does this generate an error, since one could expect this particular bar 
 to be Manhattan? Or does it assume Random, since there's already a bar 
 in existence? 
 
 This seems like action-at-a-distance to me; 
 
 Well, if you were not expecting Foo to export some bar's, then you're 
 in for a surprise regardless of dispatch when you call bar in your code 
 and one of Foo::bar gets called instead of one of yours, because it was 
 a closer match.
 
 I would say that people should know what they are getting into when they 
 C use  something. 


What I'm hearing you say here is Yes, it's action-at-a-distance, but
it's your job to make sure it doesn't trip you up.  The problem that
I see is that I may well be able to keep track of everything from the
modules I import, but what about the ones THEY import...and the ones
THEY import...and so on.  In a medium-to-large software project, that
can get to be a lot of modules, very quickly.

--Dks


Re: sub and method name overlap.

2005-03-10 Thread Jonathan Scott Duff
On Thu, Mar 10, 2005 at 03:27:23PM -0600, Rod Adams wrote:
 Given:
 
class Foo {
   method Bar () {...};
}
 
sub Bar (Any $x) {...};
my Foo $f;
 
Bar $f;
 
 
 Is that last line the same as:
Bar.($f);
 or
$f.Bar;

I don't see how it can be anything but the former.  As I understand
things, when searching for a matching sub/method, the subs are
given preference over indirect objects.

 Does it matter if we change C sub Bar  to C multi sub Bar ?

Nope.

 Is there some form of implicit multi sub that gets created to make C 
 Bar $f;  C $f.Bar ? 

I don't think so.

 Or does it only work if there is no C multi? sub bar  in sight?

That's how I see (no sub or multi in sight)

You can always be explicit if you really want to use the IO notation:

Bar $f:;

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Junctions - feedback and desires

2005-03-10 Thread Luke Palmer
Rod Adams writes:
 Dave Whipp wrote:
 
 Rod Adams wrote:
 
 I do not believe that you can create a 'lazy junction'. But I don't 
 recall the topic coming up before, so we'll have to wait for Damian 
 to come back unless someone else knows for certain.
 
 
 My understanding is that all lists are conceptually lazy. 
 any(2..Inf) is perfectly valid.
 
 
 The list being fed into the junction can be lazy. But I believe that
 the list gets iterated over completely in the creation of the
 junction, so C any(2..Inf)  is valid, but melts your processor
 similar to C sort 2..Inf .

Well, if we guarantee that .states never returns two of the same value,
then of course you can not call .states on an infinite junction.

And indeed, while it's possible to do this (taking the range to be an
arbitrary infinite list):

if any(2...)  100 {...}

You'll melt if you do this:

if any(2...)  2 {...}

We could make junctions smart about ranges, so that the latter can just
fail, but I argue that we can only do it well in the simplest of cases.
It's probably better not to allow infinite ranges in junctions.

On the other hand, if we give junctions well-defined semantics in terms
of their underlying lists (such as orderedness), then lazy junctions may
be just fine.  There's a lot you can do with lazy lists, and there are a
lot of very nice idioms having to do with junctions, and I'd like to
find a way to make those two things not be mutually exclusive.

Luke


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.