Re: iterators and functions (and lists)

2004-12-10 Thread Michele Dondi
On Sun, 5 Dec 2004, Matthew Walton wrote:
At least we had the sense to call them subroutines instead of functions.
Of course, that also upset the mathematicians, who wanted to call them
functions anyway.  Go figure.
That might be because the mathematicians haven't heard of a variant of a 
function which is allowed to have side effects yet.
More or less BS for, from the point of view of a mathematitian (i.e. from 
the point of view of Mathematics), you still have true functions, 
they're either not just the *same* function each time, or the same 
function with some arguments/parameters set to different values (that in 
the implementation are passed implicitly rather than explicitly), which 
are fundamentally the same thing after all (up to an isomorphism, that 
is).

Michele
--
I find the line I am not pestering anybody, I am asking questions on
usenet. That's what usenet is for. a classic.
It's like I am not talking to you, I am just opening and closing my
mouth while standing close to you. That's what a mouth is for.
- David Kastrup, on comp.text.tex (slightly edited)


Re: iterators and functions (and lists)

2004-12-10 Thread Michele Dondi
On Mon, 6 Dec 2004, Larry Wall wrote:
to return an infinite list, or even
   return 0..., 0...;
to return a surreal list.  Either of those may be bound to an array
Hope not to bark something utterly stupid, but... if one iterates over 
such a list, may it be that on the first Clast one really starts over 
from the second 0? Well, unless some adverb is given to the point that 
one really has to

  last :everything  # or somesuch...
Michele
--
Some time ago,I managed to wipe out almost all of  /usr/bin while doing 
some cleaning (don't drink and root...:-)
- Predrag Ivanovic in CRUX mailing list


Re: iterators and functions (and lists)

2004-12-10 Thread Matthew Walton
Michele Dondi wrote:
On Sun, 5 Dec 2004, Matthew Walton wrote:
At least we had the sense to call them subroutines instead of functions.
Of course, that also upset the mathematicians, who wanted to call them
functions anyway.  Go figure.

That might be because the mathematicians haven't heard of a variant of 
a function which is allowed to have side effects yet.

More or less BS for, from the point of view of a mathematitian (i.e. 
from the point of view of Mathematics), you still have true functions, 
they're either not just the *same* function each time, or the same 
function with some arguments/parameters set to different values (that in 
the implementation are passed implicitly rather than explicitly), which 
are fundamentally the same thing after all (up to an isomorphism, that is).
I wasn't intending to be taken seriously with that comment. I hope 
everyone realised that...



Re: iterators and functions (and lists)

2004-12-10 Thread Luke Palmer
Michele Dondi writes:
 On Mon, 6 Dec 2004, Larry Wall wrote:
 
 to return an infinite list, or even
 
return 0..., 0...;
 
 to return a surreal list.  Either of those may be bound to an array
 
 Hope not to bark something utterly stupid, but... if one iterates over 
 such a list, may it be that on the first Clast one really starts over 
 from the second 0? Well, unless some adverb is given to the point that 
 one really has to
 
   last :everything  # or somesuch...

Balancing the mathematical preposterousness and the actual usefulness of
such a thing, I really don't think that's going to fly.  From the finite
world,  and *2 look exactly the same, and I'm pretty sure that, cool
as Perl is, it's still in the finite world.

In particular, calling Clast and having the loop not exit is more than
a little weird.  Whatever you can do with that, you could do with a
sligh redesign:

return [ 0... ], [ 0... ];

And then your Clast :everything is a Cnext OUTER for a nested loop.

Luke



Re: iterators and functions (and lists)

2004-12-07 Thread Matthew Walton
Larry Wall wrote:
On Sun, Dec 05, 2004 at 12:05:46AM +, Matthew Walton wrote:
: I'm sorry, but from a C++ background, overriding postcircumfix:( ) 
: feels far more natural to me than setting 'is default' on some method. 

That only works for disambiguation if you know which .() to call in
the first place.  It seems likely that that .() maps straight to MMD
and doesn't look for a singly dispatched .() at all.  But maybe I'm
just not understanding this.
No, that makes sense.
What you're talking about
already sounds suspiciously like Aspect Oriented Programming.
I wouldn't know, I've never looked into it. Perhaps I should...
Any foo() can return a list.  That list can be a Lazy list.  So the
ordinary return can say:
return 0...;
to return an infinite list, or even
return 0..., 0...;
to return a surreal list.  Either of those may be bound to an array
as its generator of missing values.  Assignment sort of implies
copying, but I'm just saying that the copier could also be smart
at least about infinities or indefinities (ohh, a cool new word),
even if it flattens everything else.
That would be good. It would be nice to be able to copy infinite lists 
without having to flatten them first.

An object can play the Undef role.  Or maybe undef can play Ref role.
In any event, since a string is an object, the answer is Yes, but
an unthrown Exception object that can stringify would be better...
I'll take either for now. I suspect an unthrown Exception will turn out 
to be the better solution, as it sounds much more useful. Except that 
I'm not quite sure how you'd notice it - I assume unthrown Exceptions 
would be expected to return false in Boolean context?

Next thing you'll be telling me is that all this partially evaluated
code shouldn't have any side effects.  :-)
Well of course it shouldn't. Confining all actions which have side 
effects to the IO monad makes it much easier to reason about programs 
and their behaviour.

Although I suspect anybody who tries to reason about something written 
in idiomatic Perl deserves the headache they're going to get. That 
doesn't mean I don't find Perl to be immensely fun to work with though. 
I believe Perl 6 will be even more immensely fun.


Re: iterators and functions (and lists)

2004-12-06 Thread Larry Wall
On Sun, Dec 05, 2004 at 12:05:46AM +, Matthew Walton wrote:
: I'm sorry, but from a C++ background, overriding postcircumfix:( ) 
: feels far more natural to me than setting 'is default' on some method. 

That only works for disambiguation if you know which .() to call in
the first place.  It seems likely that that .() maps straight to MMD
and doesn't look for a singly dispatched .() at all.  But maybe I'm
just not understanding this.

: What if you do 'is default' on two methods? Compile-time error?

Syntactically legal, and semantically legal if they have different MMD
signatures.  Otherwise a compile time error if the compiler can catch
it then, but I wouldn't require a compiler to do so if it's onerous.
Seems like it ought to be pretty easy though, if one has a way of
doing a test dispatch without really dispatching, and we need something
like that to resolve a reference like abscomplex.

: What if 
: you're opening up someone else's class and want to override the existing 
: default (okay, so you shouldn't be doing that in an OOP world, but what 
: if you are? What if you're like me and like Perl's delightful mishmash 
: of paradigms while simultaneously liking other languages for their 
: purity? What if I actually talk about something relevant?)

I suppose you could always wrap it instead.  What you're talking about
already sounds suspiciously like Aspect Oriented Programming.

: : # other thingies:
: : 
: :  sub foo { ... };
: :  @array = @foo # all the results of foo, lazily.
: 
: Don't see the need for that when
: 
: @array := foo()
: 
: does laziness implicitly already.  Maybe even
: 
: @array = foo()
: 
: maintains laziness if it sees an infinite iterator in the return
: value of foo().  Or maybe it blows up and tells you to use :=
: to avoid trying to make a copy.  That's probably cleaner.
: 
: This is going to take me a while to get my head round... Does this 
: particular foo() return an iterator? Or is it something which is 
: iterated? Have I missed a bit of a synopsis or apocalypse which would 
: make all this clear to me or are we still in handwaving mode?

Any foo() can return a list.  That list can be a Lazy list.  So the
ordinary return can say:

return 0...;

to return an infinite list, or even

return 0..., 0...;

to return a surreal list.  Either of those may be bound to an array
as its generator of missing values.  Assignment sort of implies
copying, but I'm just saying that the copier could also be smart
at least about infinities or indefinities (ohh, a cool new word),
even if it flattens everything else.

: Exceptions should not be used for
: something so mundane as running out fo values.
: 
: Amen to that! One reason I ran screaming from Java was having to catch 
: ArrayOutOfBoundsException all the time. And all those exceptions which 
: the compiler forces you to catch. They're handy, but there is a limit. I 
: prefer return values which can indicate if they're valid or not. undef 
: is excellent for that :-)
: 
: A string pretending to be undef can be even better. Can we still do 
: that? I seem to recall it being in something at some point along the way.

An object can play the Undef role.  Or maybe undef can play Ref role.
In any event, since a string is an object, the answer is Yes, but
an unthrown Exception object that can stringify would be better...

: If that's necessary to keep the Lazy from blocking when it runs out
: of values.  Just like an ordinary array, a Lazy has to be aware of
: when it is out of values, and when it should call into some meta-Lazy
: for more iterator values.  And I suppose that meta-Lazy could in
: turn have a meta-meta-Lazy, which could have a meta-meta-meta-Lazy,
: and now my brane hurts.
: 
: And soon your entire program consists of code which may or may not ever 
: be evaluated. Welcome to Haskell :-)

Next thing you'll be telling me is that all this partially evaluated
code shouldn't have any side effects.  :-)

Larry


Re: iterators and functions (and lists)

2004-12-06 Thread Luke Palmer
Larry Wall writes:
 Any foo() can return a list.  That list can be a Lazy list.  So the
 ordinary return can say:
 
 return 0...;
 
 to return an infinite list, or even
 
 return 0..., 0...;

Is it just me, or did you just return *2?  
http://en.wikipedia.org/wiki/Ordinal#Arithmetic_of_ordinals

That would be totally cool.  But um, how do we get at the structure of
that list from within Perl?  It looks like no matter what you do it
would be impossible to see the second 0.

Luke


Re: iterators and functions (and lists)

2004-12-06 Thread Austin Hastings
Luke Palmer wrote:
Larry Wall writes:
 

Any foo() can return a list.  That list can be a Lazy list.  So the
ordinary return can say:
   return 0...;
to return an infinite list, or even
   return 0..., 0...;
   

Is it just me, or did you just return *2?  
http://en.wikipedia.org/wiki/Ordinal#Arithmetic_of_ordinals

That would be totally cool.  But um, how do we get at the structure of
that list from within Perl?  It looks like no matter what you do it
would be impossible to see the second 0.
Luke
 

my ($foo1, $foo2) = foo();
?
=Austin


Re: iterators and functions (and lists)

2004-12-06 Thread Larry Wall
On Mon, Dec 06, 2004 at 06:14:56PM -0500, Austin Hastings wrote:
: Luke Palmer wrote:
: 
: Larry Wall writes:
:  
: 
: Any foo() can return a list.  That list can be a Lazy list.  So the
: ordinary return can say:
: 
:return 0...;
: 
: to return an infinite list, or even
: 
:return 0..., 0...;
:
: 
: 
: Is it just me, or did you just return *2?  
: http://en.wikipedia.org/wiki/Ordinal#Arithmetic_of_ordinals
: 
: That would be totally cool.  But um, how do we get at the structure of
: that list from within Perl?  It looks like no matter what you do it
: would be impossible to see the second 0.
: 
: Luke
: 
:  
: 
: my ($foo1, $foo2) = foo();
: 
: ?

No, that'd put 0 and 1 into those variables.

You'd have to bind the return value to @foo and then ask @foo for its
hidden specs that generates its values.  That has two elements, one for
each infinite iterator.  Here's the quote from A6:

The List type in particular is an internal type for the temporary
lists that are passed around in Perl. Preflattened lists are Eager,
while those lists that are not preflattened are Lazy. When you call
@array.specs, for instance, you actually get back an object of type
Lazy. Lists (Lazy or otherwise) are internal generator objects,
and in general you shouldn't be doing operations on them, but on
the arrays to which they are bound. The bound array manages its
hidden generators on your behalf to "harden" the abstract list
into concrete array values on demand.

As far as I can recall we haven't renamed C.specs to anything else yet.

Larry

Re: iterators and functions (and lists)

2004-12-06 Thread Smylers
Larry Wall writes:

 As far as I can recall we haven't renamed C.specs to anything else yet.

That sounds like a challenge ...

Smylers



Re: iterators and functions (and lists)

2004-12-04 Thread Larry Wall
On Sat, Dec 04, 2004 at 08:03:53PM +0300, Alexey Trofimenko wrote:
: hm.. consider that:
: 
: perl5:
:open $fh, 'file';
:$first_line = $fh;
:@remaining = $fh;
: 
: perl6:
:$fh = open 'file';
:$first_line = $fh();
:@remaining = $fh();
: 
: I thought about parallels between arrays and iterators,  and realized that  
: they aren't very close to each other:
: iterators are much closer to subroutines. And moreover, in perl5 they ARE  
: subroutines. In abstract, arrays are things with plenty of access methods  
: and iterator is the thing with a single action: one more result, please.  
: and that simplicity IS a power.
: so why not just CALL our iterator?

Why not indeed.

: of course, that analogy isn't going to work for true functions, which  
: returns the same all the time, for some given set of arguments.

Oh, well, we pissed off the mathematicians long ago.  :-)

At least we had the sense to call them subroutines instead of functions.
Of course, that also upset the mathematicians, who wanted to call them
functions anyway.  Go figure.

: so, of course, arrays and iterators should be interchangeable, but it  
: could be kin to an autoconversion. And we for sure have no need to convert  
: iterator to array so that we should convert it back again later, for  
: Cfor etc. (as some people here already stated)

Yes, that seems right.  An array can (and often does) provide a
view of the results of an iterator (which may in fact be a Lazy
list of iterators), but that doesn't mean that all iterators have to
be viewed through an array.

: ok, structured part of my brain is over.. now,
: random thoughts:
: 
:  $fh(:chomp)

Yes, but in general I think an autochomper layer should be applied
to the handle/iterator at open/construction time, not at evaluation time.

: for $fh {...}

No, foo doesn't do anything in Perl 6 except return a function pointer.
Have to use parens.

for $fh() {...}

in which case you might as well drop the .

: for $fh.assuming(:chomp) {...}

Same issue, all you're doing is iterating over a single value which is
a curried function pointer.  Have to say

for $fh.assuming(:chomp)() {...}

But note that a naive implementation of that is going to recurry the
iterator every time through.  Again, much cleaner to do it outside the
loop rather than relying on an optimizer that might let you down if
it can't intuit the purity of the call.

Interestingly, adding a layer to a filehandle is very much like a curry.

: # what about making foo( :bar ) the same as
: #  foo.assuming( :bar) ? ah, that not gonna work.. but I
: # think that feature definitely wants something more short
: # than .assuming; maybe even some special syntactic honey.
: # because it's  fun(ny|ctional)

We made it long on purpose for readability.  You can always use a macro
to obfuscate it.  What we're *not* going to do is autocurry missing
parameters like Haskell.  That just screws up all the compiler's
expectations on return types.  If I forget to supply an argument, I
want an error, not a function pointer.  I can add in the .assuming
myself when I decide I need it.  All autocurrying does is sweep the
dirt under the carpet for someone else to deal with.

: class Foo {
:   has $.counter;
:   # multi postcircumfix:( ) makes me sick :(

Not sure it needs to be multi.  Generally a reference tells you exactly
who you're dispatching to.

:   method bar is default {
:  $.counter++;
:   }
: }
: 
: # emulating   10...
: $a = new Foo :counter(10);
: say $a.bar;
: say $a();

Probably want to handle list context as well.

: # other thingies:
: 
:  sub foo { ... };
:  @array = @foo # all the results of foo, lazily.

Don't see the need for that when

@array := foo()

does laziness implicitly already.  Maybe even

@array = foo()

maintains laziness if it sees an infinite iterator in the return
value of foo().  Or maybe it blows up and tells you to use :=
to avoid trying to make a copy.  That's probably cleaner.

: maybe  @array and @array()  could make a sense too:
: 
:   $fibonacci = {
:  state ($a, $b) = (1,1);
:  while $b 100 {
:($a,$b) = ($b, $b+$a);
:yield $a
:  }
:   }
: 
: (ah, that isn't very short and impressive.. I need to study a  course of  
: Design of Short and Impressive Examples, by  Damian or Mark-Jason,  
: maybe.)
: 
:   for @$fibonacci ... # or...
:   for $fibonacci ... # or...
:   for $fibonacci ...
: 
: interesting problem: how could we iterate through a list of iterators, one  
: by one, without flattening 'em?

By declaring it to be a Lazy list, whereupon the array view of the
list is the internal list of iterators (and any intermediate existing
scalar values).

: and the very last  and most important problem: I have no idea how we could  
: signal an end of sequence.

Just stop yielding things.  For an ordinary sub, return something finite.
For a gather, exit the gather.  In general, stop putting new iterators
or values on the Lazy you're building.

: 

Re: iterators and functions (and lists)

2004-12-04 Thread Matthew Walton
Larry Wall wrote:
: of course, that analogy isn't going to work for true functions, which  
: returns the same all the time, for some given set of arguments.

Oh, well, we pissed off the mathematicians long ago.  :-)
At least we had the sense to call them subroutines instead of functions.
Of course, that also upset the mathematicians, who wanted to call them
functions anyway.  Go figure.
That might be because the mathematicians haven't heard of a variant of a 
function which is allowed to have side effects yet.

Thank goodness the functional programming people have, otherwise Haskell 
would be pretty useless.

:  $fh(:chomp)
Yes, but in general I think an autochomper layer should be applied
to the handle/iterator at open/construction time, not at evaluation time.
That seems like a sensible approach. I see it as unlikely that I'm going 
to want to read a file in a mixture of chomped and not-chomped modes, so 
I'm going to want to set chomping on the filehandle. However that's done.

And if I *do* ever want to do mixed-chomping on a read, I should just 
open the file in non-chomped mode and chomp manually when I know I want 
to do it, because Perl won't be able to figure it out for me except in 
some really really weird circumstances I don't really want to be 
thinkinga bout.


: # what about making foo( :bar ) the same as
: #  foo.assuming( :bar) ? ah, that not gonna work.. but I
: # think that feature definitely wants something more short
: # than .assuming; maybe even some special syntactic honey.
: # because it's  fun(ny|ctional)
We made it long on purpose for readability.  You can always use a macro
to obfuscate it.  What we're *not* going to do is autocurry missing
parameters like Haskell.  That just screws up all the compiler's
expectations on return types.  If I forget to supply an argument, I
want an error, not a function pointer.  I can add in the .assuming
myself when I decide I need it.  All autocurrying does is sweep the
dirt under the carpet for someone else to deal with.
Yes, not really a Perlish thing is it? Haskell programmers cope with it 
because the entire type system explodes if you return a function instead 
of a value somewhere (by leaving out one or more arguments), but Perl's 
unlikely to do that with quite the same level of reliability, I would 
think. While I'm pleased that Perl allows me to pass functions around 
with almost the same ease as I get in Haskell, because Perl isn't a pure 
functional language, the thought of making it behave like that is quite 
scary.

: class Foo {
:   has $.counter;
:   # multi postcircumfix:( ) makes me sick :(
Not sure it needs to be multi.  Generally a reference tells you exactly
who you're dispatching to.
:   method bar is default {
:  $.counter++;
:   }
: }
: 
: # emulating   10...
: $a = new Foo :counter(10);
: say $a.bar;
: say $a();

Probably want to handle list context as well.
I'm sorry, but from a C++ background, overriding postcircumfix:( ) 
feels far more natural to me than setting 'is default' on some method. 
What if you do 'is default' on two methods? Compile-time error? What if 
you're opening up someone else's class and want to override the existing 
default (okay, so you shouldn't be doing that in an OOP world, but what 
if you are? What if you're like me and like Perl's delightful mishmash 
of paradigms while simultaneously liking other languages for their 
purity? What if I actually talk about something relevant?)

: # other thingies:
: 
:  sub foo { ... };
:  @array = @foo # all the results of foo, lazily.

Don't see the need for that when
@array := foo()
does laziness implicitly already.  Maybe even
@array = foo()
maintains laziness if it sees an infinite iterator in the return
value of foo().  Or maybe it blows up and tells you to use :=
to avoid trying to make a copy.  That's probably cleaner.
This is going to take me a while to get my head round... Does this 
particular foo() return an iterator? Or is it something which is 
iterated? Have I missed a bit of a synopsis or apocalypse which would 
make all this clear to me or are we still in handwaving mode?


Exceptions should not be used for
something so mundane as running out fo values.
Amen to that! One reason I ran screaming from Java was having to catch 
ArrayOutOfBoundsException all the time. And all those exceptions which 
the compiler forces you to catch. They're handy, but there is a limit. I 
prefer return values which can indicate if they're valid or not. undef 
is excellent for that :-)

A string pretending to be undef can be even better. Can we still do 
that? I seem to recall it being in something at some point along the way.

If that's necessary to keep the Lazy from blocking when it runs out
of values.  Just like an ordinary array, a Lazy has to be aware of
when it is out of values, and when it should call into some meta-Lazy
for more iterator values.  And I suppose that meta-Lazy could in
turn have a meta-meta-Lazy, which could have a