Re: Cmap Cgrep and lazyness

2004-07-03 Thread Luke Palmer
Alexey Trofimenko writes:
  what I want to ask - would map and grep return an iterators too?.. if  
 it's true, then previous construct becames very memory efficient, like if  
 I write
  loop ( ... ; ... ; ... ) {...; next if ...; ...; say}

Yep, they will.

 hm.. It could be a little too functional, though, for perl, which is  
 filled up by side effects. for example, $filehandle is iterator too, but  
 it has side effect of changin' position in file. now
 
  sub process (@a is Lazy) { map {...} @a }
 
 becomes somewhat dangerous if called as
 
  @b = process $file

Well, perhaps not.  Theoretically, at this point, $file has been read
completely.  It's just that it's lying and it hasn't really.  But if you
try to read again, it should resync and things should work properly.

But indeed there are cases where it is a problem:

my $x = 2;
sub mklist () {
return map { 2 * $_ } 0..10;
}

my @list = mklist;
say @list[0..4];   # 0 2 4 6 8
$x = 1;
say @list; # 0 2 4 6 8 5 6 7 8 9 10

Which is assuredly different from what would happen if it were evaluated
non-lazily.

Fortunately, if you fear such effects, you can use the eager flattener:

my @list = **mklist;

Which will exhaust the iterator and turn it into a real list
immediately.  Of course, if you do:

my @list = ** 0...;

You'll be testing your computer's temper.

Luke

 
 (assuming we have lazy arrays too. maybe it should be := insted of = ?)

I don't actually know whether it should be := .  I expect not; the
laziness may be built into the array value implementation. However, it
would feel cleaner to make it behave as a tied array.  But then you'd
have to declare it tied, which would be a pain.

Luke


Re: push with lazy lists

2004-07-03 Thread Dan Hursh
Joseph Ryan wrote:
The way I understand the magicness of lazy lists, I'd expect:
@x = 3..Inf;
say pop @x; # prints Inf
@x = 3..Inf;
push @x, 6; # an array with the first part being 
# lazy, and then the element 6

say pop @x; # prints 6
say pop @x; # prints Inf
say pop @x; # prints Inf
say pop @x; # prints Inf
# etc 

The way I think of a lazy infinite list is kind of like a special object.  It needs to keep track of what the start is and what the end is.  Every other element doesn't actually exist, but is calculated based on the index of the FETCH/STORE/SPLICE/whatever call.
I guess that's true with X..Y lazy lists.  I thought there were other 
ways to make lazy lists, like giving it a closure that gets called 
lazily to populate the list with the result's being cached.  I can't 
remember the syntax though.  I think gather was one way.  Maybe I'm just 
remembering wrong.

Anyhow, I was thiking that was how X..Inf was implemented.  That would 
be foolish in this case.

how 'bout
@x = gather{
loop{
take time
}
}   # can this be @x = gather { take time loop }
push @x, later;
say pop @x;# later
say pop @x;# heat death?
say @x[rand];  # how about now?
Also, any list that contains and infinite list becomes tied.  The container list's FETCH would 
change so that any accessed index that falls within the indexes owned by the 
infinite list would be dispatched to the infinite list.  So, with a list like:
@array = ('a','b','c',2..Inf,woops);
Elements 0, 1, and 2 would be accessable as normal, but then elements 3 through Inf would be dispatched to the infinite list.  However, since woops's index is also Inf, and that index is owned by the infinite list, it would be impossible to access it except through a pop call (which doesn't look at indexes at all).
I was wondering about lazy list where we don't know how many element it 
might generate.  Admittedly, I picked a poor example.  I would right to 
assume woops would also be accessable with @array[-1], right?

Dan


Re: The .bytes/.codepoints/.graphemes methods

2004-07-03 Thread Brent 'Dax' Royal-Gordon
Aaron Sherman wrote:
On Tue, 2004-06-29 at 11:34, Austin Hastings wrote:
(2) Perl6 should equitably support all its target
locales; (3) we should set out to make sure the performance is damn
fast no matter what locale we're using.
Well, that's a nice theory, but you can prove that low-level encodings
(e.g. ASCII, EBCDIC) will be more efficient than high-level encodings
(e.g. UTF-8), so the only way to accomplish what you suggest in (2) is
to break (3) by slowing down the faster handling (not what you wanted,
I'm sure).
At the Parrot level, codepoint operations will generally be the most 
efficient, even on strings with exotic charsets.  Parrot uses an 
internal encoding that allows O(1) access to codepoints; essentially, it 
uses an array of 8-, 16-, or 32-bit integers, depending on the highest 
codepoint value.  This is the default even for character sets with shift 
characters, like Shift-JIS.

On strings where all codepoints have values under 256, bytewise and 
codepointwise lookup are equivalent; otherwise, though, bytewise lookup 
will actually be *slower* than codepointwise, as Parrot will maintain 
the illusion that each codepoint is stored in an integer that's the 
perfect size for it.

If you force Parrot to use the UTF-8 encoding internally then bytewise 
lookup becomes fastest, and codepointwise slows down a lot.  But you 
really shouldn't do that--UTF-8 is ill-suited for actually 
*manipulating* text, unlike the Parrot internal encodings.  (UTF-16 and 
UTF-32 will presumably be available too, although I've seen no specific 
mention of them.)

You can also force it to use a raw or bytes encoding, where bytes 
and codepoints are identical.  But you can't store Unicode characters in 
such a string and have them behave in a reasonable way.

(Note: this is all based on my own, possibly false, memory.)
--
Brent Dax Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker
Oceania has always been at war with Eastasia.


Re: Cmap Cgrep and lazyness

2004-07-03 Thread Brent 'Dax' Royal-Gordon
Alexey Trofimenko wrote:
 apply to it perl6 GC, which wouldn't always free memory immediately, 
so  it could eat 3_000_000 or more.
Parrot runs a DOD (Dead Object Detection) sweep whenever its memory 
pools fill up, so this is probably a far smaller problem than you 
suggest.  (If there still isn't any space in the existing pools after a 
DOD, it malloc()s a new one.)

 ok, I know, that 1..n will return an iterator in perl6, which is 
called  only when new item needed. great.

 what I want to ask - would map and grep return an iterators too?.. if  
it's true, then previous construct becames very memory efficient, like 
if  I write
 loop ( ... ; ... ; ... ) {...; next if ...; ...; say}
As you mentioned below, this causes problems if the code in question has 
side effects.  But there are other cases where it messes up:

sub even($_ = $CALLER::_) { ! $_ % 2 }
my @e=grep { even() } 1..1024;
#Okay, we don't need even anymore...
undef even;
say @e;
Put that Cundef in an Ceval, and all of a sudden you can't tell if 
the laziness is safe even at compile time.

I suggest that this laziness be confined only to places where it's 
specifically asked for:

my @e=grep { even() } :lazy 1..1024;
--
Brent Dax Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker
Oceania has always been at war with Eastasia.


Re: undo()?

2004-07-03 Thread Jonadab the Unsightly One
Juerd [EMAIL PROTECTED] writes:

 I thought temp replaced local. 

temp is dynamic scoping, the same thing as Perl5's local.

Hypotheticals are the ones that turn permanent if everything succeeds
according to plan but revert to the old value if stuff fails -- a
rollback mechanism, basically.  I was just about to mention
hypothetical scoping wrt undo but for some reason did not.  

In fairness to the undo suggestion, there is a significant difference:
to use hypotheticals to revert you have to plan the reverting when (or
before) you make the change.  I think continuations work this way also
(except that they don't just revert one thing).  This sounds like a
no-brainer (i.e., you're writing the code that uses undo so obviously
you planned at coding time to do the reversion) until you think about
putting references into the mix; with undo you could revert an
arbitrary item.

One thing worth noting about .undo is that retrofitting it later would
not break backward-compatibility at the language level.  It would be
one heck of a messy change under the hood, but any user who wasn't
using it wouldn't have to even know about the change.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: undo()?

2004-07-03 Thread Jonadab the Unsightly One
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes:

 Actually, I think you're underestimating the little guys.  After
 all, if they rolled back *all* of your changes, all they could do
 was repeatedly execute the same code!

Except that you can pass the continuation some arguments, possibly
including functions, closures, or even other continuations, which
would rather complicate matters.

But Luke's explanation makes sense of some things I previously
couldn't make sense of.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: if not C, then what?

2004-07-03 Thread Jonadab the Unsightly One
Jonathan Lang [EMAIL PROTECTED] writes:

 Strictly from a grammatical perspective, I'd be much more comfortable with
 C, then instead of Cthen as the perl equivelent of the C-style comma:
 have the then keyword change the preceeding comma from a list
 constructor to an expression combiner.  From a parsing perspective,
 though, this would be a nightmare.  

Parsing Perl was nightmarish already before work started on Perl6.  If
we wanted a language that's easy to parse, we'd be using lisp, or
maybe assembly language.

Still, I'm not sure what the comma adds, other than extra[1]
punctuation.

This is different from its use in conditional sentences, since in that
case the protasis (if clause), being an introductory subordinate
clause, is usually set off from the rest of the sentence via a comma,
whether or not then is used to introduce the apodosis (then
clause).  It is common to see a comma before then for this reason,
but that is entirely a different use (and meaning) of then.

Come to think of it, the frequent use of then in conditionals might
make it a bad choice for use in another way.

 Actually, the whole purpose of the C-style comma is to allow you to place
 multiple expressions in a place that's only designed to take one, such as
 the various divisions within a loop control set (loop ($i = 0, $j = 1; $i
  10; $i++, $j*=2) {...}).  For something like this, you might be better
 off doing something like

   last($a, $b, $c)

 (where last is a sub that takes a list of arguments, evaluates them one at
 a time, and returns the value of the last one).  Unfortunately, last is
 already in use by perl; so you'd have to think up another name for the
 sub, such as final.  

Oh, like lisp's progn (except that final is a better name for it).

Perl5 programmers have been known to use xor for this, though of
course that is not the intended use of xor.

 where C[-] is read as followed by.  You could even set up a
 right-to-left version, C[-], but why bother?  

Oh, for aesthetic symetry, of course ;-)

[1] Do one thing then do another is valid SWE I think. then is not
a coordinating conjunction like and; it's a special adverb of
sorts, in a similar category with because (except that because
is a subordinator; whereas, then does coordinate; but it is not
a conjunction) or so (although so often is treated like a
conjunction and takes the comma, which is an odd little wrinkle --
but it does not always do this).  then can function as a
coordinating adverb (like consequently and nonetheless and so on);
in the case wherein it joins whole independent clauses it is
preceded by a semicolon (as in She went to the store; then she
came home. -- if there were a comma in this case it would be
after then, not before), but it can also be used to coordinate
the parts of a compound part of speech, e.g., a compound verb with
the subject expressed only once (if at all; in the imperative mood
the subject need not be expressed); in that case no punctuation is
needed, as in She went to the store then came home.  This last
usage most closely fits the proposed way of using it in Perl, as
in  (you) Go to the store then come straight home.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: if not C, then what?

2004-07-03 Thread Jonadab the Unsightly One
David Storrs [EMAIL PROTECTED] writes:

 e.g., is this legal?

 sub infix:before ( $before, $after ){ ... }

I should HOPE it would be legal to define infix:before.  Some of us
don't want to use untypeable characters every time we want to define
an operator that doesn't conflict with the core language.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: if not C, then what?

2004-07-03 Thread Jonadab the Unsightly One
Jonathan Lang [EMAIL PROTECTED] writes:

 For the record, I was mentally parsing this example as:

   pray_to $_; 
   sacrifice $virgin for @evil_gods;

So was I, FWIW.

 The precedence of Cthen isn't very intuitive to me.  

Is that an argument for changing its precedence, or for leaving it out
of the core language?

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: if not C, then what?

2004-07-03 Thread Juerd
Jonadab the Unsightly One skribis 2004-07-03 13:33 (-0400):
  e.g., is this legal?
  sub infix:before ( $before, $after ){ ... }
 I should HOPE it would be legal to define infix:before.

There already are infix:x and infix:xx. If Perl 6 will let us define our
own operators just like built in ones, infix:before should also be
possible.

And infix:¥ (for those like me who have a simple terminal that doesn't
know how to display this, or are suffering from my lack of config-fu to
get headers and encodings synched: this is Yen, created using ^KYe in
vim. I see a dashed rectangle.) will in my programs probably only be
used through infix:Y or infix:z, which I will define myself if
necessary. (zip() is not infix and thus not an *equivalent*
alternative.)


Juerd


Re: push with lazy lists

2004-07-03 Thread JOSEPH RYAN
- Original Message -
From: Dan Hursh [EMAIL PROTECTED]
Date: Friday, July 2, 2004 10:32 pm
Subject: Re: push with lazy lists

 Joseph Ryan wrote:
 I guess that's true with X..Y lazy lists.  I
thought there were 
 other 
 ways to make lazy lists, like giving it a closure
that gets called 
 lazily to populate the list with the result's
being cached.  I 
 can't 
 remember the syntax though.  I think gather was
one way.  Maybe 
 I'm just 
 remembering wrong.
 
 Anyhow, I was thiking that was how X..Inf was
implemented.  That 
 would 
 be foolish in this case.
 
 how 'bout
 
 @x = gather{
 loop{
 take time
 }
 }   # can this be @x = gather { take time loop }
 push @x, later;
 say pop @x;# later
 say pop @x;# heat death?
 say @x[rand];  # how about now?

I'm a bit confused by your syntax, but I think I 
understand what you mean.  I was under the impression
that loops were not lazily evaluated, but essentially
run until they were broken out of.  The advantage of
using an infinite list is just that you have an 
iterator that never runs out.

  Also, any list that contains and infinite list
becomes tied.  
 The container list's FETCH would change so that
any accessed index 
 that falls within the indexes owned by the
infinite list would 
 be dispatched to the infinite list.  So, with a
list like:
  
  @array = ('a','b','c',2..Inf,woops);
  
  Elements 0, 1, and 2 would be accessable as
normal, but then 
 elements 3 through Inf would be dispatched to the
infinite list.  
 However, since woops's index is also Inf, and
that index is 
 owned by the infinite list, it would be
impossible to access it 
 except through a pop call (which doesn't look at
indexes at all).
 
 I was wondering about lazy list where we don't
know how many 
 element it 
 might generate.  Admittedly, I picked a poor
example.  I would 
 right to 
 assume woops would also be accessable with
@array[-1], right?

Oh yeah, that would work too. :)

- Joe



Re: undo()?

2004-07-03 Thread Jonadab the Unsightly One
Luke Palmer [EMAIL PROTECTED] writes:

 Oh no!  Someone doesn't understand continuations!  How could this
 happen?!  :-)

Yes, well, I've only just started reading up on them recently...

 A continuation doesn't save data.  It's just a closure that closes
 over the execution stack

Ah.  That helps a lot.  For some reason, I hadn't realize that yet
from reading about them in Dybvig.

 You could make the programmer specify which variables he wants delta
 data for, and then any *others* wouldn't keep it and wouldn't be
 undoable.
 
 A much more useful way to do this would be:

 use undo  $foo $bar $baz ;
 my $foo = 41;
 my $state = undo.save;
 $foo++;  $foo.undo($state);  # or perhaps $state.remember;

That seems reasonable to me.

 I don't want to think about what happens when you write:
 
use undo  $state ;

Something terribly inefficient, I suppose.  There could be a warning
in the documentation about that.

Or something could try to be clever and detect this sort of thing; I'm
not entirely certain whether that's equivalent to the halting problem,
but either way it sounds like all kinds of excitement, or something.

-- 
$;=sub{$/};@;=map{my($a,$b)=($_,$;);$;=sub{$a.$b-()}}
split//,[EMAIL PROTECTED]/ --;$\=$ ;- ();print$/



Re: Cmap Cgrep and lazyness

2004-07-03 Thread Luke Palmer
Brent 'Dax' Royal-Gordon writes:
 As you mentioned below, this causes problems if the code in question has 
 side effects.  But there are other cases where it messes up:
 
 sub even($_ = $CALLER::_) { ! $_ % 2 }
 my @e=grep { even() } 1..1024;
 #Okay, we don't need even anymore...
 undef even;
 say @e;
 
 Put that Cundef in an Ceval, and all of a sudden you can't tell if 
 the laziness is safe even at compile time.

Perhaps this isn't a problem.  Think of your code this way:

my $even = sub ($_ = $CALLER::_) { ! $_ % 2 };
my @e = grep { $even() } 1..1024;
undef $even;
say @e;

Is it a problem now?  Nope.  @e holds a reference to the grep generator,
which holds a reference to the code, which holds a reference to $even.
So the Cundef $even didn't change a thing.

So it is only a problem if sub calls are made by name lookup as they are
in Perl 5.  If the sub is predeclared, the call to even() my have been
made into a reference. 

 
 I suggest that this laziness be confined only to places where it's 
 specifically asked for:
 
 my @e=grep { even() } :lazy 1..1024;

There's a way to go the other way, to specifically mark it as non-lazy:

my @e = **grep { even() } 1..1024;

I don't mind lazy by default, as long as the error messages are smart
enough to know that they were inside a lazy generator.  That is, in your
case:

Subroutine call to even() not defined at test.pl line 2
Called from lazy generator on test.pl line 2.

Luke