Re: My first functional perl6 program

2006-08-25 Thread John Macdonald
On Wed, Aug 23, 2006 at 04:10:32PM -0700, Larry Wall wrote:
 Yes, that should work eventually, given that hypers are supposed to stop
 after the longest *finite* sequence.  In theory you could even say
 
 my %trans = ('a'..*) »=« ('?' xx *);
 
 but we haven't tried to define what the semantics of a lazy hash would be...

That's a rather large hazard.  %trans{$key} would run until
the lazy hash is extended far enough to determine whether
$key is ever matched as a key - and that could easily mean
trying forever.  So, it is only safe to use the hash for
keys that you *know* are in the domain; or, if the lazy
key generation is simple enough, keys that you *know* can
be excluded in a finite amount of time.  (I'm assuming that
1 ~~ any( 5..* ) will be smart enough to return false.)

-- 


Re: My first functional perl6 program

2006-08-24 Thread Luke Palmer

On 8/23/06, Larry Wall [EMAIL PROTECTED] wrote:

Yes, that should work eventually, given that hypers are supposed to stop
after the longest *finite* sequence.


Shudder xx *

What the hell does that mean!?

Let me posit this:

   @a = 0..42;
   @b = list_of_twin_primes();
   (@a = @b).length;

Is it 43, or does it not terminate (as far as we can tell)?

If we are to use lazy lists powerfully, we must be allowed to not be
able to know whether they are finite.  I would argue that we don't
make semantic distictions (other than eager) between lazy and non-lazy
lists, because I'm guessing that such distinctions will remove the
power of lazy lists.  I like to use lists in Haskell because I know
what they are; I don't care if they have been pre-evaluated or are
being evaluated as I am using them, I am sure of the semantics either
way.  I fear that if eager lists are given an elevated status in Perl
6, then I would be afraid to use lazy lists for anything other than
minor conveniences.

The way i would define hyper would be to stop after the shortest list
(also with zip).  I know there are reasons not to do that, however, it
is easy to say:

   (@a, 0 xx *) + @b

or

   @a + @[EMAIL PROTECTED]

It removes this lazy/nonlazy distinction, making semantics simpler and
more predictable.  It removes the need for default values for
operators, and exchanges it for the request for the programmer to say
what he means.  It removes the need for defaulting parameters in the
zip call, simplifying its semantics.

Mostly, though, it will allow me to use lazy lists like
list_of_twin_primes() without me worrying that it will be
discriminated against in my generic list code.

Luke


Re: My first functional perl6 program

2006-08-24 Thread Mark J. Reed

I found your rant a bit long on vehemence and short on coherence,
Luke, but if I understand you correctly, your complaint is that this
is finite:

@finite_list = @infinite_list

while, according to S03, this is long:

@short_list = @long_list

e.g. q(a b) = (1,2,3,4) would return (a=1, b=2, undef=3, undef=4).

I agree that is a logical contradiction.  Either the first should be
infinite, or the second should be short.

But I still don't understand your expressed incredulity about xx *.  I
think it's perfectly clear what that means.  Fpr example, $foo xx *
creates a(n infinite) list which contains $foo at every position no
matter how high a position you ask for . . .



--
Mark J. Reed [EMAIL PROTECTED]


Re: My first functional perl6 program

2006-08-24 Thread Mark J. Reed

On 8/24/06, Mark J. Reed [EMAIL PROTECTED] wrote:

e.g. q(a b) = (1,2,3,4) would return (a=1, b=2, undef=3, undef=4).


or rather, it would if I'd typed qw(a b) as I intended.

One other point: while I agree that we should shield the programmer as
much as possible from having to care whether a list is finite or not,
some things cannot be helped; for instance, calling .length on an
infinite list is going to be a bad idea no matter what...

--
Mark J. Reed [EMAIL PROTECTED]


Re: My first functional perl6 program

2006-08-24 Thread Luke Palmer

On 8/24/06, Mark J. Reed [EMAIL PROTECTED] wrote:

I found your rant a bit long on vehemence and short on coherence,
Luke, but if I understand you correctly, your complaint is that this
is finite:

@finite_list = @infinite_list

while, according to S03, this is long:

@short_list = @long_list


Precisely.


But I still don't understand your expressed incredulity about xx *.  I
think it's perfectly clear what that means.  Fpr example, $foo xx *
creates a(n infinite) list which contains $foo at every position no
matter how high a position you ask for . . .


Ahh, that wasn't a complaint about xx *. I was shuddering an infinite
number of times.

Luke


Re: My first functional perl6 program

2006-08-24 Thread Larry Wall
On Thu, Aug 24, 2006 at 12:09:44AM -0600, Luke Palmer wrote:
: The way i would define hyper would be to stop after the shortest list
: (also with zip).  I know there are reasons not to do that, however, it
: is easy to say:
: 
:(@a, 0 xx *) + @b
: 
: or
: 
:@a + @[EMAIL PROTECTED]

Well, now that we have *, it does tilt the equation differently.  We could
perhaps even allow * at the end of a list to expand to * xx * or some such.
It would make it easy to say when you don't care if the list is short:

   (@a, *) + @b

Always presuming that + does something sane with *, of course.

With that I could probably be argued into stop-at-shortest semantics,
though I do wish there were an easy way to detect two lists that
weren't conformant.  I hate forgetting things accidentally.  Hmm,
if the standard + doesn't deal with Whatever, you get an error when
it hits one, but in a lexical scope you can define a my multi that
says how to handle a Whatever.  Not sure if that's the right default
though--it doesn't actually detect non-conformant lists unless you
put * on the shorter one.  We could check for conformance only on
lists that are known to be finite and assume the rest are infinite.

Or, as with the reduce ops, maybe we just need a hyperop variant like \+.
Presumably it'd be the variant that enforces conformance, so you have to
ask for it.  Definitely needs more thought, though...

Larry


My first functional perl6 program

2006-08-23 Thread Mark J. Reed

To get my feet wet, I thought I'd translate my silly little cryptogram
helper.  It turned out like this:


#!/usr/local/bin/pugs
#==
# Braindead cryptogram assistant with hard-coded key.
#--
my %key =
(
   a = 'f', b = 'o', e = 'n', f = 'w', g = 'd', h = 'a', j = 'm',
   k = 'i', l = 's', m = 'l', n = 'c', o = 'g', q = 'r', r = 'h',
   s = 'k', t = 'u', u = 'p', v = 't', w = 'j', x = 'e', y = 'v',
);


# Start by mapping all letters to question marks so the as-yet-undeciphered
# letters will stand out.  Then add the letters from the key, making sure to
# get both lowercase and uppercase forms

my %trans = ('a'..'z') »=« ('?' xx 26);

%trans{%key.keys.map({.lc,.uc})} = %key.values.map({.lc,.uc});

for = { say(.trans(%trans)) }




Surprisingly terse.  I wonder if there a more elegant way to do that
hash assignment?

It was especially convenient that String#trans accepts a Hash for the
mapping; my Perl5 and Ruby versions also store the key in a hash, but
then use keys+join and values+join to get tr-friendly strings out of
it.   This was much more natural.

(Speaking of which, pugs apparently doesn't have Ctr as a global
function, only the .trans method)

It does sadden me somewhat that the say() requires the parens (or an
explicit $_ etc).  But I'll live. :)

(The key above is for today's Order of the Stick, btw.)


--
Mark J. Reed [EMAIL PROTECTED]


Re: My first functional perl6 program

2006-08-23 Thread Mark J. Reed

On 8/23/06, Mark J. Reed [EMAIL PROTECTED] wrote:

my %trans = ('a'..'z') »=« ('?' xx 26);


Also, correct me if I'm wrong, but I should theoretically be able to
use xx * there, thus creating a lazily-evaluated infinitely-long list
of question marks?

--
Mark J. Reed [EMAIL PROTECTED]


Re: My first functional perl6 program

2006-08-23 Thread Larry Wall
On Wed, Aug 23, 2006 at 06:49:06PM -0400, Mark J. Reed wrote:
: On 8/23/06, Mark J. Reed [EMAIL PROTECTED] wrote:
: my %trans = ('a'..'z') »=« ('?' xx 26);
: 
: Also, correct me if I'm wrong, but I should theoretically be able to
: use xx * there, thus creating a lazily-evaluated infinitely-long list
: of question marks?

Yes, that should work eventually, given that hypers are supposed to stop
after the longest *finite* sequence.  In theory you could even say

my %trans = ('a'..*) »=« ('?' xx *);

but we haven't tried to define what the semantics of a lazy hash would be...

Larry


Re: My first functional perl6 program

2006-08-23 Thread Larry Wall
On Wed, Aug 23, 2006 at 06:39:52PM -0400, Mark J. Reed wrote:
: It does sadden me somewhat that the say() requires the parens (or an
: explicit $_ etc).  But I'll live. :)

Strange, this works for me:

$_ = foo; say .uc
FOO

Seems to work with .uc() as well.

Larry


Re: My first functional perl6 program

2006-08-23 Thread Mark J. Reed

On 8/23/06, Larry Wall [EMAIL PROTECTED] wrote:

Strange, this works for me:

$_ = foo; say .uc
FOO


Maybe that was fixed in 6.2.12, then.  I'm still running 6.2.11, and
at least on Cygwin, I get this:

$ pugs -e '$_ = foo; say .uc'
$
No output.  And if I try .trans:

$ pugs -e '$_ = foo; say .trans(o=0)'
*** No compatible subrountine found: trans
   at -e line 1, column 13-31

But in any clase I'm glad it's merely an implementation bug rather
than specced behavior.

--
Mark J. Reed [EMAIL PROTECTED]