Re: Some Things I'd Like To Do With Pod

2007-06-24 Thread Piers Cawley

On 22/06/07, brian d foy [EMAIL PROTECTED] wrote:

===Per class documentation, not per file documentation

Related to the one above, I'd like to have NAME, SYNOPSIS, etc. for
each class, not just per file. Well, what I really want is the
Smalltalk class and method browsers, but I know I'm not going to get
those.


I'm sure it's going to be great deal easier to implement such a tool
in Perl 6 than it is in Perl 5 though. It's just not going to be in
the core. And even if it's not going to be easy, I can think of at
least one person who is going to have a bloody good go at implementing
it.

With apologies if I'm teaching my grandma to suck eggs here.


Re: Selective String Interpolation

2006-02-18 Thread Piers Cawley
Damian Conway [EMAIL PROTECTED] writes:

 Brad Bowman asked:

 When building code strings in Perl 5 I usually write the code,
 then wrap it in double quotes, then \ escape everything light blue
 under syntax highlighting.  I was wondering if there'll a better
 way in Perl 6. I thought it would be nice to define the variables
 you wish to
 interpolate individually, perhaps as extensions to the :s, :a,
 etc quote adverbs, perhaps using a signature object.

 There is already a mechanism for this. You simply turn off all
 variable interpolation, and interpolate any the variables you wish to
 interpolate via block interpolations. Or, more simply, only turn on
 block interpolation in a non-interpolating string:

  my $code = q:c{
  package {$package_name};

  sub {$sub_name} \{
 return {$return_val}
  \}
  };

The problem here is that sometimes (especially in code generation) you
don't really want to interpolate the stringification of a value, you
just want the value itself. I've been struggling with this slightly
when I've been writing code generation methods in Ruby. Where, in
Scheme or lisp you'd simply use some combination of C`, C, and
C,@, in Ruby you end up having to store values somewhere in the
binding that will be accessed by your compiled code; which would be
fine if (again, as with Lisp macros) you could generate what I tend to
think of as an anonymous symbol to bind the value to:

   my $anon_symbol = gensym
   my ${$anon_symbol} = $the_complex_value_we_want_to_use_in_generated_code

   my $code = q:c{
   package {$package_name};

   sub {$sub_name} \{
   return ${$anon_symbol}
   \}
   };

And backwhacking braces in generated code is *not* a pretty solution
to my eyes. I'd *like* to be able to have a quasiquoting environment
along the lines of lisp's backquote (though I'm not sure about the
unquoting syntax):

   my $code = q:`{
   package ,$package_name;

   sub ,$sub_name {
   ,$the_complex_value_we_want_to_use_in_generated_code 
   }
   
   sub ,$another_sub_name {
   ,[EMAIL PROTECTED](';')}
   }
   };

Whatever we go with, we need a quoting mechanism that returns a parse
tree rather than a simple string if we want to deal with interpolating
complex values (especially if we don't want to have to worry about
what, if any, quotes are needed round some of our interpolated values.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Perl 6 OO and bless

2006-01-23 Thread Piers Cawley
John Siracusa [EMAIL PROTECTED] writes:

 On 1/18/06 11:06 PM, Rob Kinyon wrote:
 Not to mention that 90% of the hacking done in Class:: and Object:: will
 handled by the fact that Perl6 has actual OO syntax. (Look Ma, no hands!)
 You won't need Class::MakeMethods because Perl6 will make your accessors for
 you.

 There's more to life than simple get/set accessors.  Method-makers will have
 and a long and glorious life in Perl 6, I assure you :)

I refer the interested reader to all the handy dandy method makers
(and other tricksy class methods) to be found in the Ruby on Rails
framework... 

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: relationship between slurpy parameters and named args?

2005-12-30 Thread Piers Cawley
Stuart Cook [EMAIL PROTECTED] writes:

 On 29/12/05, Austin Frank [EMAIL PROTECTED] wrote:
 So, is there a conceptual connection between imposing named argument
 interpretation on pairs in an arg list and slurping up the end of a
 parameter list?  Are there other meanings of prefix:* that relate to
 one or the other of these two meanings?

 The missing link is that prefix:* in an argument list also causes
 things like arrays to be treated as a sequence of separate parameters,
 rather than as a single array parameter.  See Flattening argument
 lists in S06.

 (This was the original meaning of prefix:* in arglists; the
 named-pair behaviour was added later, when pair values ceased to have
 named behaviour automatically.)

Personally, I think that prefix * in an arglist should only flatten
array arguments if there is only one array. And if it doesn't, how do
I declare parameter that is 'a slurpy list of arrays' or 'the rest
of the arguments, without flattening'. If I *really* want aggressive
flattening then I can call, say, @slurpy_param.flatten


-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Journal moved.

2005-12-28 Thread Piers Cawley
Audrey Tang (autrijus) [EMAIL PROTECTED] writes:

[...]

 I am not sure how much (if any) of this should be cross-posted to P6C...
 Would the list subscribers be interested in getting them in email form,
 in addition to the current blog format?

It'd certainly make it easier for this summary writer if they appeared
in the same inbox as the rest of p6c. 

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: relational data models and Perl 6

2005-12-18 Thread Piers Cawley
Rob Kinyon [EMAIL PROTECTED] writes:

 On 12/16/05, Ovid [EMAIL PROTECTED] wrote:
 Minor nit:  we're discussing to the relational algebra and not the
 relational Calculus (unless the topic changed and I wasn't paying
 attention.  I wouldn't be surprised :)

 Algebra, in general, is a specific form of calculus. So, we're
 speaking of the same thing, just in different terms.

Umm... I think you have that relationship the wrong way around.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: statement_controlfoo()

2005-11-30 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 On Tue, Nov 22, 2005 at 10:12:00AM +0100, Michele Dondi wrote:
 : Oh, I'm not the person you were responding to, and probably the less 
 : entitled one to speak in the name of everyone else here, but I feel like 
 : doing so to say that in all earnestness I'm quite sure no one took any 
 : offense out of your words. Despite the slight harshness, they're above all 
 : witty. Just as usual: and that's the style we all like!


$fh = open '', 'quotefile' or fail;
$fh.print 'EOQ'
I like witty sayings as much as the next guy, but wit can hurt when
misdirected.  If people want me to be machine for cranking out quote
file fodder, I'll do my best.  But I also care about my friends.

Larry
EOQ

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Perl6 perlplexities

2005-11-15 Thread Piers Cawley
Rob Kinyon [EMAIL PROTECTED] writes:
 First-class blocks make continuations and coros almost neglible to
 implement from an API perspective. Almost makes me wonder how much
 trouble it would be to implement this in P5 ...

Um... tosh. Seriously. Full continuations need some fairly serious retooling of
the call stack if they are to work properly. And one shot continuations are the
next best thing to useless.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Perl6 perlplexities

2005-11-04 Thread Piers Cawley
Juerd [EMAIL PROTECTED] writes:

 Michele Dondi skribis 2005-11-04 14:58 (+0100):
 Let me explain: we all know that Perl5 has a very simple parameter
 passing mechanism for subs and an even more rudimentary
 {prototyping,signature} mechanism that one actually seldom uses.

 It is unused because it sucks. /blunt

 With this simple mechanism one can implement or fake quite a lot of
 parameter passing paradigms.

 And it is a lot of work to do so.

 for simple subs in Perl6 I will probably still use @_

 You'd be a fool to do so, with the sole exception of list manipulation,
 which at least in my codebase isn't used quite that much, and almost
 never listens to the qualification simple sub.

 Compare:

 sub dosomething { @_[0] blah @_[1] }

 sub dosomething ($a, $b) { $a blah $b }

 sub dosomething { $^a blah $^b }

 The @_ solution is really the most ugly and hard to type of the three
 possibilities.

 err... that or the new pointy subs which are indeed so cool!

 Cool, but probably not a good idea for named subs, if only for style.

 our dosomething ::= - $a, $b { $a blah $b }

 Not really a winner in any perspective.

And the return semantics of pointy blocks are different, you have to be careful
about doing an explicit return in them because that returns to the caller of
the lexical scope in which they were defined (otherwise for ... - ... {...}
wouldn't work)

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Perl6 perlplexities

2005-11-04 Thread Piers Cawley
Rob Kinyon [EMAIL PROTECTED] writes:

 On 11/4/05, Michele Dondi [EMAIL PROTECTED] wrote:
 I'm still convinced my remark _partly_ applies in the sense that the
 overall impression is that a vast majority of most common needs is
 addressed by a *subset* of the current features and trying to stuff all
 them in has brought in quite a lot of discussions of which I'm not even
 sure if they've all settled down.

 I think a good comparison can be made to Ruby. For work, I've been
 learning Ruby this past week (we're going to try out Rails to see if
 we like it). As my colleague put it, Ruby has all the P6 features we
 want and it's usable now.

 Ruby's OO system is 1000% more complex that Perl5's. Yet, it's still a
 net win. For one thing, I don't have to write the following anymore
 (lifted from a CPAN module I am working on):

The thing about Ruby (and Perl 6's) OO system is that the complexity is in the
right place -- tucked away where most people don't have to worry about it until
they want to do something complex.

 sub children {
 my $self = shift;
 if ( caller-isa( __PACKAGE__ ) || $self-isa( scalar(caller) ) ) {
 return wantarray ? @{$self-{_children}} : $self-{_children};
 }
 else {
 return @{$self-{_children}};
 }
 }

 This is in a vain attempt to implement a protected subroutine. In
 fact, I really want a private writing accessor with a public reading
 accessor, but have absolutely no way to implement that.

 Why do I want such a beast? Because I want to GUARANTEE in an absolute
 kind of way that, unless my user truly intended to do so, he's not
 going to be able to accidentally screw up my internal state.

And when your user does want to, essentially say Nah, you screwed up designing
that object protocol, children shouldn't've been protected. it's the work of a
moment to write:

   thing.send(:children, *args)

 (Oh, and Ruby has first-class block. W00T!)

And continuations. But continuations are scary. Good scary, but still scary.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: All tests successful considered harmful

2005-11-01 Thread Piers Cawley
chromatic [EMAIL PROTECTED] writes:

 On Thu, 2005-10-27 at 10:26 -0700, jerry gay wrote:

 we're missing some parts of a testing framework. we don't have the
 ability to write test files in PIR, so we're dependent on a perl
 install for testing. perl's a great language for writing tests anyway,
 and right now we're dependent on perl for parrot's configure and build
 as well. that said, breaking this dependency will make parrot just a
 bit closer to standing on its own.

 We have a Test::Builder port in PIR.  I will move up my plan to port
 Parrot::Test to use it.

Somewhere I have the beginnings of an xUnit style 'parrotunit' testing
framework, but that was written ages ago, so I'd need to start it again, but it
wasn't that hard to implement.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Proposal to make class method non-inheritable

2005-10-14 Thread Piers Cawley
Stevan Little [EMAIL PROTECTED] writes:

 Piers,

 On Oct 12, 2005, at 5:22 AM, Piers Cawley wrote:
 We definitely have two instances of A since, B.isa(::A). We also have
 a fragile implementation of count.

 :)

 Sorry, I purposefully made it a kludge as that is usually the way the  example
 is shown in most tutorials about class methods.

So, let me see if I have this straight here. You're arguing that, because
people are often foolish, we should make it harder to be clever? And you're
using a deliberately broken example as grist to your mill?

Doesn't sound all that Perlish to me.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Roles and Trust

2005-10-13 Thread Piers Cawley
Ovid [EMAIL PROTECTED] writes:

 --- Piers Cawley [EMAIL PROTECTED] wrote:
 
 How about:
 
   my method SCALAR::attributes($self:) { $$self }
   my method HASH::attributes(%self:) { %self.kv }
   my method ARRAY::attributes(@self:) { [EMAIL PROTECTED] }
 
   method _attributes($attrs) {
 my @attributes = $attrs.attributes
 return @attributes[0] if @attributes == 1;
 ...
   }
 
 Assuming it's legal.

 Just saw this.  Sorry for the late reply.

 At first that gave me the willies, then I noticed the my on the
 front.  I assume because of the my on there that this would affect
 those data types only locally?  That seems like it would be a nice
 compromise.

 Is this legal syntax?

After some discussion on #perl6, we thought probably not (unless
@Larry rules otherwise). However, 

  my multi attributes( Scalar $scalar: ) { $$scalar }
  my multi attributes( Hash %hash: ) { %hash.kv }
  my multi attributes( Array @array: )   { [EMAIL PROTECTED]  }

definitely is legal (though it does rather suffer from the end-weight
problem to my way of thinking).

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Proposal to make class method non-inheritable

2005-10-12 Thread Piers Cawley
Stevan Little [EMAIL PROTECTED] writes:

 Hello all.

 I would like to propose that class methods do not get inherited along
 normal class lines.

 I think that inheriting class methods will, in many cases, not DWIM.
 This is largely because your are inheriting behavior, and not state
 (since class attributes are not inheritable). Let me explain in more
 detail.

 Let's start by making a very basic definition of an *object*,
 ignoring any implementation details or specifics.

object == state + behavior

 This statement assumes that *objects* at their core are a unique
 state coupled with a collection of behaviors to act upon that
 particular state. Of course we are ignoring all the other class/meta/
 inheritence junk for now.

 To take away the behavior, and only be left with state would degrade
 our object to the level of C struct or Pascal-style record-type. To
 take away the state, and only be left with behavior, would basically
 leave a module/package or some pseudo-random collection of functions.

 So at this point, I think it is safe to say that an *object* should
 have both state and behavior.

 Now, back down from the theoretical cloud to reality. I would like to
 show some canonical class-method examples (and in some cases, show
 how they are broken), then show how they might be better accomplished
 in Perl 6 without the need for class methods to be inherited.

 == Instance Counting Class

 The most common example given for class methods is an instance
 counter. Here is how one might (naively) look in Perl 6:

 class A {
  our $.count;
  method count (Class $c:) { $.count; }
  submethod BUILD {
  $.count++;
  }
 }

 Each time an instance of A is created the counter is incremented. So
 that ...

 A.count; # 0
 A.new;
 A.count; # 1

 Now this makes sense, until we subclass A.

 class B is A {}

 A.count; # still 1
 B.new; # calls A::BUILD

 A.count; # 2
 B.count; # 2

 Clearly, we only have one instance of A, and one instance of B, so
 those numbers are wrong. It could be argued that since B is a subtype
 of A, we do have two A's, but the argument does not work in reverse.
 But either way, I would argue that the results shown above are
 misleading, and probably not what the programmer intended.

We definitely have two instances of A since, B.isa(::A). We also have
a fragile implementation of count.

  class A {
our %.count_of

method count (Class $c:) { %.count_of{$c} }

method BUILD {
  $class = ($?SELF.class)

  @countable_ancestors = $class.ancestors.uniq.grep :{.isa(::A)}

  for $class, [EMAIL PROTECTED] - $c { %.count_of{$c}++ }
}

Where we're assuming I've got the syntax of 'for' right, and that
'ancestors' is a class method that returns all of a class's
ancestors. This might not work too well in the face of a dynamic
inheritance tree, but it should be possible to work around. Something
like this might work:

   Class A {
 our %.instance_count_of

 method count (Class $c: ?$with_descendents = undef) {
   my @interesting_classes = $c;
   if $with_descendents {
 push @interesting_classes, *($c.all_subclasses);
   }
   [+] %.instance_count_of(@interesting_classes)
 }

 method BUILD {
   %.instance_count_of($?SELF.class)
 }
   }

Where we're assuming that a class can find all its subclasses 

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Roles and Trust

2005-10-10 Thread Piers Cawley
Ovid [EMAIL PROTECTED] writes:

 Apocalypse 12 has the following to say about roles and trust
 (http://www.perl.com/pub/a/2004/04/16/a12.html?page=10)

   It's not clear whether roles should be allowed to grant
   trust. In the absence of evidence to the contrary, I'm 
   inclined to say not.

 In Perl 5, I recently found myself in the annoying position of having a
 method which could accept scalar, array, or hash references.  My
 primary code looked similar to this (simplified for clarity):

   sub _attributes {
 my ($self, $attrs) = @_;
 return $$attrs if UNIVERSAL::isa( $attrs, 'SCALAR' );

 my @attributes = UNIVERSAL::isa( $attrs, 'HASH' ) 
   ? %$attrs : @$attrs;
 return unless @attributes;
 # more code here
   }

 This was a private method, but $attrs is an argument that is passed in
 by the person using my class.  It would be nice if I could just assign
 an attributes role to the SCALAR, ARRAY, and HASH classes and say
 that only my class could see the method(s) it provides.  Thus, my
 caller would be blissfully unaware that I am doing this:

   $attrs-attributes; # even if it's an array reference

How about:

  my method SCALAR::attributes($self:) { $$self }
  my method HASH::attributes(%self:) { %self.kv }
  my method ARRAY::attributes(@self:) { [EMAIL PROTECTED] }

  method _attributes($attrs) {
my @attributes = $attrs.attributes
return @attributes[0] if @attributes == 1;
...
  }

Assuming it's legal.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Exceptuations

2005-10-06 Thread Piers Cawley
Peter Haworth [EMAIL PROTECTED] writes:

 On Wed, 5 Oct 2005 19:24:47 +0200, Yuval Kogman wrote:
 On Wed, Oct 05, 2005 at 16:57:51 +0100, Peter Haworth wrote:
  On Mon, 26 Sep 2005 20:17:05 +0200, TSa wrote:
   Piers Cawley wrote:
   Exactly which exception is continued?
The bottommost one. If you want to return to somewhere up its call
chain, do:
   
  $!.caller(n).continue(42)
  
   Whow, how does a higher level exception catcher *in general* know
   what type it should return and how to construct it? The innocent
   foo() caller shouldn't bother about a quux() somewhere down the line
   of command. Much less of its innards.
  
  Well said.
 
 No! Not well said at all!

 Sorry, I misread that. I thought I was agreeng with how does a higher
 level exception catcher know what to change in order to make resuming the
 continuation useful?, especially in the light of Piers saying that the
 bottom-most exception should be the one resumed.

I'm sorry, we appear to have lost some kind of context, the original example
given only had one exception thrown, but it got propagated up through a long
call chain. At no point did anything catch the original exception and
rethrow. If they had, you're absolutely correct in asserting that by default
things should resume from the point of the outermost rethrow. A brave exception
catcher (or more likely programmer with a debugger) might want to crack that
exception open and examine its inner exceptions, but in general that's not
going to be safe.

The scary syntax proposed above is, again, the sort of thing that might be
useful in a debugger I don't really care about the inner workings of these
helper functions, I just want 'open' to return this mocked handle. (actually
in that case, being able to do $!.caller(open).continue(MockIO.new), where
'caller open' looks up the call chain for the lowest call to open and returns
that continuation would be rather neat)

 The highest level exception is the only one a caller has any right to deal
 with, but even then it doesn't really know what will happen if it resumes
 some random continuation attached to the exception.

Oh stop with the 'rights'. And it's not dealing with a 'random' continuation,
if it's going to resume it should be damned careful about which exceptions it
resumes from; you don't just go around doing CATCH {...; $!.continue(...)}, you
do CATCH SomeSpecificKindOfResumableException { ...; $!.continue(...)}. And, in
general, you don't do that either, because in the average program you catch the
exception at a point where you can simply return a sensible default to your
caller. Resumable exceptions come into their own, however, when you're
debugging. I can envisage doing:

  perl6 -debug::on::error some_script

And have it run along happily until an exception gets propagated up to the top
level, at which point the debugger swings into action and uses the continuation
to tunnel back to the point at which the exception was thrown so the programmer
can inspect the program state, possibly fix things up, return something
sensible and carry on.

  CATCH {
  when some_kind_of_error {
  $!.continue($appropriate_value_for_some_kind_of_error)
  }
  }

 That just gives me the willies, I'm afraid.

It doesn't amuse me that much, unless whatever generates
$appropriate_value_for_some_kind_of_error is very, very smart indeed. But, as
I've said above, that's not really where resumable exceptions shine.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Exceptuations

2005-09-30 Thread Piers Cawley
TSa [EMAIL PROTECTED] writes:
 BTW, I would call *intentional* exceptions terrorism.

So that would be all exceptions then. They all get implemented somewhere, even
the ones that get thrown by builtins.

  CATCH Exception { say Why do you hate freedom? }

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: This week's summary

2005-09-27 Thread Piers Cawley
TSa [EMAIL PROTECTED] writes:

 HaloO,

 The Perl 6 Summarizer wrote:
 Meanwhile, in perl6-language
   \(...)
 Oh look, a thread in p6l that's still going more than a fortnight later.
 How unusual.

 Is a long running thread considered a bad thing on this list?

Nah, it's just hard to summarise.

 I have grasped so far, that spawning a new thread after
 some divergence from the original topic is considered nice.

Definitely.

 This particular instance of the form is nominally about the
 behaviour of \($a, $b) but various subthreads have drifted onto
 discussions of context in general and meaningful whitespace. So far
 there has been no discussion of the return value of
 Pin.head.contents.grep - Angel $a {$a.is_dancing} but I'm sure it's
 only a matter of time.

 Please tell me if the particular pinhead is me. I'm actually about to reply
 to Juerds question about my ranting about code backing the interpolation
 of data into strings. Or is that considered counter productive
 hairsplitting?

Just a reference to the old philosophical question of how many angels can dance
on the head of a pin. That and the fact that I occasionally get curmudgeonly
and hit the send button before I have second thoughts.

The weird thing is that the syntax I rolled there is soon to be the topic of an
original thread, once I've got the thing written up a little more.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: loadlib and libraries with '.' in the name

2005-09-26 Thread Piers Cawley
Joshua Juran [EMAIL PROTECTED] writes:

 On Sep 23, 2005, at 3:47 AM, Leopold Toetsch wrote:

 On Sep 23, 2005, at 7:51, Ross McFarland wrote:

 i was planning on playing around with gtk+ bindings and parrot and went
 about looking around for the work that had already been done and didn't turn
 anything up. if anyone knows where i can find it or who i should talk to i
 would appreciate that info as well.

 Google for NCI gtk. There is also a weekly summary entry but the xrl.us
 shortcut seems to have expired.

 I was wondering about that.  I Googled for tinyurl considered harmful and 
 was
 surprised to find only one message, discussing the phishing risks.  I found no
 mention of the risk of outsourcing a bottleneck to a third party who has zero
 obligation or direct interest to continue providing the service.

  From http://metamark.net/about#expire:

 Do Metamark links expire?

 The Metamark urls expire after five years or two years after the last usage -
 whichever comes later. However, if a link is never used, it will expire after
 two years. This should mean that as long as a link is on a public page, some
 search engine will visit it and keep it alive.

 Of course, this is subject to change and is no promise but just my intentions
 as of this writing. If you want guarantees you can make your own service.

 To be quite frank, I'm astonished the practice exists here in the first place.
 In my opinion it goes directly against the spirit of the Web envisioned by Tim
 Berners-Lee.  A better practice would be to post long URL's within angled
 brackets.  And there's no reason you can't do both, either.

Which is why the archived summaries at deve.perl.org and perl.com all use the
long form URLs. The metamarked URLs only ever appear as a convenience for
readers on the mailing list. I am not about to start polluting my mailed
summaries with such monstrosities as

http://groups.google.com/[EMAIL PROTECTED]

any time soon. You're welcome to write your own summaries that do use the full
URLs of course. Or, if it bothers you that much, write something to run from
cron once a month or so that grabs shortened summary URLs and does a simple GET
on them.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Sort of do it once feature request...

2005-09-26 Thread Piers Cawley
Michele Dondi [EMAIL PROTECTED] writes:

 Every time I've desired a feature for Perl6 it has turned out that either it
 was already planned to be there or I have been given good resons why it would
 have been better not be there.

And you've done it again. What you ask for is already there. See below.


 Now in Perl(5) {forum,newsgroup}s you can often see people doing stuff like

my @files=grep !/^\.{1,2}/, readdir $dir;

 Letting aside the fact that in the 99% of times they're plainly reinventing 
 the
 wheel of glob() a.k.a. File::Glob, there are indeed situations in which one 
 may
 have stuff like

 for (@foo) {
next if $_ eq 'boo';
# do something useful here
 }

  for @foo {
next if (($_ ne 'boo')..undef)
# do something useful
  }

 whereas they know in advance that Cif can succeed at most once (e.g. foo
 could really be Ckeys %hash).

 Or another case is this:

 while () {
  if (@buffer  MAX) {
  push @buffer, $_;
  next;
  }
  # ...
  shift @buffer;
  push @buffer, $_;
 }

  while  {
 if 0..MAX { push @buffer, $_; next }
  end

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Exceptuations

2005-09-26 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 9/25/05, Yuval Kogman [EMAIL PROTECTED] wrote:
 I propose a new model - each exception has a continuation that
 allows it to be unfatalized.

 I think we've already talked about something like this.  But in the
 presence of use fatal, it makes a lot more sense.

 Something comes to mind:

 use fatal;
 sub foo()  { bar()  }
 sub bar()  { baz()  }
 sub baz()  { quux() }
 sub quux() { fail }
 {
 say foo();
 CATCH { $!.continue(42) }
 }

 Exactly which exception is continued?

The bottommost one. If you want to return to somewhere up its call chain, do:

  $!.caller(n).continue(42)

Assuming caller returns a continuation (which I still fondly hope it will). I'm
assuming you're examples aren't necessarily tail calls of course. 


 Where do we cut off the call chain and replace our own value?  This comes up
 again with open().  Let's say open is implemented with a series of five
 nested calls, the innermost which knows how to fail and propagate outwards.
 However, the programmer using open() has no idea of its internals, so it
 ought to override the return value of open() itself, rather than its utility
 functions.  However, we can't go with outermost, because then you'd only be
 fixing the lexical call (say foo() above).  So it's somewhere in between.
 Where?

Obviously the topmost function should do:

  sub open(...) {
...
CATCH { $!.rethrow }
  }

This assumes that 'rethrow' throws a new exception that delegates to the
original exception for lots of its behaviour. If, later, you want to explicitly
get at the exception thrown by the helper function, you could do something
like:

   $!.inner

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Exceptuations

2005-09-26 Thread Piers Cawley
TSa [EMAIL PROTECTED] writes:

 HaloO,

 Piers Cawley wrote:
Exactly which exception is continued?
 The bottommost one. If you want to return to somewhere up its call chain, do:
   $!.caller(n).continue(42)

 Whow, how does a higher level exception catcher *in general* know
 what type it should return and how to construct it.

It asks the continuation? The information should be there. Consider a function
definition:

  sub whatever(...) returns List {
throw ResumableException;
  }

Then, assuming that caller returns continuation -- which is a pretty big
assumption, but which would be really cool -- $!.caller(1) would be a
continuation with an signature of (List $not_a_real_name). If the function can
return several types dependent on context, then the continuation's signature
would be the appropriate one for the context in which the function was
called. Monkeying with this kind of thing in code isn't necessarily a good
idea, but it's great for, for instance, having a top level exception catcher
that could (potentially) bring up an interactive shell with limited debugging
features which would allow you to inspect the running program and work out what
went wrong. Ruby on Rails already does something like this, with the added
wrinkle that, if it hits a breakpoint when running in the server it hands off
the interactive session to a console process rather than having you monkey with
it within your browser. A very neat trick and a remarkably powerful debugging
technique. 


 The inocent foo() caller shouldn't bother about a quux() somewhere down the
 line of command. Much less of it innards.

 Think of receiving a 'shelf picker died of lung cancer' exception when you
 just ordered a book from your favorite book dealer. Irrespective of the
 seriousness to the shelf picker, but how would you expect a customer to
 handle such an exception?

I wouldn't, but I would expect that a programmer would find such an exception
very useful indeed.

-- 
Piers Cawley [EMAIL PROTECTED]
http://www.bofh.org.uk/


Re: Do slurpy parameters auto-flatten arrays?

2005-08-03 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 7/26/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
 Hi,
 
 are the following assumptions correct?
 
   sub foo ([EMAIL PROTECTED]) { @args[0] }
 
   say ~foo(a, b, c); # a

 Yep.

   my @array = a b c d;
   say ~foo(@array);# a b c d (or a?)
   say ~foo(@array, z);   # a b c d (or a?)

 a for both of these.  The *@ area behaves just like Perl 5's calling
 conventions.  I could argue for never auto flattening arrays, but then
 there'd really be no difference between @ and $.

   say ~foo([EMAIL PROTECTED]);   # a
   say ~foo(*(@array, z));# a

 Hmm, *(@array, z)... what does that mean?  Whatever it means, you're
 correct in both of these.  In the latter, the @array is in a
 flattening context, so it gets, well, flattened.

   sub bar ([EMAIL PROTECTED]) { [EMAIL PROTECTED] }
 
   say bar(1,2,3);  # 3
   say bar(@array); # 1 (or 4?)

 4

Wha? And I mean that sincerely. That's cockeyed. Surely a [EMAIL PROTECTED] in 
the
signature simply says 'gather up the rest of the args and stick 'em in this
list'. In this case @array is a single argument, so @args should be equal to
[EMAIL PROTECTED] If I'm calling the function and I want @array to be treated as
anything but a single argument I use [EMAIL PROTECTED]

   say bar(@array, z);# 2 (or 5?)

 5

Double wha? That's even worse.

Do you claim that 

   say bar('z', @array)

also emits 5? Ick.


   say bar([EMAIL PROTECTED]);# 4

 Yep.

So how *do* I pass an unflattened array to a function with a slurpy parameter?


Re: Exposing the Garbage Collector (Iterating the live set)

2005-08-03 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 7/26/05, TSa (Thomas Sandlaß) [EMAIL PROTECTED] wrote:
 Piers Cawley wrote:
  I would like to be able to iterate over all the
  objects in the live set.
 
 My Idea actually is to embedd that into the namespace syntax.
 The idea is that of looking up non-negativ integer literals
 with 0 beeing the namespace owner.
 
for ::Namespace - $instance
{
   if +$instance != 0 { reconfigure $instance }
}

 Oh, so a namespace can behave as an array then.  Well, to avoid
 auto-flattening problems in other, more common places, we ought to
 make that:

 for *::Namespace - $instance {...}

 However, this is very huffmanly incorrect.  First of all, what you're
 doing may take a quarter of a second or more for a large program
 (which isn't a short amount of time by any means).  Second, the fact
 that you're using it means you're doing something evil.  Third, only a
 fraction of 1/omega perl programmers will be using this feature. 
 Therefore, it should probably look like:

 use introspection;
 for introspection::ALL_INSTANCES(::Namespace) - $instance {...}

And if my proposal or something like it were accepted, the implementation could
simply look like:

  module introspection {
class Class is extended {
  method all_instances($class:) {
fail unless $*PLATFORM.GC.can_iterate_over_liveset;
$*PLATFORM.GC.grep - $instance { $instance.isa($class) }
  }
}

sub ALL_INSTANCES($class) {
  $class.all_instances
}
  }
 
The point about my proposal to have the garbage collector or something like it
expose methods to iterate over the live set isn't that it's syntactically
gorgeous, but that it's a useful minimal behaviour that can be used to
implement nicer syntaxes which can be loaded as required. If we're going to
allow such reflective stuff (on platforms that can do it) then there needs to
be some minimal core functionality that other modules can use. The point about
iterating over the live set is that it's essentially free until you use it; the
garbage collector must *already* hold onto the information needed to do the
iteration.


Re: Elimination of Item|Pair and Any|Junction

2005-08-03 Thread Piers Cawley
Autrijus Tang [EMAIL PROTECTED] writes:

 On Fri, Jul 22, 2005 at 03:40:34PM -0700, Larry Wall wrote:
 I dunno.  I'm inclined to say that it should default to Item|Pair, and
 let people say Any explicitly if they really want to suppress autothreading.
 Otherwise conditionals and switches are going to behave oddly in the
 presence of accidental junctions.

 Okay.  However, in that view, I suspect many builtins will be defined on
 Item|Pair, for example perl, clone, id, as well as various coercion
 builtins.  Considering that builtins are Code objects but not Routines,
 maybe they, too, should default to Item|Pair -- except the ones that
 operates on junctions, of course.

 This leads me to think that maybe users don't really need to write down
 the two junctive types, under the hierarchy below:

 - Object
   - Any
   - Item
   - ...pretty much everything
   - Pair
   - Junction
 - num, int, str...

 Since junctions are still boxed objects, having the Object type to
 effectively mean Any|Junction seems natural (everything is an object).

 Also, since Any unifies Item and Pair, the rule for implicit types of
 argument becomes:

 sub ($x) { }# Item $x
 - $x { } # Any $x- i.e. Item|Pair but not Junction
 { $^x }   # Any $x- i.e. Item|Pair but not Junction

Maybe there's a case for introducing Bundle types, akin to CPAN bundles. These
would be types only in the very losest sense, that could be used in function
prototypes to stand for particular bundles of types. So instead of Any being in
the class hierarchy where you propose it'd be a bundle that expanded to the
equivalent of doing:

   any(Object.all_subclasses.grep - $class { !$class.does(Junction) })

That way we get to arrange the class hierarchy in the way that makes the most
sense conceptually, but slice still slice it appropriately for Type
specifiers. 

Just a thought.


Re: Do slurpy parameters auto-flatten arrays?

2005-08-03 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 8/3/05, Aankhen [EMAIL PROTECTED] wrote:
 On 8/3/05, Piers Cawley [EMAIL PROTECTED] wrote:
  So how *do* I pass an unflattened array to a function with a slurpy 
  parameter?
 
 Good question.  I would have thought that one of the major gains from
 turning arrays and hashes into references in scalar context is the
 ability to specify an unflattened array or a hash in a sub call
 without any special syntax...

 Well, you can, usually.  This is particularly in the flattening
 context.  In most cases, for instance:

 sub foo ($a, $b) { say $a }
 my @a = (1,2,3);
 foo(@a, 3);

 Passes the array into $a.  If nothing flattened by default, then you'd
 have to say, for example:

 map {...} [EMAIL PROTECTED];


I would assume that the way to implement map is:

   multi sub map(block, @array) { map block, [EMAIL PROTECTED] }
   multi sub map(block, [EMAIL PROTECTED]) { ... }

If I call map like:

map {...} @a, @b, @c;

then I would expect the block to be called three times with @a, @b and @c as
the respective arguments.


I think the problem I have with this is that unless I missed something, the
default prototype for a block is [EMAIL PROTECTED] If slurpiness works as 
described, then 

   $func = { [EMAIL PROTECTED] }
   $func.(@array)

doesn't return the length of the array, but the numification of its first 
element. 

It seems to me that a slurpy parameter spec should simply say Grab the
rest of the arguments and stick 'em in this array/hash, a function's caller
should control the flattening of a particular array argument, not the thing it
calls.

One of us has obviously misread the appropriate Apocalypse/Synopsis/Exegesis. I
have the horrible feeling that it's probably me, but I do think that the
interpretation I propose is the least surprising and most useful.

By the way, if flattening that way, what's the prototype for zip? We can after
all do:

   zip @ary1, @ary2, @ary3, ... @aryn



Re: Exposing the Garbage Collector

2005-07-26 Thread Piers Cawley
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
 Let's say I have a class, call it Foo which has a bunch of attributes, and 
 I've
 created a few of them. Then, at runtime I do:
eval 'class Foo { has $.a_new_attribute is :default10 }';
 Assuming I've got the syntax right for defaulting an attribute,

 I think you need a 'class Foo is extended' to re-open the class.
 Otherwise you produce a redefinition error if the scope you call
 eval in already contains---or is that extains because of the name
 search beeing *outwards*---one you start from scratch.

Oh for heaven's sake! That's the last time I go trying to come up with concrete
examples for this sort of thing. Of course, you're right, I should have said
'is extended', but if I were doing it for real, the eval would fail and I'd
have a meaningful error message. 

[ An explanation of why this particular case doesn't require iterating over the
live set ]

I really shouldn't go picking concrete examples that can be worked around
should I? Suffice to say that sometimes (say for debugging purposes, or program
analysis -- Smalltalk can do some cunning typer inferencing tricks by examining
the live set for instance) I would like to be able to iterate over all the
objects in the live set. ISTM that exposing the Garbage Collector at the
Language level is the neatest way of doing this (or coming up with something
like Ruby's ObjectSpace, but conceptually I reckon the GC is the right place to
hang it).


Exposing the Garbage Collector

2005-07-23 Thread Piers Cawley
Let's say I have a class, call it Foo which has a bunch of attributes, and I've
created a few of them. Then, at runtime I do:

   eval 'class Foo { has $.a_new_attribute is :default10 }';

Assuming I've got the syntax right for defaulting an attribute, and lets assume
I have, the Perl runtime needs to chase down every instance of Foo or its
subclasses and add an attribute slot (adding a method to a class is nowhere
near as interesting, because every instance of the class shares a single class
object). 

One way to do this is for a class to keep track of all its instances, which is
all very well until you start subclassing because subclasses have to both keep
track of their instances and inform their superclasses about any new instances,
which seems an awfully heavyweight thing to have to do just to be ready for the
occasional programmer like me who wants to develop classes in an image based
IDE or someone else who wants to add a role to a class at runtime or
whatever. Also, the class's links to its instances needs to be week, otherwise
you end up with instances that never get collected, which isn't good. 

It seems to me, that the way to get at all the instances of a class is to ask
the Garbage Collector to do the heavy lifting for us, and ideally I'd like to
see this exposed at the Perl level. It doesn't really have to expose that many
methods of course -- a simple map/grep would do nicely, then it'd be possible
to write, say:

class Class {
  method all_instances ($class:) {
$*GC.grep {$^obj.isa($class)}
  }
}

Note that, *of course* this is slow, but I suggest that this sort of thing
should be slow (or, at the very least, you shouldn't require everything else to
pay a runtime cost just to allow people to use reflective tools like this).



Re: Do I need has $.foo; for accessor-only virtual attributes?

2005-07-20 Thread Piers Cawley
Sam Vilain [EMAIL PROTECTED] writes:

 Larry Wall wrote:
Users of the class includes people subclassing the class, so to them
they need to be able to use $.month_0 and $.month, even though there
is no has $.month_0 declared in the Class implementation, only
has $.month.
 We thought about defining the attribute variables that way,
 but decided that it would be clearer if they only ever refer to
 real attributes declared in the current class.

 Clearer in what way?

 This implies that you cannot;

- refactor classes into class heirarchies without performing
  code review of all methods in the class and included roles.

That's why it's generally a bad idea to use the C$.whatever forms outside
your basic accessor methods.

- wrap internal attribute access of a superclass in a subclass

Which is why it's generally a bad idea to use the C$.whatever forms outside
your basic accessor methods.

 This in turn implies that the $.foo syntax is, in general, bad
 practice!

Yup.


Re: What do use and require evaluate to?

2005-07-14 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 On Tue, Jul 12, 2005 at 08:48:41PM +0300, Gaal Yahas wrote:
 : I propose to throw away the filesystem coupling, and map from a more
 : general name of the bit of code we are requiring to a more general
 : description of which instance of it we actually got. Once modules return
 : interesting values, it might be useful to keep a copy of that value
 : somewhere on the value side of %*INC: or else turn it inside out and
 : stipulate that a standard field in the Module object is where you got
 : this particular module.

 Yes, that's basically what I was mumbling about in my response.  Now just
 make sure %*INC is lexically scoped.

 : Probably, %*INC values should be weak references.

 Why should they be weak references?  If %*INC is lexically scoped
 then its entries represent this lexical scope's *real* references to
 modules, and there's no need to weaken them, since it's not functioning
 as some kind of cache.  As long as this lexical scope sticks around, it
 needs the modules it points to.  As soon as the lexical scope is destroyed,
 it doesn't need them any more.  (Counting all closures over this lexical
 scope as preserving its needfulness, until all such closures are dead
 objects.)

 It's my conjecture that any explicit need for weak references probably
 indicates a design failure somewhere.  Something like the mis-scoping
 of a reference variable, or maybe only something niggly like the
 absence of a feature like is cached to encapsulate weak semantics.
 Or maybe something as major as the lack of robust GC, in the case of
 Perl 5...

So long as there's some way of asking the garbage collector for everything in
the live set so you can grep through them I'm sure you're right. Because almost
everything is extensible at runtime a class is going to need some way of
finding all its (and its subclasses) instances so it can update 'em when/if
it's definition changes. I'm also trying to think how an object/database mapper
could be made to work effectively without being able to keep track of all its
managed objects, or would that just be handled through the use of 'is cached'?


Re: Dependency Injection

2005-07-08 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 On Wed, Jul 06, 2005 at 11:47:47PM +0100, Piers Cawley wrote:
 : Or you could use a global, but globals are bad...

 Globals are bad only if you use them to hold non-global values.
 In this case it seems as though you're just going through contortions
 to hide the fact that you're trying to do something naturally
 global.  You might argue that a singleton object lets you hide the
 implementation of the delegation from the world, but there's really not
 much to implement if you just want to tell the world that whenever the
 world says LOGGER the world is really delegating to LOGGER::DBI.
 Plus if you really need to reimplement you just vector the world
 through LOGGER::SELECTOR or some such.

The thing about the version where the language handles the vectoring through
Logger, or whatever, is that you can retrofit such indirection without having
to make sure all your code uses the global. For instance, in the Test::* world,
there's a huge number of test modules that all play nicely because they work
with Test::Harness, and that's fine until you reach the point where you want to
specialize Test::Harness itself (say you want to write a graphical test
runner). With the global variable approach, you have to alter everything that
uses Test::Harness, with an injection approach, you only have to make changes
to Test::Harness itself.

Hmm... thinking about this a little further, the interface I proposed can't be
as automagical as simply loading a class that injects into your injectable
class because said class could well inherit from another injecting class. You
would have to make it a two step process like:

use InjectableClass;

use InjectingClass;

InjectableClass.inject_with(InjectingClass);

What I'm after is another way to hide implementation details from client
classes and allow programmers to write natural code. 

 One nice thing about a variable is that you're guaranteed to
 be able to temporize it:

 temp $*LOGGER = pick_a_logger();

I'm not sure that, in the particular case, that's all that useful. It'd be cool
if, say in a debugging situation, I could say that, from now on, all messages
to Logger from class Foo are actually dispatched to InstrumentedLogger, and
then to turn it off again, but I'm not sure how I'd do that with a global.

$Package::Name::OUR::*LOGGER = ::InstrumentedLogger

perhaps?



Re: SMD is for weenies

2005-07-06 Thread Piers Cawley
Yuval Kogman [EMAIL PROTECTED] writes:

 On Fri, Jul 01, 2005 at 13:42:34 +1200, Sam Vilain wrote:
 Yuval Kogman wrote:
 As I understand it SMD is now not much more than a mechanism to
 place a constraint on the MMD, saying that there can only be one
 method or subroutine with the same short name.
 Why is this the default?
 
 Otherwise you lose this quite useful warning if the signatures didn't
 match;
 
 method foo redefined at ...

 That's a good point...

 I'm guessing that the default warnings should have a warning for MMD
 methods which append to a short name without appearing immediately
 after each other in the same file.

 I agree with you MMD is very cool, and I use it a lot.  But I don't
 mind clarifying the intent with multi; this overloading is
 considered by some to be surprising to new programmers.

 Prepending 'mutli' is not a problem when I have to type it. It's a
 problem when others won't type it. When 90% of the module code I'll
 be using is not MMD compatible, because MMD is not the default, I
 can't specialize other people's code without editing it (at runtime
 or at the source level).

 Overloading won't happen unless people overloading semantics are
 introduced, and that's exactly what I'd like to do to other people's
 code occasionally.

Then write yourself a module, call it 'multiplicity' say, which would allow you
to say  

use multiplicity;

sub foo (...) {...} # foo is a multimethod, even if there's already a 'SMD'
# foo in existence.

It shouldn't even be that hard, just macroize sub/method/whatever to become
multis that first check if there's already a singly dispatched sub with the
same name and promoting to multi status if possible. 

Of course, if you use something like that, you're taking the risks on your own
head, but you knew that as soon as you typed 'use multiplicity'. 

The important thing is that the dispatch and reflection system should be
flexible enough to allow you to write something like this.


Re: Summarizer Suggestion...

2005-07-06 Thread Piers Cawley
Matt Fowles [EMAIL PROTECTED] writes:

 Will~

 On 7/6/05, Will Coleda [EMAIL PROTECTED] wrote:
 
 It would be nice if the summarizers also summarized the various
 Planet RSS feeds of journal entries, if those entries were
 sufficiently relevant.

 I would be willing to do that, but I can't speak for Piers...

From the various journal entries I've ready, they often stand pretty well as
summaries anyway. Which is why, in my last summary, instead of summarizing
journals I simply pointed to planetsix -- I presume there are others.


Dependency Injection

2005-07-06 Thread Piers Cawley
So, I got to thinking about stuff. One of the more annoying things about
writing nicely decoupled objects and applications are those occasions where you
want an object to be able to create objects in another class. Say you've
provided a singleton interface to your logging system. The naive implementation
goes something like:

require Logger; 

has $.logger;

method logger { $.logger //= Logger.new }

method whatever {
  ./logger.debug(About to do stuff);
  .do_some_stuff;
  ./logger.debug(Did stuff);
  ...
}

But that's problematic because we've backed knowledge of the particular class
that handles logging into our class. The bad solution to this is to subclass
our class if we want a different Logger class (that conforms to the same
interface). A slightly better solution is to parametrize the logger class
name, probably with a class variable -- but doing that means you have to
remember to set the variable for every class you use. Or you could use a
global, but globals are bad...

It'd be really cool if you could essentially write the naive implementation
above and have your application/test/webserver harness decide which particular
class will be taken to be the concrete implementation. Something like this:

role Logger is Injected { 
  method debug {...}
  method info {...}
  ...
}

Logger::DBI does Logger { ... }

Logger::Debugger does Logger { ... }

Then the harness that actually sets up the application would simply do

use Logger::DBI :dsn..., :user..., :password

and Logger::DBI would install itself as the default Logger class.

The question is, how does one write Injected to make this work? Or what
features do we need to be able to write Injected? Thinking about this, it
shouldn't be too hard to implement 'Injected' in Perl 5:

sub Injected::AUTOLOAD {
  no strict 'refs';
  die If something's already been instantiated you're screwed 
if ref($_[0]) or $Injected::injecting;
  local $Injected::injecting = 1;
  my $target_role = $_[0]
  my @possibles = grep {/(.*)::$/  $1-isa($target_role)} keys %::;
  die Too many possibles if @possibles  1;
  if (@possibles) {
*{$target_role\::} = *{$possibles[0]};
  }
  else {
my $default_package = $target_role-default_class;
eval require $default_package or die Can't find a default package;
*{$target_role\::} = *{$default_package\::};
  }
  {$target_role-can($AUTOLOAD)}(@_);
}

NB, that's completely untested code, but it, or something like it, should work.





   


Re: Fwd: [EMAIL PROTECTED]: Re: fixing is_deeply]

2005-07-01 Thread Piers Cawley
Michael G Schwern [EMAIL PROTECTED] writes:

 On Fri, Jul 01, 2005 at 07:11:26AM +, Smylers wrote:
  The question you have to ask yourself is why should a reference be
  treated different from any other value? It is a VALUE.
 
 Except it isn't.  Or at least, not all the time: it depends how you wish
 to look at it.  If you just consider a reference to be a value
 (effectively a pointer, a memory address) then you aren't examining a
 data structure _deeply_; you're just doing a _shallow_ comparision of it
 as a reference.

 I think this hits the nail on the head.  References are treated differently
 because we don't look at the reference we look at the data that reference
 points to.  is_deeply() does this fairly consistently ignoring blessing,
 ties and overloading.

 Under the proposed logic, this test fails:

   my $a = [];
   my $b = [];
   my $c = [];

   my $x = [$a, $a];
   my $y = [$b, $c];

   is_deeply($x, $y);

 because $x and $y can be altered in exactly the same way yet come out
 differently.

   $x-[0][0] = 1;  # [[1],[1]]
   $y-[0][0] = 1;  # [[1],[]]

 There's plenty of other cases where this can happen.  If $x is tied.  If $x
 is a string overloaded object.  If $x is an object.  These can lead to 
 situations where the same operation is applied to both structures yet 
 results in different structures.  But we ignore this because is_deeply()
 has to draw a line between internal and external information somewhere.
 Its drawn at the reference value.

 is_deeply() is not about exact equivalence.  Its about making a best fit
 function for the most common uses.  I think most people expect [$a, $a] and
 [$b,$c] to come out equal.

I've always thought of Cis_deeply as being about the 'shape' of a data
structure. When you think of things in this way, then it seems obvious that
given

$a = [], $b = [], $c = []

then [$a, $a] and [$b, $c] have substantially different shapes.


Re: OO magic (at least for me)

2005-06-26 Thread Piers Cawley
BÁRTHÁZI András [EMAIL PROTECTED] writes:

 Hi,

 I'm wondering, if it's possible with Perl 6 or not?

 class MyClass {

   method mymethod($par) {
   say mymethod called!;
   }

 }

 class ExClass is MyClass {

   mymethod(12);

 }

 # pugs myprog
 mymethod called!

 I would like to use mymethod to add ExClass some methods, etc.

 ///

 Just another problem, related to the above:

 class MyClass {

   method whenmother() {
   say MyClass is parent now!!!;
   say Her child name is:  ~ ;
   }

 }

 class Child is MyClass {
 }

 # pugs myprog
 MyClass is parent now!!!
 Her child name is: Child

I'd like to hope so. Actually, I don't think that this *specific* functionality
should be in the core, but the ability to implement it (just needs a unified
notifcation scheme that gets tickled when new classes, methods, subs, packages,
etc, get added to the image -- more detailed behaviour is a SMOP).


Re: proposal: binding with a function

2005-06-23 Thread Piers Cawley
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes:
 As I've said before, Perl supports `alias`--it's just spelled `:=`.

Here's a rubyish idiom:

  my old_behaviour := function;

  function := sub { try_some_stuff || old_behaviour }

Except, with binding it doesn't work like that, you end up with an infinite
loop. 
  


Re: AUTLOAD and $_

2005-06-23 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 6/20/05, chromatic [EMAIL PROTECTED] wrote:
 On Mon, 2005-06-20 at 12:11 +0200, Juerd wrote:
 
  I think there exists an even simpler way to avoid any mess involved.
  Instead of letting AUTOLOAD receive and pass on arguments, and instead
  of letting AUTOLOAD call the loaded sub, why not have AUTOLOAD do its
  thing, and then have *perl* call the sub?
 
 Who says AUTOLOAD will always either call a loaded sub or fail?

 Uh, what else can it do?  It doesn't have to load a sub to return a
 code reference.

For myself, I'd like to see AUTOLOAD with a signature along the lines of:

   sub AUTOLOAD (Symbol $sym, ArgumentCollection $args, Continuation $cc)
 returns (Code | Pair)
   {
 ...
   }

This presupposes a deal of support infrastructure, but also provides
flexibility. For the 'NullObject' case, you'd simply do C$cc() to return
directly to the caller, skipping over whatever Perl is up to.

'ArgumentCollection'? Well, that's the activation record and I'd like to see it
allowing methods like:

my ($foo, $bar, $baz) =
  $args.parse_signature('Int $foo, String $bar, Code $baz')

 That way code could probe the argument structure in order to do its own
 dispatch.

 As for returning a coderef or a pair. If you return a coderef, Perl simply
 calls it and throws it away. Returning a pair, with a name (long or short) as
 the key and the code as the value would make perl bind the code to the given
 name (which should be compatible with the name passed in in the first place).

 Details left as an exercise for the interested reader.


Re: When can I take given as read?

2005-06-21 Thread Piers Cawley
Carl Franks [EMAIL PROTECTED] writes:

  sub factorial (Int $n is topic) {
  return 1 when 0;
  return $n * factorial $n;
  }

 hmm, could we write...

 sub foo (Class $self is topic: +$foo, +$bar) {
   .method;
 }

 to avoid having to use ./
 ?

Yay!


nested subs

2005-06-16 Thread Piers Cawley
So, I was about to write the following test for Pugs:

  sub factorial (Int $n) {
my sub factn (Int $acc, $i) {
  return $acc if $i  $n;
  factn( $acc * $i, $i+1);
}
factn(1, 1);
  }

When I thought to check the apocalypses and exegeses and, what do you know, I
couldn't find any evidence that nested named functions like this were legal. 

So, are they legal?

And yes, I know there are other ways of doing this, but I like the lack of
sigils on the function when you do it this way.


Re: nested subs

2005-06-16 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 6/16/05, Piers Cawley [EMAIL PROTECTED] wrote:
 So, I was about to write the following test for Pugs:
 
   sub factorial (Int $n) {
 my sub factn (Int $acc, $i) {
   return $acc if $i  $n;
   factn( $acc * $i, $i+1);
 }
 factn(1, 1);
   }
 
 When I thought to check the apocalypses and exegeses and, what do you know, I
 couldn't find any evidence that nested named functions like this were legal.
 
 So, are they legal?

 Yep.  And they work just as if you had used an anonymous sub there--it
 closes over lexicals and everything.

I should bloody well hope so too.


When can I take given as read?

2005-06-16 Thread Piers Cawley
Suppose I have a simple, single argument recursive function:

  sub factorial (Int $n) {
return 1 if $n == 0;
return $n * factorial $n;
  }

Can I write that as:

  sub factorial (Int $n:) {
return 1 when 0;
return $n * factorial $n;
  }

NB. Yes, I know it's a pathological example.



Binding slices

2005-06-14 Thread Piers Cawley
Following a conversation with Chip on IRC, is this

my @y := @foo[0..][1];

legal?



Re: Binding slices

2005-06-14 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 6/14/05, Piers Cawley [EMAIL PROTECTED] wrote:
 Following a conversation with Chip on IRC, is this
 
 my @y := @foo[0..][1];
 
 legal?

 Definitely not.  But it sure would be nice if this:

 my @y := @foo[0...][1];

 were.

I think that's what I meant to write :)


Re: How much do we close over?

2005-06-13 Thread Piers Cawley
Rob Kinyon [EMAIL PROTECTED] writes:

 Piers Cawley said:
 in other words, some way of declaring that a subroutine wants to hang onto
 every lexical it can see in its lexical stack, not matter what static 
 analysis
 may say.

 I'm not arguing with the idea, in general. I just want to point out
 that this implies that you're going to hold onto every single
 file-scoped lexical, leading to quite a bit of action-at-a-distance.

Well, duh. If eval string isn't a hearty pointer to the This subroutine
deliberately takes advantage of action at a distance then I don't know what
is.


 Maybe, instead, you should say sub is lexical_stack(N) where N is
 the number of scoping levels it will hold onto in addition to any
 lexical it actually refers to. I would have 0 be the innermost scope,
 1 be the enclosing scope, etc.

Which is all very well, but you don't necessarily know how deep in the stack
you are. I want to be able to write something in such a way that evalling the
string works in exactly the same way as it would if I had just written a do
block in the first place.

sub foo { my $x; ...; return sub { do {...} } }

It's an introspection thing. Most of the time you don't want it, but sometimes
you do and we really shouldn't be making that impossible.


Re: How much do we close over?

2005-06-13 Thread Piers Cawley
Rod Adams [EMAIL PROTECTED] writes:

 Piers Cawley wrote:

Chip and I have been having a discussion. I want to write:

sub foo { my $x = 1; return sub { eval $^codestring } }
say foo()($x);

I claim that that should print 1. Chip claims it should throw a warning about
because of timely destruction. My claim is that a closure should close over 
the
entire lexical stack, and not simply those things it uses statically. Chip
claims the opposite, arguing that timely destruction implies that this is
absolutely the right thing to do. It's also quicker.
  

 I'm going to have to side with Piers on this one. My feeling is that having a
 reference to a closure accessible in memory should keep all the possible
 lexicals it can access in memory as well. That said, I can the compiler
 optimizing memory consumption by destroying all the outer lexicals that it can
 prove will never be used by the inner closure. However, the presence of an
 eval' in the closure makes such a proof tenuous at best.

 On the other hand, one could easily view the eval as constructing yet another
 closure, and it's unclear if we wish for that closure to be able to skip the
 first level outer closure to directly access the 2nd level outer lexicals. In
 that respect, I could see things Chip's way.

 As for the warning, it should only be a warning if strictures are on, for 
 using
 the now undeclared '$x' inside the eval.

But dammit, I'm doing runtime evaluation of code strings, I don't care about
quicker.

If it's not the default can it please be mandated that there be some way of
doing:

sub foo { my $x = 1; return sub is lexically_greedy {eval $^codestring} }

in other words, some way of declaring that a subroutine wants to hang onto
every lexical it can see in its lexical stack, not matter what static analysis
may say.

  

 Well, you could always do something like:

 sub foo { my $x = 1; return sub {my $x := $OUTER::x; eval $^codestring} }

 But I'm spending too much time in other languages lately to remember exactly
 how $OUTER::x is spelled for certain. One could probably even write a macro
 that auto-binds all the lexicals in the outer scope to the current scope.

Only if I actually know what variables which were within scope when that inner
sub was compiled are going to be used by my passed in code string. I really
don't want to have to write a macro to walk the OUTER:: chain in order to build
a something like:

   sub { my $foo = $OUTER::foo;
 my $bar = $OUTER::OUTER::bar;
 ...;
 eval $^codestring }

Just to pull everything into scope.

And even if I could do that, what I actually want to be able to do is something
like this:

$continuation.bindings.eval_in_this_scope($^codestring);

Which can be done today in Ruby and which is one of the enabling technologies
for tools like Rails.


Re: Attack of the fifty foot register allocator vs. the undead continuation monster

2005-06-12 Thread Piers Cawley
Chip Salzenberg [EMAIL PROTECTED] writes:

 On Wed, Jun 08, 2005 at 10:26:59PM +0100, The Perl 6 Summarizer wrote:
   Loop Improvements
 Oh no! It's the register allocator problems again. One of these days I
 swear I'm going to swot up on this stuff properly, work out whether it's
 really the case that full continuations break any conceivable register
 allocator and summarize all the issues for everyone in a nice white
 paper/summary.

 It's not really that complicated.  It just takes a long time to explain.
-- Dr. Howland Owll, on SubGenius doctrine

 Consider this code:

 sub example1 {
my $a = foo();
print $a;
my $b = bar();
print $b;
 }

 It's obvious that $a and $b can be allocated the same register because
 once $b has been set, $a is never used again.

 (Please ignore that $a and $b are variables that can't be stored
 purely in registers.  The real world case that I'm illustrating deals
 with temporaries and other values that lack user-visible names.  But
 the issue is best illustrated this way.)

 Now consider this:

 sub example2 {
my $a = foo();
do {
print $a;
$b = bar();
print $b;
} while ($b);
 }

 You can see that it's now *not* OK to allocate $a and $b to the same
 register, because the flow of control can jump back to the print $a
 even after $b is assigned.

 Look at the first function again, and consider what happens if foo
 captures its return continuation _and_bar_invokes_it_.  It would
 effectively amount to the same issue as example2:

 sub foo {
$a = 1;
foo();
  _implicit_label_for_return_continuation:
print $a;
$b = bar();
print $b;
 }

 bar() {
if rand()  0.5 { goto _implicit_label_for_return_continuation }
return lucky;
 }

 Therefore, register allocation must allow for implicit flow of control
 from *every* function call to *every* function return ... or, more
 precisely, to where *every* continuation is taken, including function
 return continuations.

Buf if you fallow the calling conventions that looks like:

   sub foo {
 $a = 1.
 $c = 10;
 print $c
 
save_dollar_a_and_only_dollar_a_because_im_going_to_use_it_after_this_function_call
 foo()
_implicit_label_for_return_continuation:
 restore_dollar_a
_ooh_i_dont_have_to_save_anything
 $b = bar()
_nor_do_i_have_to_restore_anything
print $b
   }

That's what caller saves means. You only have to save everything that you're
going to care about after the function returns. You don't have to save the
world, because if it was important it's already been saved further up the call
chain.

This means, of course, that the continuation needs to save the state of the
restore stack, but I thought we already knew that.

Of course, if you're going to actually use GOTO to get to some label that you
should only get to via a continuation (as you do in the code example) then you
deserve to get everything you've got coming to you. A continuation must contain
everything needed to restore the user registers to the correct state no matter
how many times they were taken.

I really don't see how this affects register allocation; the call to bar
doesn't need to save $a because it's not referred to (lexically) after the call
returns. So what if the call to bar might take a continuation. Taking that
continuation should be exactly equivalent to returning from the call to
foo. You really have to stop thinking of continuations as gotos.


Re: Attack of the fifty foot register allocator vs. the undead continuation monster

2005-06-12 Thread Piers Cawley
Chip Salzenberg [EMAIL PROTECTED] writes:

 On Sun, Jun 12, 2005 at 03:15:22PM +0100, Piers Cawley wrote:
 But if you fallow the calling conventions that looks like:
 
sub foo {
  $a = 1.
  $c = 10;
  print $c
  
 save_dollar_a_and_only_dollar_a_because_im_going_to_use_it_after_this_function_call
  foo()
 _implicit_label_for_return_continuation:
  restore_dollar_a
 _ooh_i_dont_have_to_save_anything
  $b = bar()
 _nor_do_i_have_to_restore_anything
 print $b
}

 You have greatly misunderstood.  We're talking about how foo manages
 its callee-saves registers.  The registers involved, the ones that I'm
 calling $a and $b, are P16-P31.

 Of course, if you're going to actually use GOTO to get to some label
 that you should only get to via a continuation ...

 For purposes of allocating the callee-saves registers, a continuation
 may as well _be_ a goto.

No it's not. A continuation should carry all the information required to
restore the registers to the correct state when it is taken. A goto
doesn't. For the purposes of allocating the registers in foo you can allocate
$a to P16, and $b to p16, because when the call to bar takes the continuation
back to bar, the 'restore' phase should grab $a from the continuation and bung
it back on P16. The continuation doesn't even need to know where to restore $a
to, because the 'caller restores' code should take care of that.

 Don't feel bad, though.  I thought the same thing the first time *I*
 heard about this problem.

I think you should have held that thought.


Re: Attack of the fifty foot register allocator vs. the undead continuation monster

2005-06-12 Thread Piers Cawley
Matt Fowles [EMAIL PROTECTED] writes:

 Chip~

 On 6/12/05, Chip Salzenberg [EMAIL PROTECTED] wrote:
 I'd like like to note for other readers and the p6i archives that
 Piers has failed to grasp the problem, so the solution seems pointless
 to him.  I'm sorry that's the case, but I've already explained enough.

 This response worries me firstly because of its rudeness and second
 because of the problem itself.  As I see it there are four
 possibilities a:

 1) Chip is right, Piers is wrong.  This is a complex problem and
 refusing to explain it means that others will doubtless also
 misunderstand it, which you have a chance to preempt here.

 2) Chip is wrong, Piers is right.  This is a complex problem and
 refusing discussion on it would be a costly mistake.

 3) Chip is right, Piers is right. The two of you have are working from
 a different base set of definitions/axioms or misunderstood each other
 in some other way.

 4) Chip is wrong, Piers is wrong.  Shutting down open conversation so
 forcefully and caustically will prevent discussion in the future and
 this problem will continue to haunt parrot as no viable solution has
 been seen.

 Regardless of which of these possibilities is true.  I see a need for
 more discussion of this issue.  Preferably a discussion that does not
 degrade into backhanded insults.  I have my own ideas about this
 problem, but I will save that for another response.

Don't worry Matt, we're still talking. It takes more than sarcasm to stop me.


How much do we close over?

2005-06-12 Thread Piers Cawley
Chip and I have been having a discussion. I want to write:

sub foo { my $x = 1; return sub { eval $^codestring } }
say foo()($x);

I claim that that should print 1. Chip claims it should throw a warning about
because of timely destruction. My claim is that a closure should close over the
entire lexical stack, and not simply those things it uses statically. Chip
claims the opposite, arguing that timely destruction implies that this is
absolutely the right thing to do. It's also quicker.

But dammit, I'm doing runtime evaluation of code strings, I don't care about
quicker.

If it's not the default can it please be mandated that there be some way of
doing:

sub foo { my $x = 1; return sub is lexically_greedy {eval $^codestring} }

in other words, some way of declaring that a subroutine wants to hang onto
every lexical it can see in its lexical stack, not matter what static analysis
may say.


Re: return() in pointy blocks

2005-06-09 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 6/8/05, Piers Cawley [EMAIL PROTECTED] wrote:
  In other words, it outputs:
 
 Foo
 Foo
 # dies

 Yep.  My mistake.

 If that works, then I think it means we can write:
 
 sub call-with-current-continuation(Code $code) {
 my $cc = - $retval { return $retval }
 $code($cc);
 }
 
 Which I personally think is rather cute. Even if I can't quite bring myself 
 to
 believe it's that simple...

 Yeah, that's pretty.  But that will bite people who don't understand
 continuations; it will bite people who don't understand return; it
 will even bite people who understand continuations, because they can
 be made in such an awkward form so easily.

Having worked through the little and seasoned Schemers, I'm actually at the
point where I can happily think that 'return' is deep scary magic. What I
*want* is a 'proper' continuation, but this would have been close enough for
government work until the real ones came along.


 Currently call/cc is done like this:

 sub call_with_current_continuation(code) {
 code(?CALLER_CONTINUATION);
 }

 But that might be broken in pugs at the moment.

Doesn't that call code with the continuation of the caller of
call_with_current_continuation, when it *should* call code with the
continuation of call_with_current_continuation?


Re: return() in pointy blocks

2005-06-09 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 On Wed, Jun 08, 2005 at 10:51:34PM +, Luke Palmer wrote:
 : Yeah, that's pretty.  But that will bite people who don't understand
 : continuations; it will bite people who don't understand return; it
 : will even bite people who understand continuations, because they can
 : be made in such an awkward form so easily.

 Right--we don't want mere mortals to be able to get at continuations
 quite that easily, whether they think they want them or not.

Shame. If you go monkeying with continuations without knowing what they do,
then of course you deserve everything you have coming to you, but is that
really any reason for making them hard to get at when you *do* need them?

I'm not denying that they should be hard to get accidentally, but it would be
good to know how to get them deliberately.


Non-deterministic programming in Perl 6

2005-06-09 Thread Piers Cawley
So, the return in pointy sub thread got me thinking about useful uses of return
in pointy subs that involve being able to return multiple times. And this is
what I came up with, it's an implementation of 'choose':

my give_up = sub { fail Ran out of choices }

sub choose ([EMAIL PROTECTED]) {
  my old_give_up = give_up;
  my $try = - @choices {
if [EMAIL PROTECTED] { give_up = old_give_up; give_up }
else {
  my ($choice, @newchoices) = *choices;
  give_up = - { return $try(@newchoices) }
  $choice;
}
  }
  $try(@all_choices);
}

How do you use that I hear you ask:

my $x = choose(1,3,5);
my $y = choose(1,5,9);

# say Trying $x * $y; # Uncomment for an insight into how this works.
give_up unless $x * $y == 15;
say Found $x * $y = 15;

Yes, that is an artificial example.

If you can't use a returning pointy block more than once, then this becomes:

sub callcc (Code block) { block(?CALLER_CONTINUATION) }

my give_up = sub { fail Ran out of choices }

sub choose ([EMAIL PROTECTED]) {
  callcc - cnt {
my $try = - @choices {
  if [EMAIL PROTECTED] { give_up = old_give_up; give_up }
  else {
my ($choice, @newchoices) = *choices;
give_up = sub { cnt($try(@newchoices)) };
$choice;
  }
}
$try(@all_choices);
  }
}

Tracing the flow of control in both these examples is left as an exercise for
the interested reader.

The only catch is, neither of them works in Pugs. Yet.



Re: return() in pointy blocks

2005-06-08 Thread Piers Cawley
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
 My preference is for:
 Boo
 Boo
 Can't dereferene literal numeric literal 42 as a coderef.

 How do you reach the second 'Boo'? Iff - does not create a Sub
 but a Block instance then Luke's code can be interpreted as a
 much smarter version of

I really wish you'd quote in more detail, it makes it a real PITA to go back
and find the explanatory code.  

sub foo () {
  return - { return 42 }
}

my $code =   foo();
#  ^--- continuations points to the RHS of the assignment
say Boo!;
$code();

So, this is what happens.

1. foo() returns a coderef to the RHS of the assignment.
2. The coderef gets assigned to $code.
3. say Boo!
4. We invoke the coderef, which returns 14 to continuation which was current
   when it was created.
5. That means 42 gets returned to the RHS of the assignment
6. say Boo!
7. Try to invoke the literal 42. 
8. Die.

In other words, it outputs:

   Foo
   Foo
   # dies


 sub foo()
 {
 enter: 42;
 if $?RETURN_LABEL { goto $?RETURN_LABEL }
 return;
 }

  say Boo!;
  say goto foo::enter; # goto sets up $?RETURN_LABEL
  say after goto;

 which of course prints

 Boo
 42
 after goto

 The smartness is in the value that prefix:{'-'} returns
 while in the snippet above it is explicitly coded.

 Or do I completely misunderstand the distinction between
 blocks and closures?

It seems so.


Re: return() in pointy blocks

2005-06-08 Thread Piers Cawley
Piers Cawley [EMAIL PROTECTED] writes:

 TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
 My preference is for:
 Boo
 Boo
 Can't dereferene literal numeric literal 42 as a coderef.

 How do you reach the second 'Boo'? Iff - does not create a Sub
 but a Block instance then Luke's code can be interpreted as a
 much smarter version of

 I really wish you'd quote in more detail, it makes it a real PITA to go back
 and find the explanatory code.  

 sub foo () {
   return - { return 42 }
 }

 my $code =   foo();
 #  ^--- continuations points to the RHS of the assignment
 say Boo!;
 $code();

 So, this is what happens.

 1. foo() returns a coderef to the RHS of the assignment.
 2. The coderef gets assigned to $code.
 3. say Boo!
 4. We invoke the coderef, which returns 14 to continuation which was current
when it was created.
 5. That means 42 gets returned to the RHS of the assignment
 6. say Boo!
 7. Try to invoke the literal 42. 
 8. Die.

 In other words, it outputs:

Foo
Foo
# dies


If that works, then I think it means we can write:

sub call-with-current-continuation(Code $code) {
my $cc = - $retval { return $retval }
$code($cc);
}

Which I personally think is rather cute. Even if I can't quite bring myself to
believe it's that simple... 


Re: return() in pointy blocks

2005-06-08 Thread Piers Cawley
TSa (Thomas Sandlaß) [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
 [..] then I think it means we can write:
 sub call-with-current-continuation(Code $code) {
 my $cc = - $retval { return $retval }

 For the records: the return here is the essential ingredient, right?
 Without it the block would be evaluated or optimized away to an undef
 or some such.

Yes. Without the return you just get block that returns the value its last
expresion to the place from which it (the pointy sub) was called, rather than
to the place that the subroutine that created it was called from.


 $code($cc);
 }
 Which I personally think is rather cute.

 Me too!


 Even if I can't quite bring myself to
 believe it's that simple... 

 I have convinced myself.
 How can I be of assistance on your side?

How's your Haskell?


Re: return() in pointy blocks

2005-06-08 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 6/7/05, Matt Fowles [EMAIL PROTECTED] wrote:
 On 6/7/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote:
  Hi,
 
sub foo (Code $code) {
  my $return_to_caller = - $ret { return $ret };
 
  $code($return_to_caller);
  return 23;
}
 
sub bar (Code $return) { $return(42) }
 
say foo bar; # 42 or 23?
 
  I think it should output 42, as the return() in the pointy
  block $return_to_caller affects foo, not the pointy block.
  To leave a pointy block, one would have to use leave(), right?
 
 I don't like this because the function bar is getting oddly
 prematurely halted. 

 Then let's put it this way:

sub foo () {
for 0..10 { 
when 6 { return 42 }
}
return 26;
}

 And if that didn't do it, then let's write it equivalently as:

sub foo () {
map(- $_ { return 42 }, 0..10);
return 26;
}

 Do you see why the return binds to the sub rather than the pointy now?

 Also, we're going to be avoiding the return continuation problem with:

sub foo() { 
return - { return 42 };
}

my $code = foo();
say Boo!;
$code();

 Says not:

Boo
Boo
Boo
...

 But:

Boo
Can't return from subroutine that already returned at eval line 2.

My preference is for:

Boo
Boo
Can't dereferene literal numeric literal 42 as a coderef.

Actually, my preference is for not writing such silly code in the first place,
but there you go.


Re: return() in pointy blocks

2005-06-07 Thread Piers Cawley
Ingo Blechschmidt [EMAIL PROTECTED] writes:

 Hi, 
  
   sub foo (Code $code) { 
 my $return_to_caller = - $ret { return $ret }; 
  
 $code($return_to_caller); 
 return 23; 
   } 
  
   sub bar (Code $return) { $return(42) } 
  
   say foo bar; # 42 or 23? 
  
 I think it should output 42, as the return() in the pointy 
 block $return_to_caller affects foo, not the pointy block. 
 To leave a pointy block, one would have to use leave(), right? 

That's how it's defined in the relevant Apocalypse. And that's how I hope it'll
stay.



Re: Perl6 and support for Refactoring IDE's

2005-05-26 Thread Piers Cawley
Stevan Little [EMAIL PROTECTED] writes:

 On May 25, 2005, at 5:39 AM, Piers Cawley wrote:
 One of the 'mental apps' that's been pushing some of the things I've been
 asking for in Perl 6's introspection system is a combined
 refactoring/debugging/editing environment for the language.

 Maybe I have been reading too much about Smalltalk meta-classes lately, but in
 doing some draft ideas of the Perl6 meta-model for Pugs, I realized that given
 a really solid class/metaclass introspection system and access to the
 interpreter level meta-meta-classes, it would be possible to easily write a
 class browser much like Smalltalk.

Yes. The application in my head looks very a Smalltalk environment. The way I
see it working is that the language itself has a bunch of minimal hooks that
get triggered by various phases of compilation etc. Your editor then becomes
something that instruments the compiler in such a way that loading a file for
editing compiles it, but the compilation process hangs populates the data
structures you need for editing. So, when you go to edit, say:


class Collection {
   
  method inject_into ($self: $initial_value is copy, *block) {
$self.each
  :{ $initial_value = block($initial_value, $_) }
return $initial_value;
  }
}

You'd end up with a Class object which would have all sorts of interesting
things added to it, including collections of instance variables, class
variables, methods etc. Methods would have metadata about the environment in
which they were evaluated (so when you edit a method you could recompile it in
the correct environment), the file they're found in, their source code
(possibly attributed to allow for syntax highlighting), the resulting AST,
etc. Once you have such a rich set of metadata to hand, it becomes a simple
matter of programming to add all sorts of handy features, refactorings,
breakpoints, whatever...

The point being that you don't really need a massive amount of support from the
core language to do all this. At a pinch you can take advantage of the fact
that the grammar is replaceable and core classes are extensible (and if they're
not, you just stick them in boxes for the editor's purposes).

 And to extend that to also be a refactoring browser would require the
 meta-meta-class system to be able to generate and emit code, which, if we
 properly model the meta-meta-classes should also be fairly simple as well.

We've got eval for that. Assuming you can do eval with arbitrary bindings (and
if necessary you can drill down to parrot for it) you just do something like:

Class.can('fred').environment.eval($freds_new_sourcecode)

Of course, if you alter a macro you're going to have to reevaluate pretty much
all the source code, but so what?

 And of course all this is even simpler if the interpreter is written in Perl6
 (although the cyclical nature of that can be dizzying at times).

It really doesn't have to be. It'd be nice, but not necessary. You just have to
make sure you can extend the runtime using perl. And macros already do that.

 However adding debugging support to this is another matter all together, and 
 it
 is only partially useful to the non-OO programmer.

Not that hard to be honest. The same instrumented interpreter techniques can be
used to write the debugger.


Re: Perl6 and support for Refactoring IDE's

2005-05-25 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 On 5/6/05, J Matisse Enzer [EMAIL PROTECTED] wrote:
 I've become scared that if Perl is to continue to be viable for large,
 complex, multi-developer projects that the tools need to serious
 catch-up with what is available for Java, for example. Things like:
 
- Refactoring Support (see http://www.refactoring.com/)
- CVS and/or Subversion integration
- Support for integrating regression tests and auto-building
- Automated syntax and dependency checking
 
 I've been using Eclipse, with the EPIC plugin
 (http://e-p-i-c.sourceforge.net/) and so far I like it. It uses
 Devel::Refactor to support extract subroutine, but a lot more is
 needed to match what you can do with Java these days.
 
 What are others' thoughts on this?

 I think you're absolutely right.  Perl should have an IDE with
 Eclipse-like context-sensitivity and refactoring support.  However,
 it's hardly in Perl's philosophy or interest to bless one.

 One thing is for sure.  Perl 6 is providing enough introspection and
 parsing capabilities to make it possible to write a context-sensitive
 IDE, unlike Perl 5 (well, Perl 5 made it *possible*, I suppose, but
 Perl 6 will make it obvious).  Perl 6 is exposing its whole grammar at
 the language level, so you can say give me a syntax tree for this
 chunk of code and it will.  Even if there are modules that change the
 syntax with macros (though your editor might have trouble
 understanding what the macros mean).

One of the 'mental apps' that's been pushing some of the things I've been
asking for in Perl 6's introspection system is a combined
refactoring/debugging/editing environment for the language. One of the
annoyances of the 'only perl can parse Perl' thing is not so much the truth of
the statement, but that perl 5 doesn't allow you to ask about the parsed code
in ways that would be useful for an IDE. Perl 6 promises to change that -- it
should be possible to either write a fantastic Perl 6 IDE in perl itself, or to
write a codegrokker object that can be used by some pre existing IDE. 

 In other words, Perl 6 is open to the possibility of such an IDE, and
 is going to provide the machinery necessary to build a really good
 one, but I doubt it will become a development milestone.

What about the debugger?


Re: Undef issues

2005-05-25 Thread Piers Cawley
Adrian Taylor [EMAIL PROTECTED] writes:

 Hi,

 Over the weekend I added some tests on 'undef' behaviour
 (t/builtins/undef.t):

 These behave as expected:

 eval_is('undef * 2', undef, 'undef * 2');

That's not what I'd expect. I'd expect it to return 0 and throw a warning
about numification.


Re: Virtual methods

2005-05-25 Thread Piers Cawley
Aaron Sherman [EMAIL PROTECTED] writes:

 On Wed, 2005-05-18 at 10:51, Luke Palmer wrote:

 Except that mixins like this always treat things as virtual. 
 Whenever you mixin a role at runtime, Perl creates an empty, anonymous
 subclass of the current class and mixes the role in that class.  Since
 roles beat superclasses, you'll always override your own methods.

 Ok, good point (I've even pointed that out to others before, and I
 missed it)...

 I know that's the way it works, but now it's really bothering me.

 There are many gotchas that fall out of that. For example, you might
 have a special role that overrides .print to handle structured data, so
 your code says:

   my Foo $obj;
   given $obj {
   when StructuredPrintRole {
   # Someone's already taken care of it, possibly
   # adding a more specialized role, so leave it
   # alone.
   }
   default {
   # Add in a boring default handler
   $obj does StructuredPrintRole
   }
   }
   $obj.print($structured_data);

 Woefully, you lose is Foo happens to be DECLARED with
 StructuredPrintRole, and it overrode print. But, if it just inherited a
 print(), then it works. In other words, this code will mysteriously fail
 the second someone innocently adds a print method to Foo!

 Action at a distance... my head hurts.

Aaron, you do realise that that's quite obscene code don't you? I mean, you're
doing a case statement based on the type of its topic, and to compound the
evils, you're changing how your topic's print method works *everywhere* simply
to get your 'special' print behaviour. If you must do something like this (and
call it print), then write it as a multimethod or something.



Re: turning off warnings for a function's params?

2005-04-27 Thread Piers Cawley
David Storrs [EMAIL PROTECTED] writes:

 I image we've all written logging code that looks something like this
 (Perl5 syntax):

   sub foo {
   my ($x,$y) = @_;
   note(Entering frobnitz().  params: '$x', '$y'); 
   ...
   }

 This, of course, throws an 'uninitialized value in concatenation or
 string' warning when your test suite does this:

   is( foo(undef, undef), undef, foo(undef, undef) gives undef );

 In a testing environment, I don't want to see this warning. 

 In a
 production environment, I do.  Furthermore, when I want it gone, I
 want it gone from every instance of Cnote, without having to change
 something in every location.  I suppose I could change all my logging
 calls to look like this:

   {
 if ( $DEBUG ) { no warnings 'uninitialized'; note(); }
 else { note(); }
   }

 But that's really ugly, takes up a lot of space, is confusing, and is
 redundant.

 How would I best solve this problem in Perl6?

Write an appropriate macro:

warns(is( foo(undef, undef), undef, foo(undef, undef) gives undef),
  uninitialized value in concatenation or string);


That way you get to ensure that the warning gets thrown correctly if undef is
passed, but you don't get the warning mucking up your test output.


Re: Blocks, continuations and eval()

2005-04-12 Thread Piers Cawley
wolverian [EMAIL PROTECTED] writes:

 On Fri, Apr 08, 2005 at 12:18:45PM -0400, MrJoltCola wrote:
 I cannot say how much Perl6 will expose to the high level language.

 That is what I'm wondering about. I'm sorry I was so unclear.

 Can you tell me what your idea of a scope is? I'm thinking a
 continuation, and if that is what you are thinking, I'm thinking the
 answer to your question is yes.

 Yes. I want to know how Perl 6 exposes continuations, and how to get one
 for, say, the current lexical scope, and if it has a method on it that
 lets me evaluate code in that context (or some other way to do that).

As I understand what Larry's said before. Out of the box, it
doesn't. Apparently we're going to have to descend to Parrot to write
evalcc/letcc/your-preferred-continuation-idiom equivalent. 


Re: Blocks, continuations and eval()

2005-04-12 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 On Tue, Apr 12, 2005 at 11:36:02AM +0100, Piers Cawley wrote:
 : wolverian [EMAIL PROTECTED] writes:
 : 
 :  On Fri, Apr 08, 2005 at 12:18:45PM -0400, MrJoltCola wrote:
 :  I cannot say how much Perl6 will expose to the high level language.
 : 
 :  That is what I'm wondering about. I'm sorry I was so unclear.
 : 
 :  Can you tell me what your idea of a scope is? I'm thinking a
 :  continuation, and if that is what you are thinking, I'm thinking the
 :  answer to your question is yes.
 : 
 :  Yes. I want to know how Perl 6 exposes continuations, and how to get one
 :  for, say, the current lexical scope, and if it has a method on it that
 :  lets me evaluate code in that context (or some other way to do that).
 : 
 : As I understand what Larry's said before. Out of the box, it
 : doesn't. Apparently we're going to have to descend to Parrot to write
 : evalcc/letcc/your-preferred-continuation-idiom equivalent. 

 We'll make continuations available in Perl for people who ask for
 them specially, but we're not going to leave them sitting out in the
 open where some poor benighted pilgrim might trip over them unawares.

Oh goody! Presumably we're initially talking of a simple
'call_with_current_continuation'? 


Re: return of copies vs references

2005-03-29 Thread Piers Cawley
Darren Duncan [EMAIL PROTECTED] writes:

 At 7:10 AM +0100 3/29/05, Piers Cawley wrote:
Doesn't that rather depend on the type of the attribute? Personally, if I get
an object back from accessor method then I expect that any modifications of
that object's state will be seen the next time I look at the results of that
accessor method. This is a direct result of the way reference types work, and
the world is a better place because of it. If you want a (deep) copy of the
returned object you should say so:
my $res = $object.attribute.clone;

 I recanted what you're replying to last week.  Essentially, I agree with you
 that references of non-scalar values should be returned by default, and that
 the method must do an explicit copy if that's what they want returned.  Things
 are much simpler that way, and its how Perl 5 worked. -- Darren Duncan

Bah! Must start keeping up to date with the list again.


Re: .method == $self.method or $_.method?

2005-03-28 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 I've been thinking about this in my sleep, and at the moment I think
 I'd rather keep .foo meaning $_.foo, but break the automatic binding
 of the invocant to $_.  Instead of that, I'd like to see a really,
 really short alias for $self.  Suppose we pick o for that, short
 for object.  Then we get self calls of the form:

 o.frobme(...)


I really, really don't want to see .foo meaning anything but $_.foo, so how
about arranging things so that the invocant becomes $_ iff you don't give it a
name. So:

   method whatever {
 # $_ is whatever's invocant
   }

   method whosit ($self:) {
 # $_ is unbound, so:
 .this # fails
 ...
   }

Note that this would also work for mappy things with pointy subs used to name
arguments.


   method whatever {
 map { .this } .list_of_contents; # Works, but is weird...
 map - $x { .do_something_with($x.result) } # .do_something uses the
 # method's invocant.
   }

Same applies to given:

   method foo {
 given .parent - $p {
   ... # $_ is foo's invocant
 }

 given .parent {
   ... # $_ is the result of calling .parent
 }
   }



Re: return of copies vs references

2005-03-28 Thread Piers Cawley
Darren Duncan [EMAIL PROTECTED] writes:

 At 11:26 PM -0700 3/16/05, Luke Palmer wrote:
   For each of the above cases, is a copy of or a reference to the
  attribute returned?  For each, will the calling code be able to
  modify $obj's attributes by modifying the return values, or not?

Well if you're making accessors, why the heck are you making them
private?  But I can't really answer your question, because it depends on
how you write the accessors.

 I am writing accessors to mediate with the attributes, which are all private,
 and whose implementation may change over time.  What I want, in the normal
 case, is that calling code which invokes my methods will get a copy of
 attributes which it can modify, that won't affect the original attribute
 values.

 When I last asked a related question here, I was told that simply returning
 an attribute will allow the caller to modify the original attribute by
 default.  I wanted to make sure this didn't happen.  It is possible that
 there was a misunderstanding regarding the previous question, and the default
 action is in fact a copy.

Doesn't that rather depend on the type of the attribute? Personally, if I get
an object back from accessor method then I expect that any modifications of
that object's state will be seen the next time I look at the results of that
accessor method. This is a direct result of the way reference types work, and
the world is a better place because of it. If you want a (deep) copy of the
returned object you should say so:

   my $res = $object.attribute.clone;






Re: Objects, classes, metaclasses, and other things that go bump in the night

2004-12-16 Thread Piers Cawley
Dan Sugalski [EMAIL PROTECTED] writes:

 At 11:13 AM +0100 12/14/04, Leopold Toetsch wrote:
Dan Sugalski [EMAIL PROTECTED] wrote:

   subclass - To create a subclass of a class object

Is existing and used.

 Right. I was listing the things we need in the protocol. Some of them 
 we've got, some we don't, and some of the stuff we have we probably 
 need to toss out or redo.

add_parent - To add a parent to the class this is invoked on
   become_parent - Called on the class passed as a parameter to 
 add_parent

What is the latter used for?

 To give the newly added parent class a chance to do some setup in the 
 child class, if there's a need for it. There probably won't be in 
 most cases, but when mixing in classes of different families I think 
 we're going to need this.

The chap who's writing Ruby on Rails, a very capable framework reckons
that some of these 'meta' method calls that Ruby has in abundance have
really made his life a lot easier; they're not the sort of things you
need to use very often, but they're fabulously useful when you do.



Re: continuation enhanced arcs

2004-12-08 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:
 Leopold Toetsch [EMAIL PROTECTED] writes:

  ... While S registers hold pointers, they have
  value semantics.

 Is that guaranteed? Because it probably needs to be.

 It's the current implementation and tested.

  This would restore the register contents to the first state shown above.
  That is, not only I and N registers would be clobbered also S registers
  are involved.

 That's correct. What's the problem? Okay, you've created an infinite
 loop, but what you're describing is absolutely the correct behaviour for
 a continuation.

 Ok. It's a bit mind-twisting but OTOH it's the same as setjmp/longjmp
 with all implications on CPU registers. C has the volatile keyword to
 avoid clobbering of a register due to a longjmp.

  Above code could only use P registers. Or in other words: I, N, and S
  registers are almost[1] useless.

 No they're not. But you should expect them to be reset if you take a
 (full) continuation back to them.

 The problem I have is: do we know where registers may be reset? For
 example:

 $I0 = 10
   loop:
 $P0 = shift array
 dec $I0
 if $I0 goto loop

 What happens if the array PMC's Cshift get overloaded and does some
 fancy stuff with continuations. My gut feeling is that the loop might
 suddenly turn into an infinite loop, depending on some code behind the
 scenes ($I0 might be allocated into the preserved register range or not
 depending on allocation pressure).

 Second: if we don't have a notion that a continuation may capture and
 restore a register frame, a compiler can hardly use any I,S,N registers
 because some library code or external function might just restore these
 registers.

This is, of course, why so many languages that have full continuations
use reference types throughout, even for numbers. And immutable strings...


Re: continuation enhanced arcs

2004-12-07 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:

 Further to my last response. If you have things set up so that you can
 return multiple times from the same function invocation then the return
 continuation should have been replaced with a full continuation before
 the first return, so even the first return will use copying semantics,
 and the registers will always be restored to the state they were in when
 the function was first called, which is absolutely the right thing to
 do.

 Here is again the example I've brought recently. Please go through it
 and tell me what's wrong with my conclusion.


$I0 = 42 # set I16, 42 42
$N0 = 2.5# set N16, 2.5..101...
$S0 = a# set S16, a0x1004  - a
$P0 = a# set P16, a0x2008  - a
   loop:
foo()# set P0, ...; invokecc

  We have some temporary variables and a function call. Variables are used
  beyond that point, so the register allocator puts these in the preserved
  register range. The function Cfoo() might or might not capture the
  continuation created by the Cinvokecc opcode.

  Let's assume, it is captured, and stored into a global, if it wasn't
  already, i.e. the first time. According to Dan's plan, the function
  return restores the register contents to the state of the creation of
  the return continuation, which is shown in the right column.

$I0 += 1 # add I16, 1  43
$N0 *= 2.0   # mul N16, 2.0.101
$S0 .= b   # concat S16, b 0x1008  - ab
inc $P0  # inc P16 0x2008  - b
dec a# dec P17 0x200c  - 1
if a goto loop   # if P17, loop

  A note WRT strings: the concat might or might not assign a new string to
  S16. It depends on the capacity of the string buffer. But generally:
  string operations do create new string headers with a different memory
  address like shown here. While S registers hold pointers, they have
  value semantics.

Is that guaranteed? Because it probably needs to be.


  Now we loop once over the function call. This creates a new return
  continuation and on function return registers are restored to their new
  values (44, 10.0, abb, c). All fine till here.

  The loop counter a reaches zero. Now the next instruction is
  another function call.

bar()# set P0, ... invokecc

  The bar() function extracts the return continuation captured in the
  first call to foo() from the global and invokes it. Control flow
  continues right after the invokecc opcode that called foo().

  This would restore the register contents to the first state shown above.
  That is, not only I and N registers would be clobbered also S registers
  are involved.

That's correct. What's the problem? Okay, you've created an infinite
loop, but what you're describing is absolutely the correct behaviour for
a continuation. If you need any state to be 'protected' from taking the
continuation then it needs to be in a lexical or a mutated PMC. This is
just how continuations are supposed to work. 

  Above code could only use P registers. Or in other words: I, N, and S
  registers are almost[1] useless.

No they're not. But you should expect them to be reset if you take a
(full) continuation back to them. 

Presumably if foo() doesn't store a full continuation, the restoration
just reuses an existing register frame and, if foo has made a full
continuation its return does a restore by copying?


Re: continuation enhanced arcs

2004-12-06 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:
 Leopold Toetsch [EMAIL PROTECTED] writes:

 Matt Fowles [EMAIL PROTECTED] wrote:

 Thanks for the clear explanation.  I did not realize that S registers
 could switch pointers, that does make things a little harder.  I have
 a recommendation for a possible hybrid solution.  Incur the cost of
 spilling I,S,N registers heavily.  Restore the state of P register.

 My conclusion was that with the copying approach I,S,N registers are
 unusable.

 But you only need to copy when the frame you're restoring is a full
 continuation

 Yes. With the effect that semantics of I,S,N (i.e. value registers)
 suddenly changes.

 I'd submit that, in the vast majority of cases you're not going to be
 dealing with full continuations, and on the occasions when you are the
 programmer using them will be aware of the cost and will be willing to
 pay it.

 *If* the programmer is aware of the fact that a subroutine can return
 multiple times, he can annotate the source so that a correct CFG is
 created that prevents register reusing alltogether. The problem is
 gone in the first place.

 *If* that's not true, you'd get the effect that suddenly I,S,N registers
 restore to some older values which makes this registers de facto unusable.

But they're bloody value registers. They're *supposed* to restore to the
state they were in when the function was originally called. Which is
what copying semantics does.



Re: continuation enhanced arcs

2004-12-06 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:
 Leopold Toetsch [EMAIL PROTECTED] writes:

 Matt Fowles [EMAIL PROTECTED] wrote:

 Thanks for the clear explanation.  I did not realize that S registers
 could switch pointers, that does make things a little harder.  I have
 a recommendation for a possible hybrid solution.  Incur the cost of
 spilling I,S,N registers heavily.  Restore the state of P register.

 My conclusion was that with the copying approach I,S,N registers are
 unusable.

 But you only need to copy when the frame you're restoring is a full
 continuation

 Yes. With the effect that semantics of I,S,N (i.e. value registers)
 suddenly changes.

 I'd submit that, in the vast majority of cases you're not going to be
 dealing with full continuations, and on the occasions when you are the
 programmer using them will be aware of the cost and will be willing to
 pay it.

 *If* the programmer is aware of the fact that a subroutine can return
 multiple times, he can annotate the source so that a correct CFG is
 created that prevents register reusing alltogether. The problem is
 gone in the first place.

 *If* that's not true, you'd get the effect that suddenly I,S,N registers
 restore to some older values which makes this registers de facto
 unusable.

Further to my last response. If you have things set up so that you can
return multiple times from the same function invocation then the return
continuation should have been replaced with a full continuation before
the first return, so even the first return will use copying semantics,
and the registers will always be restored to the state they were in when
the function was first called, which is absolutely the right thing to
do.



Re: continuation enhanced arcs

2004-12-05 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Matt Fowles [EMAIL PROTECTED] wrote:

 Thanks for the clear explanation.  I did not realize that S registers
 could switch pointers, that does make things a little harder.  I have
 a recommendation for a possible hybrid solution.  Incur the cost of
 spilling I,S,N registers heavily.  Restore the state of P register.

 My conclusion was that with the copying approach I,S,N registers are
 unusable.

But you only need to copy when the frame you're restoring is a full
continuation (and, actually, if copy on write works at a per register
level, copy on write might be the way to go). If it's a return
continuation you can simply use the stored state. 

I'd submit that, in the vast majority of cases you're not going to be
dealing with full continuations, and on the occasions when you are the
programmer using them will be aware of the cost and will be willing to
pay it.



Re: continuation enhanced arcs

2004-12-05 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 Piers Cawley writes:
 I'd submit that, in the vast majority of cases you're not going to be
 dealing with full continuations, and on the occasions when you are the
 programmer using them will be aware of the cost and will be willing to
 pay it.

 Yeah probably.  Except the problem isn't the cost.  The problem is the
 semantics.  If you copy the registers, then when you invoke the
 continuation, their *values* restore to what they were when you made the
 continuation.  These are not proper semantics, and would result in
 subtle, incorrect infinite loops.

PMCs don't relocate, so the values you're restoring are simply the
addresses of said PMCs. The Numeric registers are value registers
anyway so no problem there (since there's no way of making a pointer to
the contents of such a register AFAICT). I'm not sure about string
registers.

And anyway, copying is how it used to work, and work it did, albeit slowly.


Re: continuation enhanced arcs

2004-11-28 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:
 Leopold Toetsch [EMAIL PROTECTED] writes:

 We don't have a problem WRT register preservation, the problem arises
 due to register re-using.

 Ah! [a light goes on over Piers's head].

 Or am I missing something fundamental?

 I don't know ;)

 I was. Hmm... bugger. So, unless we make the register allocator solve
 the halting problem, the rule becomes If you're playing silly beggars
 with continuations and you're expecting to get at something in a
 'surprising' way, stuff it in a lexical or we guarantee that you will be
 anally violated by an enraged waterbuffalo that's just sick to death of
 non-determinism?

 This would make quite a fine explanation in the docs, except that's a
 bit unclear about stuff *it*. The waterbuffalo is concerned of
 preserved *temporary* variables too.

I just thought of a heuristic that might help with register
preservation:

A variable/register should be preserved over a function call if either of the
following is true:

1. The variable is referred to again (lexically) after the function has
   returned.  
2. The variable is used as the argument of a function call within the
   current compilation unit.

Condition 2 is something of a bugger if you have big compilation units,
but register allocation is always going to be a pain when there are big
compilation units around.



Re: continuation enhanced arcs

2004-11-26 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:
 Okay, I'm confused, I thought that the whole point of a caller saves,
 continuation passing regime was that the caller only saves what it's
 interested in using after the function returns.

 We don't have a problem WRT register preservation, the problem arises
 due to register re-using.

 ... Exactly *where* that
 return happens, and whether it happens more than once, is completely
 irrelevant from the point of view of the caller.

 The return can only happen, where the normal function call would have
 returned, but anyway.

 ... ISTM that the register
 allocator should work on the principle that anything it didn't save
 before it made the call will be toast afterwards.

 Yes. But - please remember your example Fun with nondeterministic searches.
 Here's the relevant piece of code from main:

arr1=[1,3,5]
arr2=[1,5,9]
x = choose(arr1)
y = choose(arr2)
$P0 = find_lex fail
$P0()

 You know, both choose calls capture the continuation and backtrack via
 fail (basically). But the register allocator isn't aware of that. The
 control flow graph (CFG) is linear top down, with new basic blocks
 starting after each function call. arr2 is obviously used around a
 call and allocated in the preserved (non-volatile) register area. This
 works fine.

 Now the register allocator assigns a register to $P0. It finds the
 register that arr2 had usable, because in a linear CFG, there's no way
 that arr2 might be used again. So that register is considered being
 available. Now if $P0 happens to get the register that arr2 had,
 backtracking through the call to fail() obviously fails, as arr2 is
 now the Closure PMC. And that was exactly the case.

Ah! [a light goes on over Piers's head].


 Or am I missing something fundamental?

 I don't know ;) 

I was. Hmm... bugger. So, unless we make the register allocator solve
the halting problem, the rule becomes If you're playing silly beggars
with continuations and you're expecting to get at something in a
'surprising' way, stuff it in a lexical or we guarantee that you will be
anally violated by an enraged waterbuffalo that's just sick to death of
non-determinism?
 




Re: continuation enhanced arcs

2004-11-25 Thread Piers Cawley
Okay, I'm confused, I thought that the whole point of a caller saves,
continuation passing regime was that the caller only saves what it's
interested in using after the function returns. Exactly *where* that
return happens, and whether it happens more than once, is completely
irrelevant from the point of view of the caller. ISTM that the register
allocator should work on the principle that anything it didn't save
before it made the call will be toast afterwards. Doing anything more
sophisticated than optimizing register allocation on a sub by sub basis
seems like a license for getting completely and utterly plaited.

Or am I missing something fundamental?


Re: Closures and subs

2004-11-05 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Piers Cawley [EMAIL PROTECTED] wrote:
 Leopold Toetsch [EMAIL PROTECTED] writes:

 Klaas-Jan Stol [EMAIL PROTECTED] wrote:
 Hello,

 I've been playing with closures and subs but I have a little bit of
 trouble with those.

  newsub $P0, .Closure, _foo
  $P0(q)
  newsub $P0, .Closure, _foo
  $P0(q)

 Closures have to be distinct.

 Does this *really* mean that, if I create a closure in a function and
 return it to my caller, that closure can only be invoked once?

 No, it can be invoked as often you like.

 But above case seems to be different and very similar to what I already
 asked:

   (define (choose . all-choices)
 (let ((old-fail fail))
   (call-with-current-continuation

 You remember that snippet, it's now a test in t/op/gc.t. I had to insert
 the line below XXX and use a second closure, which has the arr2 in it's
 context.

  newsub choose, .Closure, _choose
  x = choose(arr1)

  # XXX need this these closures have different state
  newsub choose, .Closure, _choose
  y = choose(arr2)

 The question was, if that's technically correct.

Ah... of course, I was asking a stupid question. Always the most
plausible hypothesis I think. 

-- 
Piers 
Oh, predicting the future's easy, you just make a continuation at the
point you're asked, say anything and head off into the future to find what
happens, then take the continuation back to the question and give a more
accurate answer. -- me in #parrot



Re: Why is the fib benchmark still slow - part 1

2004-11-05 Thread Piers Cawley
Miroslav Silovic [EMAIL PROTECTED] writes:

 Leopold Toetsch wrote:

 I believe that you shouldn't litter (i.e. create an immediately
 GCable object) on each function call - at least not without
 generational collector specifically optimised to work with this.


 The problem isn't the object creation per se, but the sweep through
 the *whole object memory* to detect dead objects. It's of course true,
 that we don't need the return continuation PMC for the fib benchmark.

 Well, creation is also the problem if you crawl the entire free heap
 before triggering the next GC round. You get a potential cache miss on
 each creation and on each mark and on each destruction. To keep GC out
 of the way, the entire arena has to be confined to cache size or less.

 But a HLL translated fib would use Integer PMCs for calculations.

 Hmm, I'm nitpicking here, but it's not how e.g. Psyco works. It
 specialises each function to specific argument types and recompiles for
 each new argument type set. Assuming that you'll call only very few
 functions with more than 1-2 type combinations, this is a good tradeoff.
 It also removes a lot of consing, especially for arithmetics.


 ...  This would entail the first generation that fits into the CPU
 cache and copying out live objects from it. And this means copying GC
 for Parrot, something that (IMHO) would be highly nontrivial to
 retrofit.


 A copying GC isn't really hard to implement. And it has the additional
 benefit of providing better cache locality. Nontrivial to retrofit or
 not, we need a generational GC.

The catch with generation GC is that, once you have guaranteed
destructors being called promptly, you still have to sweep the whole
arena every time you leave a scope.


Re: Closures and subs

2004-11-04 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Klaas-Jan Stol [EMAIL PROTECTED] wrote:
 Hello,

 I've been playing with closures and subs but I have a little bit of
 trouble with those.

  newsub $P0, .Closure, _foo
  $P0(q)
  newsub $P0, .Closure, _foo
  $P0(q)

 Closures have to be distinct.

Does this *really* mean that, if I create a closure in a function and
return it to my caller, that closure can only be invoked once?

If it does, this is slightly more broken than a very broken thing.


Re: Are we done with big changes?

2004-11-02 Thread Piers Cawley
Jeff Clites [EMAIL PROTECTED] writes:

 On Nov 1, 2004, at 6:14 AM, Dan Sugalski wrote:

 Because I need to get strings working right, so I'm going to be
 implementing the encoding/charset library stuff, which is going to
 cause some major disruptions.

 Please tag cvs before checking this in.

Release candidate?



Re: [CVS ci] indirect register frames 14 - cache the register frame

2004-11-02 Thread Piers Cawley
Dan Sugalski [EMAIL PROTECTED] writes:

 At 2:30 PM -0500 11/2/04, Matt Fowles wrote:
All~

I don't like the idea of having to dig down through the entire return
chain promoting these guys.  Is there a reason not to use DOD/GC to
recycle continuations?

 Yes. Speed.

 While you can skip some of the digging (since you can stop at the 
 first promoted one) the reality is that 90%+ of the return 
 continuations will *never* need promoting. Not bothering to make the 
 return continuations true full continuations until they're actually 
 needed as one lets us immediately recycle return continuations as 
 soon as they're used in the near-overwhelming majority of the cases 
 -- that is, when nothing can possibly have a hold of 'em. That leaves 
 a lot fewer objects for the DOD to sweep through, as well as speeding 
 up allocation (since we're more likely to have ones at hand, and 
 likely in cache too) of the things in the first place.

And, dammit, making a full continuation isn't something a programmer
should do lightly. 


Re: [OT] Perl 6 Summary for 2004-10-01 through 2004-10-17

2004-10-26 Thread Piers Cawley
Aldo Calpini [EMAIL PROTECTED] writes:

 Larry Wall wrote:
 I suppose if I were Archimedes I'd have climbed
 back out and shouted Eureka, but as far as I know Archimedes never
 made it to Italy, so it didn't occur to me...

 well, Archimedes *was* italian. for some meaning of italian, at least. 
 he was born in Syracuse (the one in Sicily, not the one in the state of 
 NY obviously :-). he lived and studied in Egypt, but most of his life 
 was spent in Syracuse. granted, Sicily at that time was more a Greek 
 region than an Italian one as it is today, but well, geographically 
 speaking, it is in Italy.

 and of course, Venice was founded ~700 years after Archimedes death, so 
 he really had no chance of falling into your same canal.

But the odds are good that at least one of the water molecules in said
canal passed some of its time in Archimedes body (or one of its
constituent atoms did). 


Re: [pid-mode.el] cannot edit

2004-10-04 Thread Piers Cawley
Stéphane Payrard [EMAIL PROTECTED] writes:

 On Fri, Oct 01, 2004 at 06:09:37PM +0200, Jerome Quelin wrote:
 Hi,
 
 I tried the pir-mode provided in the editor/ subdir. And when opening a
 .imc file (I've associated .pir with pir-mode + font-lock-mode), I
 cannot type spaces or carriage returns:
 
 (24) (warning/warning) Error caught in `font-lock-pre-idle-hook':
 (invalid-regexp Invalid syntax designator)
 
 And the minibuffer tells me:
 Symbol's function definition is void: line-beginning-position
 
 I'm using xemacs 21.4.14
 
 Is the pir-mode.el file complete? Or am I encountering a bug in
 it?

 This function is defined in emacs:

   line-beginning-position is a built-in function.
   (line-beginning-position optional N)

   Return the character position of the first character on the current line.
   With argument N not nil or 1, move forward N - 1 lines first.
   If scan reaches end of buffer, return that position.

   The scan does not cross a field boundary unless doing so would move
   beyond there to a different line; if N is nil or 1, and scan starts at a
   field boundary, the scan stops as soon as it starts.  To ignore field
   boundaries bind `inhibit-field-text-motion' to t.

   This function does not move point.

 switch to emacs. :)

Or patch pir-mode.el, your choice.


Re: Continuation re-invocation

2004-09-27 Thread Piers Cawley
Jeff Clites [EMAIL PROTECTED] writes:

 Two questions:

 1) Is it supposed to be possible to invoke a given continuation more 
 than once, or is it used up once invoked?

Yes, you should be able to invoke one more than once.


 2) Am I supposed to be able to jump down the stack by invoking a 
 continuation? To be specific, if A calls B calls C, and C invokes the 
 return continuation which takes it directly back to A, can something 
 later invoke the return continuation which leads to B? (Emphasizing 
 there the notion that something skipped over a continuation, then 
 later came back and used it.)

Yes.


Re: towards a new call scheme

2004-09-24 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Dan Sugalski wrote:

 At 4:15 PM +0200 9/23/04, Leopold Toetsch wrote:
   get_cc(OUT Px)  # 1) get current continuation, i.e. the return cont.
 In a rare, possibly unique burts of opcode parsimoniousness... perhaps
 this would be a good thing for the interpinfo op. 

 That's fine too.


   return_cc() # 2) return via current continuation

 1) is only needed for special porposes, like passing the continuation
 on to a different place. The normal way to return from a sub will be
 2)

 If that's in, access to CP1 as a return continuation will be
 deprecated.
 Well... should we? We're still passing the return continuation *in* in
 P1, unless you want to move it out and unconditionally make it a
 parameter to invoke. 

 Well, basically, if an interpreter template is used (hanging off the 
 subroutine), the previous interpreter template is the return 
 continuation. That means that for the usual case (function call and 
 return) there isn't any need to construct a return continuation and put 
 it somewhere. The return continuation would only be needed to create a 
 real continuation out of it and pass it along somewhere.

 If that calling scheme doesn't fly, its still better to have specific 
 locations in the interpreter context that hold the sub and the return 
 continuation to allow simple function backtrace for the error case or 
 introspection. That's currently not possible, because P0 and P1 can be 
 swapped out into the register backing stack and reused to hold something 
 totally different.

 I think I'd also like to make a change to sub invocation, too, to
 allow passing in alternate return continuations, which makes tail
 calls easy. 

 Ok. Good point. We could get rid of Cinvoke Px (call the sub in Px w/o 
 calling conventions) in favor of Cinvoke_with_retc Px. Anyway, the 
 visible part of a return continuation (in above opcode or Cget_cc 
 would be a continuation. The normal case (call/return) could just have 
 that continuation internally in the context. No additional PMC is 
 constructed ifn't needed.

I could be wrong here, but it seems to me that having a special
'tailinvoke' operator which simply reuses the current return
continuation instead of creating a new one would make for rather faster
tail calls than fetching the current continuation out of the interpreter
structure, then invoking the target sub with with this new
continuation (ISTM that doing it this way means you're going to end up
doing a chunk of the work of creating a new return continuation anyway,
which rather defeats the purpose.)



Re: Current state?

2004-09-13 Thread Piers Cawley
Jared Rhine [EMAIL PROTECTED] writes:

 [Patrick == [EMAIL PROTECTED] on Wed, 8 Sep 2004 11:51:18 -0600]

   Patrick ...in the immediate future we'll be wanting rules/grammar
   Patrick tests (to test the grammar engine) more than we'll need
   Patrick perl 6 code, although we'll certainly take that as well.

 If you wanted to describe the form such tests might take, maybe
 Herbert will get excited enough to pitch in with such tests.  I grok
 the difference between the grammar engine and the actual compiler, but
 I'm blanking on how to describe the process of writing tests that
 aren't simple Perl 6 code snippet style tests at this early stage.

How about:

/a pattern/

target_string matches? $1 $2 $3...

another_target matches? $1 ... 

/another pattern/

...

The game is to get a bunch of tests written. Given a sufficiently
regular layout Luke and Patrick can no doubt write some code that will
massage things into something that can get run under some test harness.


Re: Iterators and Cfor

2004-09-09 Thread Piers Cawley
Aaron Sherman [EMAIL PROTECTED] writes:

 On Thu, 2004-09-09 at 13:14, Larry Wall wrote:

 So whereas Ruby's syntax actually tends to push you toward .each
 iterators, Perl 6's syntax will be fairly neutral on the subject,
 or maybe biased every so slightly away from method iteration by the
 width of about one character:
 
 for @foo { ... }
 @foo.each:{ ... }
 
 But then, a good Ruby programmer would have put a space where there's
 a colon anyway, so maybe it's a wash.  If I wanted to make it even
 I'd pick something shorter than each, I suppose.  Except all is
 already taken.  I suppose there's something to be said for:
 
 @foo.for:{ ... }

 act any are ask cog cue did ere for get got has hop jet job kin
 let map mix net now one ore per pro put run set tag

 I won't describe why I think each one would be appropriate, since if
 it's not obvious, it's a bad choice ;-)

I find myself wondering if this is going to allow people to write
smalltalk style method selectors...

   @foo.inject:0 into: - $accum, $each { $accum + $each }



Re: Current state?

2004-09-09 Thread Piers Cawley
Herbert Snorrason [EMAIL PROTECTED] writes:

 Since this list has been started, I'd assume that means work on the
 final Perl6 compiler is about to start. (Although, with this crowd,
 you never do know...)

 In the interest of a layman's curiosity: What's the current status?

 (And I already wonder if this won't make the summaries even more
 irregular. ;)

I hope not. I'm slowly getting back to a weekly schedule after the
summer. 


Re: Reverse .. operator

2004-09-06 Thread Piers Cawley
Joe Gottman [EMAIL PROTECTED] writes:

 In perl 6, the statement  

 @foo = (1.. 5) ;

 is equivalent to

 @foo = (1, 2, 3, 4, 5); 

  

 Is there similar shorthand to set @foo = (5, 3, 3, 2, 1) ?  I know you can
 go

 @foo = reverse (1 ..5);

 but this has the major disadvantage that it cannot be evaluated lazily;
 reverse has to see the entire list before it can emit the first element of
 the reversed list.  Would

 @foo = (5 .. 1 :by(-1));

 do the trick?  If so, would the same trick work for

 @bar = ('e' .. 'a' :by(-1)); ?

   @foo = 5.down_to(1)

Where down_to is 

method Number::down_to ($self : Number $target) {
return if $self  $target;
return $self, ($self - 1).down_to($target);
}

You might have to do some monkeying around with a range object or
something to make it appropriately lazy, but that's a mere detail. Or
you could implement it as an operator. Or...


Re: Numeric semantics for base pmcs

2004-08-25 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Dan Sugalski [EMAIL PROTECTED] wrote:
 At 8:45 PM +0200 8/24/04, Leopold Toetsch wrote:
Dan Sugalski [EMAIL PROTECTED] wrote:

  Nope -- we don't have bigints. :)

Pardon, sir?

 We've got the big number code, but I don't see much reason to
 distinguish between integers and non-integers at this level -- the
 only difference is exponent twiddling.

 Ah, ok. BigInt as a degenerated BigNum. I still prefer the notion that
 adding or multiplying to integers give a BigInt on overflow.

 While at num vs int: do we automatically downgrade to int again?

   6.0/2.0 = 3.0 or 3 ?

No. Once a real, always a real. I see no harm in collapsing appropriate
rationals to ints mind...


Re: Tight typing by default?

2004-08-25 Thread Piers Cawley
Dan Sugalski [EMAIL PROTECTED] writes:

 It seems pretty clear that the general opinion is that operations 
 should produce the tightest reasonable type for an operation--integer 
 multiplication should produce an integer unless it can't, for example.

 For our purposes I think the typing should go:

platform int-float-bignum

 with an operation producing a type no tighter than the loosest type 
 in the operation. (so int/float gives a float, float-bignum gives a 
 bignum)

 This seem reasonable?

No. int-bignum-float 

In other words, floats only happen if you specifically introduce them
(or take a square root or something).


Re: The new Perl 6 compiler pumpking

2004-08-04 Thread Piers Cawley
Dan Sugalski [EMAIL PROTECTED] writes:

 There's not been a big public announcement, so it's time to change that.

 I'd like everyone to give a welcome to Patrick Michaud, who's 
 volunteered to officially take charge of getting the Perl 6 compiler 
 module written. I've put in yet another nudge to get the 
 parrot-compilers list started, and get the perl6-internals list 
 renamed to parrot-internals (which is what it really is) so we can 
 get things properly sorted out, as I expect Patrick will be digging 
 into the fun stuff pretty darn soon.

Mmm... three list to summarize...



Re: This week's summary

2004-07-29 Thread Piers Cawley
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes:

 Piers Cawley wrote:
 Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes:
Care to explain what those are, O great math teacher?
 What's a math teacher?

 It's the right^H^H^H^H^HAmerican way to say maths teacher.

You mean American and 'right' are not equivalent? Wow.



Re: This week's summary

2004-07-28 Thread Piers Cawley
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] writes:

 The Perl 6 Summarizer wrote:
   The infinite thread
 Pushing onto lazy lists continued to exercise the p6l crowd (or at
 least, a subset of it). Larry said that if someone wanted to hack
 surreal numbers into Perl 6.1 then that would be cool.

 Care to explain what those are, O great math teacher?

What's a math teacher?


Re: String interpolation

2004-07-26 Thread Piers Cawley
Larry Wall [EMAIL PROTECTED] writes:

 On Tue, Jul 20, 2004 at 11:00:39PM -0700, chromatic wrote:
 : On Tue, 2004-07-20 at 19:35, Luke Palmer wrote:
 : 
 :  The New Way (tm) to do that would probably be sticking a role onto the
 :  array object with which you're dealing:
 :  
 :  my @foo does separator('//') = (1,2,3,4,5);
 :  say [EMAIL PROTECTED];   # 1//2//3//4//5
 : 
 : Shh, no one's let slip the idea of curried roles yet!  I'm not even
 : certain A12 mentioned parametric roles, let alone first-class roles.

 Well, A12 did talk about parametric roles, but I glossed over the
 first-class roles a bit.  I didn't want to scare people with

 $foo does $bar

 though, of course, there's no reason in principle you shouldn't be able
 to do that as a run-time operation.  You just can't instantiate a role
 object.  The murky area in the middle is, of course, how you specify
 an initial value aimed at the attributes of a particular role without
 creating a real object containing just those values.  Passing around
 lists of pairs is probably good enough for that, as long as you can
 keep straight which list of pairs is intended to initialize which
 roles.

I really hope you change your mind about this; the sooner I can get
that wild and crazy list of pairs nicely stashed in their appropriate
role objects, the happier I'll be about the resilience of my code.


Re: String interpolation

2004-07-26 Thread Piers Cawley
Damian Conway [EMAIL PROTECTED] writes:
 I can't say I'm keen on making {...} special in strings. I felt that the
 $(...) and @(...) were a much cleaner and more general solution. The
 prospect of backslashing every opening brace in every interpolated
 string is not one I relish.

Maybe we could write macros to provide a Lispish 'metaquoted'
environment for when one is writing template code which wouldn't
interpolate *anything* unless it was in C$(...) or C@(...). 



Re: the whole and everything

2004-07-20 Thread Piers Cawley
Leopold Toetsch [EMAIL PROTECTED] writes:

 Dan Sugalski [EMAIL PROTECTED] wrote:

 Leo, we've talked about this before. The sensible and straightforward
 thing to do in a case like this is to tag in the sub pmc which
 register frames are used by the sub.

 And what, if the sub calls another sub?

Then the call to the inner sub saves the registers that are used by the
inner sub.


Re: scalar subscripting

2004-07-12 Thread Piers Cawley
Luke Palmer [EMAIL PROTECTED] writes:

 Gautam Gopalakrishnan writes:
 Hello,
 
 I've tried the archives and the 'Perl 6 essentials' book and I can't
 find anything
 about string subscripting. Since $a[0] cannot be mistaken for array subscripting
 anymore, could this now be used to peep into scalars? Looks easier than using
 substr or unpack. Hope I've not missed anything obvious.

 Well, no, it can't really.  $a[0] now means what Perl 5 called $a-[0]
 (or @$a[0]).  So it's still an array subscript, it's just subscripting
 $a, not @a.

So, it should be possible to define 

  method postcircumfix:[] is rw { ... }

in the String class to do the right thing? Or even to define it in some
Sequence trait that both arrays and strings share? Of course, the
putative method would have to take into account the calling context's
Unicode behaviour, but I can't see why it shouldn't be possible.



  1   2   3   4   5   6   7   >