Re: Demagicalizing pairs

2005-09-20 Thread TSa

HaloO,

Luke Palmer wrote:

The whole point was to deautomatize it!  However, here's an
interesting solution:  pairs are scanned for *syntactically* *on the
top level* of a function call (allowing named() or however we spell it
as a fallback when we want to be dynamic).  However, :foo(bar) and foo
= bar are equivalent again.

foo $x, $y;   # two positionals, regardless of what they contain
foo $x, :y($y)# a positional and a named
foo $x, y = $y   # a positional and a named
foo $x, (y = $y) # two positionals: $x and the pair y = $y
foo $x, (:y($y))  # same

In the fourth example, y = $y is no longer on the syntactic top
level, so it is not interpreted as a named argument.


Isn't that a task for the itemizer? I mean

  foo $x, [y = $y]  # syntactic arg type = (Item,Item)
 # but staticarg type = (Item,Pair)
  foo $x, [:y($y)]   # same

compared to

  foo $x, y = $y# syntactic arg type = (Item,Pair)
 # and staticarg type = (Item,Pair)
  foo $x, (y = $y)  # same because () only groups for changed precedence



I hate to say it, but the named args should probably be marked
with : instead of + in the signature.



That's pretty cool.  Can't say I like the secondary sigil: it's really
not marking a property of the variable, but a property of the
parameter list.  That information should probably be kept inside the
parameter list alone.


I have changed my mind on $.foo and $:foo because these forms just lack
some identifyer chars between the two sigils $what.foo and $what:foo where
now $what indicates an item and .foo a method on it. Well, and :foo
indicates a keyed access on $what, but that isn't currently specced, right?
So what does 'what' default to in $.foo and $:foo? I think it simply is
'?SELF' and the twigil syntax gives a compile error if $?SELF is unbound.

The other two twigil combinations .$foo and :$foo in that logic would be
a method ref and a key ref respectively and as such both need something
on their left side. If that happens to be a bare word as in

   blahh :$foo;

my interpretation is that first of all the symbol lookup for blahh has to
yield a sub. Since it's not sigiled blahh it is a not yet invoked sub
invocation---to me this is not weirder than an unthrown exception---and
$foo has to contain a pair that is bound by name in the pending blahh
invocation. In other words it's a parametric, named parameter. BTW, if
you want the same through a sub call I would write it as

  blahh :foo();

See also my 'syntactic, static and dynamic type' mail. The forms

  blahh .$foo;
  blahh .foo();

require blahh to be callable without params and return a suitable
invocant type for the method referenced by $foo and returned by
calling the sub foo respectively. This (il)logic can be applied
to other twigil combinations as well:

  blahh [EMAIL PROTECTED]; # call on blahh ret val through method ref from 
@foo[42]
  blahh :%foosome_pair # call blahh with named param from %foosome_pair

All of these forms fail at runtime if e.g. @foo[42] doesn't yield a method
ref and even if it does the dispatch on the retval of blahh might fail. The
compiler could also warn or give errors if the invocations can be proven
to fail from the static type information, e.g.

  my Int @foo;

  blahh [EMAIL PROTECTED];  # Int not a Method subtype


Hmm, and if you mentally unify sub and class you get the idea that
$?SELF is bound to the current invocation err instance of the sub
and as such is amenable to the $:foo syntax for replacing placeholder
variables. That means

{ $:y  $:z  $:x != 2 }

is a shorthand for

sub ($x,$y,$z) { $y  $z  $x != 2 }

and hints at the possibility for writing sub definitions as

sub foo:(Item,Item,Item -- bool)
{
has $x; # first,
has $y; # second,
has $z; # and third Item

has $:trace;

if defined $:trace { say $:trace }

return $y  $z  $x != 2;
}

and call them as usual

   foo 1,2,3;  # no trace

   foo 1,2,3, trace = 'should be false';

   foo:traceshould be false 1,2,3; # same

   foo 1,2,3, :trace($count++);

   foo 1,2,3, :$count++;  # works?

and curry them with slot assignment

   my foo ::= OUTER::foo:tracefoo called;

   foo 1,2,3; # prints traces
--
$TSa.greeting := HaloO; # mind the echo!


Re: \(...)?

2005-09-20 Thread TSa

HaloO chromatic,

you wrote:

On Mon, 2005-09-19 at 13:01 +0200, TSa wrote:



Why shouldn't there be a lvalue traversal that
in the end makes

  ($x, $y) = \($a, $b);

actually mean

  $x = \$a; $y = \$b;



Does this not go from one sequence point (evaluate the rhs sufficiently,
then perform the lvalue assignments) to multiple sequence points?  I'm
not sure you can always reason effectively about the lack of side
effects here.


I think you are right. I just used the two forms to illustrate my idea.
But since the default list is lazy while item evaluation is eager my
first case should probably be written as

  **($x, $y) = \**($a,$b);

and even then might not give the interleaved execution sequence:

  1: $x  as lvalue
  2: \$a as rvalue
  3: $y  as lvalue
  4: \$b as rvalue

but 1,3,2,4. OTOH, it is the programmer's choice. The only thing that
he should be aware of is how much undeterminsm is in which alternative.

And I wonder if

  [=] **zip( $x, $y ; \($a,$b) );

results in the 1,2,3,4 sequence deterministically.
--
$TSa.greeting := HaloO; # mind the echo!


Re: \(...)?

2005-09-20 Thread TSa

HaloO Juerd,

you wrote:

Does the type List exist? What is it? How does it fit in the
hierarchy?


I've put it below Sub in my type lattice. But that is not official,
of course.



In list context, comma provides list context to LHS and RHS, and those
lists together are flattened. (It's not exactly binary, but it doesn't
hurt to explain it as such.)

In scalar context, commas provide scalar context to the expressions they
separate (or list context? If so, what to do with parenthesized
expressions?), and the entire thing is returned as a reference to a
newly created array (of aliases, perhaps).

What it does in void context is unimportant, but it would make sense if
it provided void context to each of the expressions.

Comma doesn't build a list. Lists can only exist in list context, and
in fact, it's a list even without any comma:


Please help me to understand how the context starts to exist.
I currently see a circular definition of comma and list context
in your explaination. I for my part try to break it with the
strict notion: when you see a comma you are looking at a list.
What list is up to more text to the left and right of the comma.
And I believe the parser essentially does the same.



my @foo = bar();  # here, what bar returns is a list, without any
  # comma.


That @foo is of syntactic type Array is clear. That bar is called
without parameters is obvious as well. But where do you derive the
the return type from? That could at most come from type information
of bar e.g. :( Void -- Blubber) and then the question arises if
a Blubber is assignable to an Array or not. Well, or if a Blubber
can listify. Or as a fall-back itemize with the item beeing trivially
listified as a one element list which then ends up providing the sole
content of the @foo.



 \($x,$y);  # same as \ .($x,$y)



This would mean that \ is a function rather than a standard \W operator,
and that the parens here aren't the normal grouping parens, but instead
parens to enclose arguments. If this is the case, I suggest we rename \
to something that actually LOOKS like a function, that is: something
with a \w+ name. This all would imply that its precedence is lower than
comma.


Ups, I always thought that this is what all the operator categories
and related things are for: to get an easy way to define operators!
E.g. after

  my foo ::= prefix:\;

enreferencing should work with

  ($x,$y) = foo($a,$b);

or not?
--
$TSa.greeting := HaloO; # mind the echo!


conditional wrapper blocks

2005-09-20 Thread Yuval Kogman
Today on #perl6 I complained about the fact that this is always
inelegant:

if ($condition) { pre }

unconditional midsection;

if ($condition) { post }

Either you put the condition in a boolean var and check it twice, or
you use a higher order function and give it three blocks, and the
conditional. But no matter how much we try, it always feels too
manual.

I asked for some ideas and together with Aankhen we converged on the
following syntax:

if ($condition) {
pre;
} uncond {
middle;
} cond {
post;
}

s/uncond/pause regardless.pick/e;
s/cond/resume again.pick/e;

Some restrictions:

The block structure must always be ternary - for other cases we
already have enough control flow.

The if is not the same if that can cuddle with else - it's either
or.

Does anybody have any comments, or synonyms for the control
structure naming?

BTW, I expect readability to be optimal with 1-2 lines of pre/post,
and 1-5 lines of middle. Any observations?

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me groks YAML like the grasshopper: neeyah!!



pgpiJFUwn2ZnX.pgp
Description: PGP signature


Re: conditional wrapper blocks

2005-09-20 Thread Yuval Kogman
On Tue, Sep 20, 2005 at 18:19:42 +, [EMAIL PROTECTED] wrote:
 Some other possible problems:
 
 1: if $condition is an expression with side-effects then your new construct 
 has a different meaning then the original code.

If it has side effects then I always

my $bool =  test ... ;

if ($bool) { 
pre
}

mid

if ($bool) {
post
}

 2: if the middle part does something that changes the value of  the 
 expression $condition then the new construct again has a different meaning.

Err, that's the point


-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me sneaks up from another MIME part: neeyah!



pgpEnrEFRa2FL.pgp
Description: PGP signature


Re: conditional wrapper blocks

2005-09-20 Thread Matt Fowles
Yuval~

On 9/20/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 Today on #perl6 I complained about the fact that this is always
 inelegant:
 
 if ($condition) { pre }
 
 unconditional midsection;
 
 if ($condition) { post }
  
 I asked for some ideas and together with Aankhen we converged on the
 following syntax:
 
 if ($condition) {
 pre;
 } uncond {
 middle;
 } cond {
 post;
 }
 
 s/uncond/pause regardless.pick/e;
 s/cond/resume again.pick/e;
 
 Some restrictions:
 
 The block structure must always be ternary - for other cases we
 already have enough control flow.
 
 The if is not the same if that can cuddle with else - it's either
 or.
 
 Does anybody have any comments, or synonyms for the control
 structure naming?
 
 BTW, I expect readability to be optimal with 1-2 lines of pre/post,
 and 1-5 lines of middle. Any observations?

I don't really find this that inellegant.  It also seems like
something that is not painful enough to warrant adding new syntax,
especially a syntax that conflicts with if .. else ..

It seems like add complexity for very little win (granted it is not a
lot of added complexity, but perl6 is already an very large language).

Matt
-- 
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


Re: conditional wrapper blocks

2005-09-20 Thread Mark Reed
On 2005-09-20 14:23, Yuval Kogman [EMAIL PROTECTED] wrote:

 On Tue, Sep 20, 2005 at 18:19:42 +, [EMAIL PROTECTED] wrote:

 2: if the middle part does something that changes the value of  the
 expression $condition then the new construct again has a different meaning.
 
 Err, that's the point

Not necessarily.  Consider this common idiom (in pseudo-perl5):

foreach my $item (@menu)
{
print li\n;

if ($item is not the current page)
{
print qq|a href=${\($item-url)};
}

print $item-label;

if ($item is not the current page)
{
print /a;
}

print /li\n;
}

The middle unconditional part doesn't change anything; it's just that -
unconditional.  We want to do it every time regardless, but it's bracketed
by bits that always go together - we want to do either both or neither, but
never just one.





Re: conditional wrapper blocks

2005-09-20 Thread Yuval Kogman
On Tue, Sep 20, 2005 at 14:31:07 -0400, Mark Reed wrote:
 On 2005-09-20 14:23, Yuval Kogman [EMAIL PROTECTED] wrote:
  On Tue, Sep 20, 2005 at 18:19:42 +, [EMAIL PROTECTED] wrote:
 
  2: if the middle part does something that changes the value of  the
  expression $condition then the new construct again has a different meaning.
  
  Err, that's the point
 
 Not necessarily.  Consider this common idiom (in pseudo-perl5):

Actually we agree... I meant that the point is that the new
construct has a different meaning. =)

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me dodges cabbages like macalypse log N: neeyah!



pgp5uzfjZ8ixG.pgp
Description: PGP signature


Re: Lazy lists and optimizing for responsiveness

2005-09-20 Thread Austin Frank

TSa wrote:


IIRC, $Larry has mentioned a Pipe type which to me seems to be
just the generic type where you configure the buffer/queue size.
In multi-threaded (or connected processes) applications the buffer
size needs tuning to balance responsiveness with throughput. Thus
your gather proposal could just be a :buffer($size) adverb/trait
in the slurpy list declaration and some auto-threading behaviour
of the pipe operators == and ==.


Would the named adverbs for gather work in other contexts as well? 
Would you suggest this mechanism for specifying the buffering behavior 
for IO operations?


Tim Bray recently wrote about wanting a language that would be smarter 
about IO buffering by default.  Will perl6 be such a language?


From Radical New Language Idea 
(http://www.tbray.org/ongoing/When/200x/2005/09/13/Buffering)


I had this program that was running slow and fixed the problem by 
fixing the I/O buffering. If I had a quarter for every time I’ve done 
this over my career, I’d have, well, two or three bucks. I think the 
language-design community ought to take notice. Currently, they cook up 
new languages so object-oriented that each individual bit has a method 
repertoire, languages so concurrent that threads execute in 
incommensurable parallel universes, languages so functional that their 
effects are completely unobservable... How about a radical new language 
where the runtime system is hyperaggressive about ensuring that all of 
its I/O primitives are by default buffered unless the programmer 
specifically requests otherwise? I’ve heard that there’s something 
called “COBOL” that has this capability, I’ll have to check it out.


Apologies if I've misunderstood things so badly as to make my questions 
senseless, or worse yet, irrelevant.


/au


Re: \(...)?

2005-09-20 Thread Juerd
TSa skribis 2005-09-20 19:06 (+0200):
 Please help me to understand how the context starts to exist.

What do you mean?

Do you want to know what things provide list context?

- hash assignment
- array assignment
- arrayref constructor []
- hashref constructor {}
- slurpy parameters
- list assignment (indeed circular... anyone?)

 strict notion: when you see a comma you are looking at a list.

But that's not if and only if. What other ways are there to create
lists? Please take into account the entire Perl 6 world, not just the
subsubject at hand (comma operator).

 my @foo = bar();  # here, what bar returns is a list, without any
   # comma.
 That @foo is of syntactic type Array is clear. That bar is called
 without parameters is obvious as well. But where do you derive the
 the return type from?

List is not a type. The return *type* is not visible in this snippet.
However, what is returned, is a list.

Lists are ordered collections of scalars. The elements can have types,
a list itself cannot.

bar() evaluates to a list because it is in list context. List context
here is created by the array assignment.

There is no such thing as returns List or -- List, because there is
no type List. List thus also does not have sub or super types.

 That could at most come from type information of bar e.g. :( Void --
 Blubber) and then the question arises if a Blubber is assignable to an
 Array or not.  Well, or if a Blubber can listify.

Assignable to arrays is everything, because everything can be in list
context and then form a list. A single scalar, when in list context,
forms a list of one element.

Because there is no List type, there is also no such thing as coercion
to or from List. Listification is a useless word IMO, but I guess it
could be used to describe things that are in list context: in this case,
everything can listify.

   my foo ::= prefix:\;
 enreferencing should work with
   ($x,$y) = foo($a,$b);
  or not?

I think this works, but I was discussing syntax: the function of parens
after \, and how to look at \ compared to other \W and \w+ operators,
syntax wise.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: conditional wrapper blocks

2005-09-20 Thread Juerd
Yuval Kogman skribis 2005-09-20 20:33 (+0300):
 Today on #perl6 I complained about the fact that this is always
 inelegant:
   if ($condition) { pre }
   unconditional midsection;
   if ($condition) { post }

I believe it's not inelegant enough to do something about.

The unconditional part is easily copied if it's a single line, and can
easily be factored to a method or sub if it's not. Especially with
lexical subs.

my sub midsection {
unconditional midsection;
}

if ($condition) {
pre;
midsection;
post;
} else {
midsection;
}

Although the original you show isn't so bad either. It gets bad when
$condition gets complex, but in that case, you should use a named
variable for documentation anyway.

I think your proposed feature makes cluttered and eventually even less
elegant programming way too easy and attractive, and that its benefits
are far too little. At first glances, it makes me think it's mostly
useful for people who hate refactoring.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: conditional wrapper blocks

2005-09-20 Thread Juerd
Mark Reed skribis 2005-09-20 14:31 (-0400):
 Not necessarily.  Consider this common idiom (in pseudo-perl5):

Common, but widely regarded as bad style. The solution is templating and
factoring in templates.

But disregarding that,

The trick is to not see it as pre; midsection; post; versus
midsection;, but as simply foo; bar; baz;.

for my $item (@menu) {
if ($item-there) {
printf(
li%s/li\n,
encode_entities($item-label),
);
} else {
printf(
lia href=%s%s/a/li\n,
uri_escape($item-url),
encode_entities($item-label),
);
}
}

This has so little redundancy that it makes very little sense to want to
avoid repeating that very short encode_entities($item-label). 

(I'd actually prefer something like:

for my $item (@menu) {
my $label = encode_entities $item-label;
my $href  = uri_escape $item-url;
my $there = $item-there;

print qq[li$label/li\n]   if $there;
print qq[lia href=$href$label/a/li] if not $there;
}

instead.)


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: conditional wrapper blocks

2005-09-20 Thread John Macdonald
On Tue, Sep 20, 2005 at 08:58:41PM +0200, Juerd wrote:
 Yuval Kogman skribis 2005-09-20 20:33 (+0300):
  Today on #perl6 I complained about the fact that this is always
  inelegant:
  if ($condition) { pre }
  unconditional midsection;
  if ($condition) { post }
 
 I believe it's not inelegant enough to do something about.
 
 The unconditional part is easily copied if it's a single line, and can
 easily be factored to a method or sub if it's not. Especially with
 lexical subs.

There's a middle range where midsection is complicated enough
that copying it is a bad idea, but it is still sufficiently
short that factoring it into a sub causes more clutter and
interrupted thought patterns.

I've half-heartedly wished for this sort of linguistic construct
many times over the years, but it comes up rarely enough that
it's never been a burning desire.  Furthermore, any language
construct I've considered seems worse to me than just using
statement modifiers.  (So, this desire became far less of a
burning issue when I began programming in perl instead of C
and other languages.)

I don't like copying code of even a small amount of complexity -
sooner or later a change will happen to one copy that doesn't
get made to the other copy of the code, and a bug has been
inserted.

So, I just assign the condition to a variable and use:

{
my $cond = ... condition ...;

pre if $cond;

...
mid
...

postif $cond;
}

When I read this sort of code to check it for problems, I
want clarity.  I'm going to have to read it twice to ensure
that it is correct for both of the ways it will be used
(when $cond is true and when it is false).  Moving mid into
a subroutine makes that reading harder.  Even the syntax that
Yuval suggests is more cluttered for reading the straight-line
code for the $cond is true case.

Reading the code for the case when $cond is false is easy no
matter which coding method you use - all of the midsection
code is in one place with any technique.

But when reading the code for the case when $cond is true,
I can read the code as if it were:

pre

...
mid
...

post

by simply ignoring the trailing  if $cond; as I read.
Ignoring the text off to the right is easy; much easier than
ignoring syntax that is mixed into the code, or than reading
code that has been broken into 3 parts and the middle part is
somewhere on the page before or after the other two parts.

-- 


Re: Lazy lists and optimizing for responsiveness

2005-09-20 Thread Stuart Cook
On 19/09/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 This solution lacks the elegance of the lazy loading approach, but
 has the best responsiveness. These implementations tend to be overly
 complex for what they do, and hence not worth the maintenance costs.
 
 The gain is that the user only has to wait for the first message,
 and if the throughput of the system is higher than the user's input,
 there is no responsiveness loss because something is always ready
 for the user to get at.
 
 Ideally we could have the lazy list approach have some kind of way
 to modify the lazyness so that it's something in between -
 background eagerness - the lazy list is resolved in the background,
 accumilating to @messages. When @messages is filling up quickly the
 background resolution thread might get a lower priority. when
 @messages is empty, the receiver side has to block.

Initial reaction: I like it!

It's one of those I always subconsciously wanted to do this, but
never knew it ideas.

Essentially, if lazy means don't force items until I ask for them,
and strict means everything must be forced up-front, then async
relaxes both restrictions, saying I don't need this list to be forced
up-front, but I also don't care if they end up forced before I use
them--just make each access as quick as you can.

Obviously, applying this to an /infinite/ list might be a bad idea
(unless you could specify a finite buffering limit)...

 Note: I have an idea of how easy I want this to be, but not how I
 want to do it.
 
 I think that a nice solution is to allow an optional named adverb to
 gather which defaults to lazy:

More generally, it would be nice to have a sub async_force (or
whatever) that takes a lazy list and produces an asynchronously
pre-forced one. Shortcuts for common cases (like gather/take) would be
nice too, though.


Stuart


Re: conditional wrapper blocks

2005-09-20 Thread mark . a . biggar
Some other possible problems:

1: if $condition is an expression with side-effects then your new construct has 
a different meaning then the original code.

2: if the middle part does something that changes the value of  the expression 
$condition then the new construct again has a different meaning.


besides if you really want it just define a macro.


--
Mark Biggar
[EMAIL PROTECTED]
[EMAIL PROTECTED]
[EMAIL PROTECTED]


 Today on #perl6 I complained about the fact that this is always
 inelegant:
 
   if ($condition) { pre }
 
   unconditional midsection;
 
   if ($condition) { post }
 
 Either you put the condition in a boolean var and check it twice, or
 you use a higher order function and give it three blocks, and the
 conditional. But no matter how much we try, it always feels too
 manual.
 
 I asked for some ideas and together with Aankhen we converged on the
 following syntax:
 
   if ($condition) {
   pre;
   } uncond {
   middle;
   } cond {
   post;
   }
 
 s/uncond/pause regardless.pick/e;
 s/cond/resume again.pick/e;
 
 Some restrictions:
 
 The block structure must always be ternary - for other cases we
 already have enough control flow.
 
 The if is not the same if that can cuddle with else - it's either
 or.
 
 Does anybody have any comments, or synonyms for the control
 structure naming?
 
 BTW, I expect readability to be optimal with 1-2 lines of pre/post,
 and 1-5 lines of middle. Any observations?
 
 -- 
  ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
  /\  kung foo master: /me groks YAML like the grasshopper: neeyah!!
 
 

---BeginMessage---


pgpC3zhriMFzT.pgp
Description: PGP signature
---End Message---


Re: Object Model Pictures

2005-09-20 Thread Stevan Little


On Sep 12, 2005, at 3:56 PM, Nathan Gray wrote:

Yep, someone needs to make a diagram about Roles, too.



Here yah go.

http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel2.0/docs/ 
p6_role_model.jpg


I am planning on making Roles self-bootstrapping, so the class(Role)  
will actually be the first Role in the system. From there, Class will  
do Role, and Role will do Role. This also means that all the  
instances of Class will also do Role, which means that classes  
automatically can also be used as Roles.


Here is a mini-meta-model variation which implements this on a very  
basic level:


http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel2.0/docs/ 
MiniMetaModel_w_Role.pl


There is also an ASCII diagram here:

http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel2.0/docs/ 
misc_drawings.txt


I was planning on getting Role into the metamodel by the end of this  
week, but it seems $work might get in the way.


Stevan



Re: Junctions, patterns, and fmap again

2005-09-20 Thread Stuart Cook
On 20/09/05, Luke Palmer [EMAIL PROTECTED] wrote:
 The basic idea is that, alongside Functor, you have a Zippable theory
 which defines:
 
 theory Zippable[::T] {
 multi zip (T[::A], T[::B] -- T[:(::A, ::B)]) {...}
 }
 
 Where that last coloney madness is a yet-to-be-proposed tuple type
 (but tuples can be emulated if they are not in the core language, so
 it's no biggie).  That is, zip takes two structures and figures out
 how to combine them in a reasonable way into pairs of values.  So:
 
 zip([1,2,[3,4]], [[a,b], c, d])
 
 Gives:
 
 [[:(1,a), :(1,b)], :(2,c), [:(3,d), :(4,d)]]

Oh, looks like I was way off. So in this particular scenario, when one
side 'runs out' of structure, that part degenerates to a one-side fmap
using the leaf value as the non-hyper arg.

Of course, this is the behaviour for /built-in/ arrays--it's up to the
person defining fzip to determine how to handle their own Zippable
types. So, if they want fzip to fail() on incompatible structures, or
do some other crazy thing, they can just put that in their version of
fzip.

 So it's really up to the zippable functor itself to figure out the
 best way to zip.  After the structures are zipped up, you fmap the
 binary function on each of the tuples, resulting in a reasonable
 functor structure again.

Bottom line: user-defined fzip turns two structures into one
structure of pairs (in whatever way the user deems reasonable), and
then fmap transforms the tuples of that one structure.

For things like `foo(»$x«, »$y«, »$z«)` (assuming it ends up being
supported), you would either extend fzip over n-tuples, or just use
pair-fzip repeatedly and reduce the nested pairs into a single
n-tuple.

 Nope.  Here it is.  And it was 22 lines. :-)
 
 http://svn.luqui.org/svn/misc/luke/work/code/haskell/hyper.hs

Thanks, that made it a lot clearer. Haskell++ :)

I just hope you and I aren't the only ones who think this is a great idea...


Stuart