Anonymous Self-referential Datastructure Literals

2006-07-11 Thread Brad Bowman


Just some random thoughts about self-referential structures
and their literal representations:

$ perl -MData::Dumper -e '$a=[1,\$a]; print Dumper($a)'
$VAR1 = [
 1,
 \$VAR1
   ];

$ perl -MYAML -e '$a=[1,\$a]; print Dump($a)'
--- 1
- 1
- !perl/ref:
 =: *1

$ pugs -e 'my @a = (1,[EMAIL PROTECTED]); say @a.perl'
$_ := [1, \$_]

So the current pugs implementation is using $_ at compile time to
stitch the value together, is that right?

(Does the $_ binding need to be local/temp, even with $_'s new scoping
and the fact that this is a compile time thing?)

Are there any situations where a yaml-like literal representation
has an advantage over one that requires binding code?

The two main use cases would proabably be debugging and serialization.
For debugging .perl's fine, although many indirections in a more complex
structure may be tougher to decipher than a yaml style label.

Deserialization requires an eval anyway (unless there's some 
yet-to-be-invented hook to parse and return a literal only)

so the binding doesn't seem to matter.  The .perl method is
unlikely to be the serialization method of choice anyhow.

Nevertheless, I have a vague feeling that the YAML approach may 
be better in some way...


For another perspective:

$ python -c 'a=[1]; a.append(a); print repr(a)'
[1, [...]]

Ahem, time for the appropriate signature, 


Brad

--
There are times when a person gets carried away and talks on without
thinking too much. But this can be seen by observers when one's mind is
flippant and lacking truth. -- Hagakure http://bereft.net/hagakure/


Containers

2006-07-11 Thread Aaron Sherman
S02 and S06 discuss containers quite a bit. They say things like:

The is NAME (DATA) syntax defines traits on containers and
subroutines -S06

A variable object may itself be bound to a container type that
specifies how the container works without necessarily specifying
what kinds of things it contains. -S02

From this, I gather that it is our intention that containers have common
behaviors. In working on the Functions document (nominally S29), I've
come across some functions (such as Ceach, defined in S03), which are
not tied to specific container types, and probably want to be defined in
terms of the common container class.

Is it OK for me to arm-wave a CContainer class which can stand in for
any container type? For example:

 our List multi Container::each(Container [EMAIL PROTECTED])

Thoughts? Bad plan? I understand that there's some ambiguity here... it
might even be that Container is a role, not a class, or might be an
arm-wavy thing that abstracts some implementation details. I'm not
concerned about that just yet, I just need something to call these
things. Otherwise I have to put one definition for each of these
functions into the section for each type of container (too many
eaches...). I don't even have a section for things like Seq and Buf yet,
and I'd rather not if I don't have to.

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




Re: Containers

2006-07-11 Thread Jordan Kanter

I was having that problem too going over S09.  It seems like we need to get
the glossary together like Uri was saying that we can have a controlled
language for creating the documents.  If we dont have one already, I suggest
we start one.

Jordan

On 7/11/06, Aaron Sherman [EMAIL PROTECTED] wrote:


S02 and S06 discuss containers quite a bit. They say things like:

The is NAME (DATA) syntax defines traits on containers and
subroutines -S06

A variable object may itself be bound to a container type that
specifies how the container works without necessarily specifying
what kinds of things it contains. -S02

From this, I gather that it is our intention that containers have common
behaviors. In working on the Functions document (nominally S29), I've
come across some functions (such as Ceach, defined in S03), which are
not tied to specific container types, and probably want to be defined in
terms of the common container class.

Is it OK for me to arm-wave a CContainer class which can stand in for
any container type? For example:

our List multi Container::each(Container [EMAIL PROTECTED])

Thoughts? Bad plan? I understand that there's some ambiguity here... it
might even be that Container is a role, not a class, or might be an
arm-wavy thing that abstracts some implementation details. I'm not
concerned about that just yet, I just need something to call these
things. Otherwise I have to put one definition for each of these
functions into the section for each type of container (too many
eaches...). I don't even have a section for things like Seq and Buf yet,
and I'd rather not if I don't have to.

--
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback





Re: Containers

2006-07-11 Thread Aaron Sherman
On Tue, 2006-07-11 at 10:06 -0400, Aaron Sherman wrote:
 For example:
 
  our List multi Container::each(Container [EMAIL PROTECTED])

In thinking about each, I've come across an interesting need. I wrote
this example:

 for each(=; 1..*) - ($line, $lineno) {
   say $lineno: $line;
 }

Which is obviously an infinite loop. You could re-write that:

 for each(=; 1..*) - ($line, $lineno) {
   $line err last;
   say $lineno: $line;
 }

But would it be reasonable to also provide a named-only parameter to
each for that purpose?

 our List multi Container::each(Bool :$stop, Container [EMAIL PROTECTED])

So that:

 for each(:stop, =; 1..*) - ($line, $lineno) {
   say $lineno: $line;
 }

would only iterate until one of the containers was exhausted (in this
case, the filehandle).

Should this be added? Should zip have the same modifier?

-- 
Aaron Sherman [EMAIL PROTECTED]
Do you find yourself thinking Unicode has too many crosses? ✙✚✛✜✝✞✟✠☦☨☩†




Re: Containers

2006-07-11 Thread Aaron Sherman
On Tue, 2006-07-11 at 09:28 -0500, Jordan Kanter wrote:
 I was having that problem too going over S09.  It seems like we need to get
 the glossary together like Uri was saying that we can have a controlled
 language for creating the documents.  If we dont have one already, I suggest
 we start one.

Actually, I don't think we disagree on terminology (nor do the
synopses). The problem is that the types, as listed, don't fully fit the
terminology. This is to be expected, since we haven't fully fleshed out
the type tree yet.

That's why I said that Container might not be as real as it sounds. It
could just be a role, since many container-like things aren't going to
fall neatly into the Object - Container - Array/Hash type tree. Buf is
probably the best example of this, as a Buf is really a sort of scalar
with containerish behavior. Something like, class Buf is Scalar, does
Container. Which really blows some assumptions that I'm willing to bet
many people will make.

-- 
Aaron Sherman [EMAIL PROTECTED]



Re: Containers

2006-07-11 Thread Trey Harris

In a message dated Tue, 11 Jul 2006, Aaron Sherman writes:

But would it be reasonable to also provide a named-only parameter to
each for that purpose?

our List multi Container::each(Bool :$stop, Container [EMAIL PROTECTED])

So that:

for each(:stop, =; 1..*) - ($line, $lineno) {
  say $lineno: $line;
}

would only iterate until one of the containers was exhausted (in this
case, the filehandle).

Should this be added? Should zip have the same modifier?


It sounds reasonable to me, but :stop reads badly.  Maybe C:strictly? 
Maybe it's not a function of a flag to each, but a marking that certain 
lists should be tapped non-exhaustively:


  for each(=; :with(1..*)) - ($line, $lineno)

Where with is almost certainly the wrong word.  That way, you could 
write:


  for each(@queue1; @queue2; :with(1..*)) - $t1, $t2, $job_num {
  say Running job #$job_num;
  $proc1.run_task($t1); # Can deal with $t1 being undef
  $proc2.run_task($t2); # Ditto with $t2
  }

And you'll eat the rest of @queue1 or @queue2's elements even if they 
don't match up exactly.


This all makes me wonder if there's any problem with mixing and matching 
these loop modifying subs:


  for each(roundrobin(@queue1; @queue2); :with(1..*)) - $task, $job_num {
  say Running task {$task.id}(#$job_no);
  $task.run(:$job_num);
  }

I hope not.

Trey


Re: Containers

2006-07-11 Thread Aaron Sherman
On Tue, 2006-07-11 at 09:53 -0700, Trey Harris wrote:
 In a message dated Tue, 11 Jul 2006, Aaron Sherman writes:
  But would it be reasonable to also provide a named-only parameter to
  each for that purpose?

 It sounds reasonable to me, but :stop reads badly.  Maybe C:strictly? 
 Maybe it's not a function of a flag to each, but a marking that certain 
 lists should be tapped non-exhaustively:

:stop wasn't a great choice, but :with is going to be complicated. I
don't THINK there's such a thing as a named slurpy, so:

for each(=; :with(1..*)) - ($line, $lineno)

would have to be:

 for each(=, :with(1..*))

with the signature:

 (Container :@with, Container [EMAIL PROTECTED])

I think

But I don't think that will do, because it fails when you don't know
WHICH list would be the longest (or you have to specify them all
as :with, and that's rather counter-intuitive). Perhaps a stand-alone
adverb, :parity makes more sense.

Unless there's an obvious problem with it, let's go with :parity for
now, and we can change it if its usage becomes confusing.

 This all makes me wonder if there's any problem with mixing and matching 
 these loop modifying subs:
 
for each(roundrobin(@queue1; @queue2); :with(1..*)) - $task, $job_num {
say Running task {$task.id}(#$job_no);
$task.run(:$job_num);
}
 
 I hope not.

This makes me re-think each a bit... it might have to return an
iterator:

 our Iterator multi Container::each (Bool :$parity , Container [EMAIL 
PROTECTED] )

Given that, you could string eaches all you like, but otherwise it's not
terribly useful.

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




Re: Containers

2006-07-11 Thread Trey Harris

In a message dated Tue, 11 Jul 2006, Aaron Sherman writes:

On Tue, 2006-07-11 at 09:53 -0700, Trey Harris wrote:

It sounds reasonable to me, but :stop reads badly.  Maybe C:strictly?
Maybe it's not a function of a flag to each, but a marking that certain
lists should be tapped non-exhaustively:


:stop wasn't a great choice, but :with is going to be complicated. I
don't THINK there's such a thing as a named slurpy, so:


   for each(=; :with(1..*)) - ($line, $lineno)


would have to be:

for each(=, :with(1..*))

with the signature:

(Container :@with, Container [EMAIL PROTECTED])

I think

But I don't think that will do, because it fails when you don't know
WHICH list would be the longest (or you have to specify them all
as :with, and that's rather counter-intuitive). Perhaps a stand-alone
adverb, :parity makes more sense.


I don't understand how the word parity is being used here...  It's not 
in the mathematical sense of even vs. odd, nor in the telecomm sense of 
bit-counting (since one would want to stop if one out of four iterators 
stopped generating, but also if two out of four did).  In the colloquial 
sense of parity meaning equality amongst peers, perhaps it makes more 
sense, but it's a rather overloaded an poorly-understood word, IMHO.



Unless there's an obvious problem with it, let's go with :parity for
now, and we can change it if its usage becomes confusing.


I think both are needed, somehow.  The default behavior of each should be 
as before (returning undef as necessary).  If the boolean switch (:stop, 
:parity, whatever) is set, then each should stop generating as soon as any 
argument stops generating.  I'm not denying that need.  But I'm saying 
that there is also a need for a mixed-case usage.


This is another one of those cases where you have to have at least three 
items to see a difference, at (0|1|2)-ary the semantic differences 
collapse.


One would like to be able to say all of stop once this iterator runs out 
(these adverb names are intentionally awful):


   for each(:stop_on_exhaustion(=), @line_id_cookies; 1..*)

Stop when anything besides this iterator runs out:

   for each(=; @lines_to_merge; :attach_as_needed(1..*))

Stop when any iterator runs out:

   for each(:stop, @subjects; @objects; @verbs) - $s, $o, $v


This all makes me wonder if there's any problem with mixing and matching
these loop modifying subs:

   for each(roundrobin(@queue1; @queue2); :with(1..*)) - $task, $job_num {
   say Running task {$task.id}(#$job_no);
   $task.run(:$job_num);
   }

I hope not.


This makes me re-think each a bit... it might have to return an
iterator:

our Iterator multi Container::each (Bool :$parity , Container [EMAIL PROTECTED] 
)

Given that, you could string eaches all you like, but otherwise it's not
terribly useful.


They need to chain and nest intelligently.

Trey


Re: Containers

2006-07-11 Thread Aaron Sherman
On Tue, 2006-07-11 at 12:50 -0700, Trey Harris wrote:

  But I don't think that will do, because it fails when you don't know
  WHICH list would be the longest (or you have to specify them all
  as :with, and that's rather counter-intuitive). Perhaps a stand-alone
  adverb, :parity makes more sense.
 
 I don't understand how the word parity is being used here...  It's not 
 in the mathematical sense of even vs. odd, nor in the telecomm sense of 
 bit-counting (since one would want to stop if one out of four iterators 
 stopped generating, but also if two out of four did).  In the colloquial 
 sense of parity meaning equality amongst peers, perhaps it makes more 
 sense, but it's a rather overloaded an poorly-understood word, IMHO.

Yeah, I see your problem. I WAS using the equality amongst peers
definition, but you're probably right that there's too much baggage.

Having read and digested the rest of your mail and your comments on IRC,
let me propose (as I did on IRC before you had to run):

 zip(:fewest, @a;@b;@c); # Until one runs out
 zip(:finite, @a;@b;@c); # Stop if only known-infinite ranges are left
 roundrobin(:most, @a;@b;@c); # Include undefs until all arrays empty
 zip(@a;@b:fewest;@c); # empty @b, then stop.
 zip(@a:fewest;@b;@c:fewest); # stop when non - @b is empty
 zip(@a:fewest;@b:fewest;@c:fewest); # Same as stand-alone :fewest
 roundrobin(@a;@b:most;@c); # fill in undefs for @b until @a,@c empty
 roundrobin(@a:most;@b;@c:most); # fill in undefs for all but @b
 roundrobin(@a:most;@b:most;@c:most); # Same as stand-alone :most

I think that covers all of the bases that I, you and Larry proposed.

I'm still not clear on how :fewest and :most modify a container, but I'm
convinced that once I make sense of it, there will be other ways in
which I want to use that modifier.

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




Re: Containers

2006-07-11 Thread Aaron Sherman
On Tue, 2006-07-11 at 16:22 -0400, Aaron Sherman wrote:

  zip(:fewest, @a;@b;@c); # Until one runs out

Once again, I missed some Larry magic. He already selected :shortest
for this, so I guess on roundrobin, it's :longest... ignore my
choices.

I think just like Larry, but 1,000 times slower and less patient ;-)

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




S?? OS interaction, POSIX and S29

2006-07-11 Thread Aaron Sherman
There's a bit at the end of the current S29:

 =item A/S??: OS Interaction

I've taken on a few of these, and in doing so found that I was making
some assumptions. I'd like to share those and see if they make sense:

  * POSIX will be a low-level module that slavishly reproduces the
POSIX interfaces as closely as possible (perhaps moreso than
Perl 5)
  * OS, or whatever we call the core OS interaction module, will
have an interface which is entirely driven by Perl 6 and may not
resemble POSIX much at all.
  * OS will use POSIX to implement its functionality, so only POSIX
need know how to get at the lowest level.

Will that be reasonable? Am I stomping on anything?

I'm writing up both an example implementation and an API for OS,
starting with the support needed for getpw just as an arbitrary example,
and trying to feel out where the line between S29 and that document
are There's some overlap, but I want to keep it minimal.

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




Re: S?? OS interaction, POSIX and S29

2006-07-11 Thread Yuval Kogman
On Tue, Jul 11, 2006 at 16:46:40 -0400, Aaron Sherman wrote:
 There's a bit at the end of the current S29:
 
  =item A/S??: OS Interaction
 
 I've taken on a few of these, and in doing so found that I was making
 some assumptions. I'd like to share those and see if they make sense:
 
   * POSIX will be a low-level module that slavishly reproduces the
 POSIX interfaces as closely as possible (perhaps moreso than
 Perl 5)
   * OS, or whatever we call the core OS interaction module, will
 have an interface which is entirely driven by Perl 6 and may not
 resemble POSIX much at all.
   * OS will use POSIX to implement its functionality, so only POSIX
 need know how to get at the lowest level.
 
 Will that be reasonable? Am I stomping on anything?

I think OS is kind of bad.

Perl 6 is designed to be embeddable, retargetable, etc.

Sometimes the environment well be JS like, that is you have
(possibly) readonly environment calls (gettimeofday, etc), but not
others (IO)...

Ideally I would like to have something more partitioned, and with a
less binding name than OS.

That said, there's no reason why there shouldn't be a convenience
wrapper around a more partitioned set of APIs, that provides a more
toolchain like approach, and keeps the docs together.

-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgpa4KWeuv2pQ.pgp
Description: PGP signature