Re: Exceptuations

2005-10-06 Thread Peter Haworth
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.

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.

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

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

-- 
Peter Haworth   [EMAIL PROTECTED]
Disconcerting Haworth Fortress Unicycling Melody Gundam
-- http://www.channel4.com/4later/bits/manga.html


Re: Exceptuations

2005-10-05 Thread Peter Haworth
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.

 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?

This kind of exception should never get so far up the call chain,
except possibly as a nested cause of a more general exception. The
customer is in no position to get the book dealer to choose a
different stock picker - that's up to the order picking department of
the book shop. If it doesn't get handled there, then maybe the book
shop can try sourcing the book externally, and if that fails, they may
defer your order until later. The shop could ask the customer's
opinion as to the suitability of each of these options, but the
customer shouldn't have to know how the shop is implemented and make
such decision unprompted.

Even given a continuation to some low level routine, anything the
caller does is likely to be too far removed to make it sensible to
resume the continuation.

Eiffel deals with this by brutally its Design By Contract magic
bullet: Since all the code catching the exception knows about is its
own implementation, the only sane option it has is to try performing
the subtask in a different way. Here's how Eiffel's rescue/retry might
work in perl6, where rescue is spelled CATCH.

  class Picker{
# An individual order picker can pick a book, but may unfortunately
#   die of lung cancer, or just fail to find the book
method pick($book){
  fail Err::LungCancer if .is_smoker();
  ...
  fail Err::BookNotFound if ...;
}
  }

  class PickingDept{
# The picking department employs pickers to pick books
# If an employee dies of lung cancer while picking an order,
#   they are removed from the roster, and a different picker is chosen
# If the department doesn't have enough free pickers,
#   it just throws a too busy exception
# Due to the retry semantics, the department will keep choosing pickers
#   until one of them can pick the book, or they all die of lung cancer,
#   (or they're all busy doing something else)
method pick($book){
  my $picker=.find_free_picker();
  $picker.pick($book);
  ...

  CATCH{
when Err::NoPickersAvailable { fail Err::DeptTooBusy; }
when Err::LungCancer {
  .fire_picker($picker); # Harsh, but we won't find him again
  retry; # This re-runs the tried block (method) from the top
}
when Err::BookNotFound { fail Err::OutOfStock; } # Optimistic, maybe
default { fail; }
  }
}
  }

  class BookStore{
# The book store has multiple picking departments, so if one of them fails
# to find a book, the others can be tried. If that fails, they could order
# the book from the wholesaler and defer the order, but I'm too lazy
method order($book){
  for @.depts - $dept {
try{
  $dept.pick($book);
  return;
  
  CATCH{ 1; } # We'll just try the next one
}
  }
  fail Err::BookNotFound;
}

...
  }

  class Customer{
# The customer doesn't have any say in how bookshops are run, so all
# they can do if their order is refused, all they can do is try another
# shop, or give up and go home
method buy_book($book){
  $random_bookshop.order($book);

  CATCH{ fail Err::BookObviouslyDoesntExist; }
}
  }
  

-- 
Peter Haworth   [EMAIL PROTECTED]
Hestons' First Law: I qualify virtually everything I say.


Re: Nested captures

2005-05-17 Thread Peter Haworth
On Mon, 09 May 2005 22:51:53 +1000, Damian Conway wrote:
  # Perl 6...
# $1  $2$3   $4$5   $6
  $tune_up6 = rx/ (don't) (ray) (me) (for) (solar tea), (d'oh!)
# $1  $2  $3$4$5
| (every) (green) (BEM) (devours) (faces)
/;

Does numbering of captures after an alternation continue as if the
alternative with the most captures matched?

#   $1$1  $2$3, even if (a) matched
  rx/ [ (a) | (b) (c) ] (d) /;


If you explicitly number the first capture in one alternative, does that
affect the numbering of the other alternatives?

#   $4$4
  rx/ [ $4:=(a) | (b) ] /;


 Note that, outside a rule, C@1 is simply a shorthand for C@{$1}

Is @/ also a shorthand for @{$/} ?


-- 
Peter Haworth   [EMAIL PROTECTED]
I am continually amazed by the intuitive straightforwardness of the interface
 of my microwave and oven. If they were designed by the people who design
 computer interfaces, it would take both hands and several minutes just to set
 the timer.-- Adam Rice


Re: New S29 draft up

2005-03-23 Thread Peter Haworth
On Mon, 21 Mar 2005 08:41:27 -0800, Larry Wall wrote:
 Okay, I've come around to liking it, but I think we have to say that
 0x, 0d, 0o, 0b, and whatever else we come up with are just setting
 the default radix. If a string comes in with an explicit 0x, 0d, 0o,
 or 0b, we believe that in preference to the operator.

Don't we trust the programmer more than the data? I want this code to
produce 4660, 22136, 2832, 3394; not 4660, 22136, 4, 42.

  for '1234','5678','0b10','0d42' {
say 0x $_;
  }

-- 
Peter Haworth   [EMAIL PROTECTED]
It's not a can of worms, it's a tank of shai-hulud.
-- Jarkko Hietaniemi


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

2005-03-21 Thread Peter Haworth
On Fri, 18 Mar 2005 09:45:57 -0800, Larry Wall wrote:
 I think we'll need to figure out how to shorten $_.foo instead.

It looks short enough to me already. More importantly, its meaning
is immediately obvious.

 Either that, or there has to be a way to explicitly make $_ the
 invocant of a subblock.

How about something like this?

  method foo{
.bar; # Acts on self
for @stuff {
  .bar; # Acts on self
}
for @stuff - $_ :self {
  .bar; # Acts on self, which is currently $_
}
  }

Seems like overkill for trivial blocks though:

  map - $_ :self { .bar } 1..10;

but you can still just write $_.bar

Maybe we could allow $_ to be elided?

  map - :self { .bar } 1..10;


 At the moment I'm trying to see if I could get used to ..method
 meaning $_.method, and whether it buys me anything psychologically.

I still prefer $_.method


 Suppose you are one of those rare people who actually checks the
 return value of print to see if you filled up the disk:

 if print {...}

 That doesn't parse currently ... (Backtracking the parser is
 probably not the right answer.)

If you're going to the trouble to check that (which I do,
sometimes), surely two extra characters [$_ or ()] aren't that
much of a problem? You probably wouldn't be using implicit
variables, anyway.

A backtracking parser seems pretty scary to me. If it takes a lot of
work for the compiler to figure things out, it's going to be even
harder for the programmer.

-- 
Peter Haworth   [EMAIL PROTECTED]
I think this is one of those traumatic things eggs have to face
 to prepare a good omelette.
-- Jarkko Hietaniemi


Re: Synopsis 4 draft 1

2004-09-03 Thread Peter Haworth
On Thu, 19 Aug 2004 19:45:37 -0700, Larry Wall wrote:
 To process two arrays in parallel, use either the zip function:

 for zip(@a,@b) - $a, $b { print [$a, $b]\n }

 or the zipper operator to interleave them:

 for @a ¥ @b ¥ @c - $a, $b, $c { print [$a, $b, $c]\n }

n-ary zip() is simple enough, but the infix ¥ makes zipping more than
two lists somewhat entertaining. Without iterators doesn't work well:

  @a ¥ @b produces (@a[0],@b[0],@a[1],@b[1],...)

which is what we wanted, but

  @a ¥ @b ¥ @c produces (@a[0],@c[0],@b[0],@c[1],@a[1],@c[2],@b[1],...)

which isn't. The compiler *could* be made to detect such cases, and
turn them into

  zip(@a,@b,@c)

but that seems like piling even more onto the poor compiler's
plate, which already has to be the size of the whole table. It also
makes things harder for evil coders who want to define their own
behaviour for ¥.

If we implement ¥ as an iterator (which is surely the plan), we can
get more fancy. With two lists as arguments, we return zip(@a,@b), and
if either argument is itself a zip iterator, we decompose it to get
the original lists, and return zip(*lists_from(@a),*lists_from(@b)).

Great. But what if what you actually wanted was the horrible thing
that the naive non-iterator approach gives you with three lists? Do
you have to say this instead?

  *(@a ¥ @b) ¥ @c

Yuck, that's two thirds of the iteration benefit lost, or all of it if
either of @a or @b are infinite.


 A Creturn always exits from the lexically surrounding sub or
 method definition (that is, from a function officially declared with
 the Csub, Cmethod, or Csubmethod keywords). Pointy subs and
 bare closures are transparent to Creturn. If you pass a reference
 to a closure outside of its official sub scope, it is illegal to
 return from it.

Presumably this illegality only applies to closures not officially
declared as subs, methods or submethods?

-- 
Peter Haworth   [EMAIL PROTECTED]
Her vocabulary was as bad as, like, whatever.


Re: backticks

2004-04-20 Thread Peter Haworth
On Fri, 16 Apr 2004 23:45:48 +0200, Juerd wrote:
 Jonathan Scott Duff skribis 2004-04-16 15:51 (-0500):
  Except that you've put things in this explanation that shouldn't be
  there IMHO. The %varnamekey is a special case, but not of getting a
  single item from a hash, rather it's a special case of a one element
  list generated from   evaluating to the element. So, if you remove
  that bit, it's the same as the two below just with different syntax.
 
 I think %hashkey key key is best explained as %hash{  key key 
 key  } with implicit curlies, not as an alternative to curlies.

In that case, why aren't you suggesting something more in line with that?
Here's what I'd like to see instead of your suggestion:

  %hashkey key key  ===  %hash{key key key}
  %hash'key'===  %hash{'key'}
  %hashkey===  %hash{key}

That has
* as few keystrokes as perl5's $hash{key}
* delimiters at both ends, so you can even use non-bareword constants
* existing syntax reused in the same way as the  variant
* interpolation allowed in the double quoted variant.

That said, I really wish we could keep perl5's $hash{key}. It's obviously a
subscript, and I use constant bareword keys much more frequently than zero-arg
sub/builtin calls in hash subscripts.

-- 
Peter Haworth   [EMAIL PROTECTED]
The capacity of human beings to bore one another seems to be vastly greater
 than that of any other animals.  some of their most esteemed inventions
 have no other apparent purpose, for example, the dinner party of more than
 two, the epic poem, and the science of metaphysics.  -- H. L. Mencken


Re: Conditional Creturns?

2003-04-02 Thread Peter Haworth
On Tue, 1 Apr 2003 22:01:48 +0300, arcadi shehter wrote:
 Damian Conway writes:
  given baz(@args) { return $_ when defined }
  given baz(@args) { return $_ when $_  0 }
  # etc.
 
 since we have 2 forms of return -- return and leave , may be we
 can make return also to be a topicalizer for the rest of experssion
 , and then :
 
 return baz(@args) when $_  0 ; 
 return baz(@args) when defined  ; 
 return baz(@args) when true ; 

Damian's solution looks a lot better to me. I'm going to be surprised by the
behaviour of code that works like yours for a long time before I get used to
it.

-- 
Peter Haworth   [EMAIL PROTECTED]
I have to continue using UUCP for sentimental reasons
-- Ian Lance Taylor


Re: Variable Types Vs Value Types

2003-01-09 Thread Peter Haworth
On Wed, 8 Jan 2003 15:39:52 -0500, Dan Sugalski wrote:
 At 7:29 PM -0700 1/7/03, John Williams wrote:
 Perhaps you could explain how the $0 object will work in your mind.
 A5 assert that $0 is a object, and it behaves as an array and a hash,
 depending on how you subscript it.  Typeglobs are gone, and we're all
 hoping the TIE interface is gone too, so how will this effect be
 accomplished?
 
 All variables in parrot are implemented as PMCs, and all PMCs may be 
 accessed with a string, integer, or PMC subscript or set of 
 subscripts. For PMCs that don't do subscripting this will be a fatal 
 error, for those that do it'll do whatever the PMC is supposed to do. 
 (In the case of $0, do the lookup)

That's phrased like it's the type of the subscript value which determines
whether it's a hash-like or array-like access. Shouldn't it be the type of
brackets which do that?

In other words, I don't want to see this happen:

  $a[1];  # array-like
  $a['1'];# hash-like
  $a{1};  # array-like
  $a{'1'};# hash-like

It should be like this:

  $a[1];  # array-like
  $a['1'];# array-like
  $a{1};  # hash-like
  $a{'1'};# hash-like

Maybe it is the right way round, and I've read your remarks the wrong way.
Or maybe it is the value type which determines the type of access at the PMC
level, and it's up to the compiler to force the type based on the brackets.

-- 
Peter Haworth   [EMAIL PROTECTED]
After all, what is your hosts' purpose in having a party?  Surely not for
 you to enjoy yourself; if that were their sole purpose, they'd have simply
 sent champagne and women over to your place by taxi.
-- P J O'Rourke



RE: right-to-left pipelines

2002-12-12 Thread Peter Haworth
On Tue, 10 Dec 2002 13:02:18 -0800, Brent Dax wrote:
 Peter Haworth:
 #   @b = @a.grep { /\S/ }, $c;
 # 
 # how does the compiler know whether $c is an argument to grep, 
 # or another element to be assigned to @b?
 
 The same way it does when it sees a normal sub?
 
 I know, late binding and all that.  But when you think about it, a lot
 can be done to simulate the conditions otherwise.  For example, with a
 definition like this:
 
   class Foo {
   method bar($self: $baz) { ... }
   }
 
 And a call like this:
 
   @b=$foo_obj.bar $baz, $quux;
 
 Where we can see *at runtime* that $quux is too many arguments, we can
 just append it to the end of bar()'s return value.  (This would only
 happen when there were no parentheses.)

But at runtime, we don't necessarily have a good idea of what the original
code looked like (we've compiled to bytecode, and the user may have stripped
all the useful metadata from the .pbc file), or a way to generate new bytecode
on the fly (the user may have opted to exclude the runtime eval capability).
For this to work, we'd have to compile every possible variation of the syntax
tree, and decide which of them was appropriate at runtime. Ick.

In a strictly typed language you can do this without too many surprises.
I don't think it's appropriate for Perl, except possibly for certain special
cases like blocks as the only argument.

-- 
Peter Haworth   [EMAIL PROTECTED]
'As Annie Oakley almost said, Anything you can do, I can do meta.'
-- Larry Wall



Re: right-to-left pipelines

2002-12-10 Thread Peter Haworth
On 10 Dec 2002 11:41:23 +, Simon Cozens wrote:
 [EMAIL PROTECTED] (Damian Conway) writes:
  I don't think the method-call syntax allows it. I think methods
  need their parens. So we need:
  
  (@foo, @bar) := @a
  . grep( { $_  0} )
  . sort( { $^b = $^b } )
  . part( [/foo/, /bar/] );
 
 *Why* do methods need their parens? If methods can be specified to possibly
 take a block, such as grep and sort do, then they shouldn't need parens.
 Or at least, I know a language in which this is possible... :)

To know whether the method takes a block, you need to know how it's been
declared. In other words, the type of @a needs to be known to find grep's
declaration. In turn, grep must specify its return type in order to find
sort's declaration, and sort must specify its return type so that part's
declaration may be found.

That's all fine for the standard/builtin methods on arrays, but its a bit
unperl-like to force users to highly specify everything. Of course, if they
do declare methods with all the bells and whistles, they get the benefit of
not having to use parens later on.

-- 
Peter Haworth   [EMAIL PROTECTED]
Although they all look the same to me, doormats and other furnishings
 probably have a strict social heirarchy. Every chair a god. Every item
 of pottery from the Franklin mint, an angel. Man, I love decor.
-- Ashley Pomeroy



Re: right-to-left pipelines

2002-12-10 Thread Peter Haworth
On 10 Dec 2002 15:34:11 +, Simon Cozens wrote:
 [EMAIL PROTECTED] (Peter Haworth) writes:
  To know whether the method takes a block, you need to know how it's been
  declared. In other words, the type of @a needs to be known to find
  grep's declaration.

 Well, that's what always happens on a method call.

At run time, yes. However, at compile time, due to Perl's dynamic nature,
you don't know how methods have been declared unless the programmer is using
the optional BD features.

  In turn, grep must specify its return type in order to find sort's
  declaration,

 No, not at all. As I've said, you assume that all methods *can* take
 a block.

Fair enough; that simplifies things somewhat. However, you can't tell how
many arguments they take. How do you parse this without the programmer
specifying a great deal more than they're used to in Perl 5?

  $foo.bar $baz,$qux

Is it

  $foo.bar($baz),$qux

or

  $foo.bar($baz.$qux)

or even a syntax error (though this would require bar()'s declaration to be
known at compile time):

  $foo.bar() $baz,$qux

-- 
Peter Haworth   [EMAIL PROTECTED]
Spider Boardman: I'm having fun with it.
Dan Sugalski: Inside the [perl] tokenizer/lexer? This has got to be the
scariest thing I've heard in a long time. You are a sick, sick man.



Re: right-to-left pipelines

2002-12-10 Thread Peter Haworth
On 10 Dec 2002 17:25:34 +, Simon Cozens wrote:
 [EMAIL PROTECTED] (Peter Haworth) writes:
  Fair enough; that simplifies things somewhat. However, you can't tell
  how many arguments they take. How do you parse this without the
  programmer specifying a great deal more than they're used to in Perl 5?
 
$foo.bar $baz,$qux

 I see no block here. I'm just talking about passing a block to a method.
 You think I'm talking about a clever way of specifying a block's argument
 signature. I'm not.

Actually, I was accepting your point about block arguments not needing
parens, and generalising it to other kinds of arguments.

You want this to work:

  @b = @a.grep { /\S/ };

instead of/as well as this:

  @b = @a.grep( { /\S/ } );

I can agree that it's much cleaner looking. However, I want to be sure that
it doesn't introduce ambiguity. If the programmer wants $c on the end, and
writes this:

  @b = @a.grep { /\S/ }, $c;

how does the compiler know whether $c is an argument to grep, or another
element to be assigned to @b?

Maybe a method can either be called with a parenthesised argument list, no
arguments (without parens), or with a single paren-less block. That also
gets around the chaining issue of:

  @a.grep { /\S/ }.grep { .foo };

If the block is surrounded by implicit parens, that stops it getting
parsed as:

  @a.grep( { /\S/ }.grep( { .foo } ));


Anyway, my point was that methods with paren-less arguments are either
ambiguous or greedy, unless you restrict the types of arguments this
applies to. If it's just blocks, them I'm fine with it.

-- 
Peter Haworth   [EMAIL PROTECTED]
The usability of a computer language is inversely proportional to the
 number of theoretical axes the language designer tries to grind.
-- Larry Wall



Re: Superpositions and laziness

2002-11-13 Thread Peter Haworth
On Tue, 12 Nov 2002 21:11:36 +, Piers Cawley wrote:
 Michael Lazzaro [EMAIL PROTECTED] writes:
  On Friday, November 8, 2002, at 07:03 AM, Adam D. Lopresto wrote:
  I still prefer cached, which sounds less lingo-ish than memoized
  but reads better than same (Same as what?).
 
  Insert obligatory reference to Eiffel here, which IIR uses the word
  once:

But that means once per system, not once per unique argument list.

-- 
Peter Haworth   [EMAIL PROTECTED]
Interesting trivia: If you took all the sand in North Africa and spread
it out... it would cover the Sahara desert.



Re: Continuations

2002-11-12 Thread Peter Haworth
On Wed, 06 Nov 2002 10:38:45 +1100, Damian Conway wrote:
 Luke Palmer wrote:
  I just need a little clarification about yield().
 
 Cyield is exactly like a Creturn, except that when you
 call the subroutine next time, it resumes from after the Cyield.
 
  how do you tell the difference between a
  recursive call and fetching the next element?  How would you maintain
  two iterators into the same array?
 
 The re-entry point isn't stored in the subroutine itself. It's stored
 (indexed by optree node) in the current subroutine call frame. Which,
 of course, is preserved when recursive iterator invocations recursively
 yield.

So to get the same yield context, each call to the coroutine has to be from
the same calling frame. If you want to get several values from the same
coroutine, but from different calling contexts, can you avoid the need to
wrap it in a closure?

  sub iterate(@foo){
yield $_ for @foo;
undef;
  }

  # There's probably some perl5/6 confusion here
  sub consume(@bar){
my $next = sub{ iterate(@bar); };
while $_ = $next() {
  do_stuff($_,$next);
}
  }

  sub do_stuff($val,$next){
...
if $val ~~ something_or_other() {
  my $quux = $next();
  ...
}
  }


-- 
Peter Haworth   [EMAIL PROTECTED]
...I find myself wondering if Larry Ellison and Tim Curry
 were separated at birth...hmm...
-- Tom Good



Re: Perl6 Operator List (REMAINING ISSUES)

2002-11-06 Thread Peter Haworth
[Apologies for late reply, but it takes a long time to read this many
messages]

On Wed, 30 Oct 2002 16:37:09 -0800, Michael Lazzaro wrote:
 1) Need a definitive syntax for hypers,
  ^[op] and «op»
  have been most seriously proposed -- something that
  keeps a bracketed syntax, but solves ambiguity issues.

 2) Possible inclusion of unary prefix ^, meaning complement. (Assuming
doesn't conflict with (1))

If ^ means xor (and complement), then we can't use it for hypering. Consider
this example:

  @a ^[alpha_op] +3

You can parse this in two ways:
 * array a, hyperop alpha_op, unary plus, literal 3
 * array a, binary xor, call alpha_op and put result in arrayref,
   binary plus, literal 3

The operator doing the least at present seems to be ! (my recent attempts to
reclaim it aside). If we keep ^ as the only xor/complement operator, we can
use ! as the hyperoperator indicator without ambiguity:

  @a ![alpha_op] +3

Or (since people seem to like using ^ for hyperness), we could steal ! back
as doing all the xor/complement things that ^ is doing now, and leave ^
doing just hyperstuff. This stops ! being a (mostly) synonym for ^, which I
didn't really like, but does bring back the confusion between !! and ||.

If we want to have a sigil meaning the next set of brackets surround a
hyperoperator, it pretty much can't be the same as any of the other
operators, since that introduces ambiguity all over the place. This is
unfortunate, since perl seems to use every printable ASCII character for
something. Using French quotes gets around this, since they aren't being
used for anything else. OT3H, I can't find the «» keys on my keyboard, but
I'm sure I'm just not looking hard enough.


-- 
Peter Haworth   [EMAIL PROTECTED]
Are you the police?
No ma'am, we're musicians.



Re: [RFC] Perl6 Operator List, Take 5

2002-11-05 Thread Peter Haworth
On Wed, 30 Oct 2002 15:31:24 -0800, Michael Lazzaro wrote:
 Meaning that the list:
 
+^- force to numeric context, complement
~^- force to string context, complement
 
 simply becomes:
 
^ - complement (type-specific)

Does this include booleans? I really liked the idea that not and xor were
just the same operator, but unary/binary. Otherwise, we have ! for boolean
negation only, while ^ does the same thing for other types, as well as xor
for everything. I don't mind leaving ! in as a synonym.


-- 
Peter Haworth   [EMAIL PROTECTED]
Send this via the BT scuz-a-filtron
-- Andy Wardley



Re: Object Instantiation

2002-10-15 Thread Peter Haworth

On Fri, 11 Oct 2002 14:05:30 -0700, Michael Lazzaro wrote:
 Maybe postfix ! on a class name means to autoinstantiate an object of 
 the named class only if/when first accessed:
   
   our FancyCache $cache;  # declare, but leave undef
   our FancyCache! $cache; # undef, but new() it if/when we need 
it
   our $cache returns FancyCache!; # the same
 
 (That's just a joke.  Um, I think.  Hmm...)

Apart from the auto bit of autoinstantiate, that's almost what it means
in Eiffel, except there it's a prefix !! operator. Actually, you can specify
a subclass between the two shrieks, but perl lets you do that by sticking
Class:: on the method name, which means we'd only need one shriek:

  # ! is the new .=
  our FancyCache $cache; # declare but leave undef
  our FancyCache $cache ! new;   # create new instance
  our FancyCache $cache ! ReallyFancyCache::new; # create subclass instance

Eiffel does let you omit the name of the constructor if there is a single
argumentless constructor, but Eiffel constructors are all marked as such,
which (at least so far) Perl6 constructors aren't.

-- 
Peter Haworth   [EMAIL PROTECTED]
The Hotmail migration is becoming the IT equivalent of painting-the-Forth-
 bridge, evidently. Once you've think you've finished migrating one end, more
 FreeBSD boxes reappear at the other. So you have to start all over again.
-- http://www.theregister.co.uk/content/28/23348.html



Re: Private contracts?

2002-10-04 Thread Peter Haworth

On Thu, 3 Oct 2002 18:46:14 -0400, Michael G Schwern wrote:
  method foo($this, $that) is memoized is something
  is pre { $this = 42 }
  is pre { $that == $this / 2 }
  is pre { now we have a little bit more room to play with using
   a differnt indentation style }
  is post { but post conditions are still distanced from the
code which return()s }
  {
  ...
  }
 
 I realize that conditions are technically part of the signature, but putting
 them in there paints us into a stylistic corner.

This is the one nice thing about the Pascal-like syntax of Eiffel. It allows
this situation to be unambiguous and sensibly ordered (as well as giving each
condition labels, so that violations can be better reported):

  foo(this: ThisType, that: ThatType): FooType IS
REQUIRE
  small: this = 42
  half:  that = this / 2
DO
  -- implementation goes here
ENSURE
  fooed_ok: RESULT = baz(this) + that
END

If you're declaring an abstract feature, just replace the whole DO clause with
DEFERRED. Also notice how Eiffel's syntax also somehow makes statement
terminators completely optional. 

Aren't sub declarations in Perl 6 all expressions? Why couldn't we put the
post condition at the end, then?

  sub foo($this, $that) is memoized is something
is pre{ $this = 42 }
is pre{ $that == $this / 2 }
  {
# implementation goes here
  } is post{
# postcondition 1
  } is post{
# postcondition 2
  }

If you want an abstract method, just omit the implementation block.

-- 
Peter Haworth   [EMAIL PROTECTED]
Maybe that's [Java's] niche, its a language for people who like pain.
-- Dean Wilson



Re: Private contracts?

2002-10-04 Thread Peter Haworth

On Thu, 3 Oct 2002 19:16:09 -0400, Michael G Schwern wrote:
 On Thu, Oct 03, 2002 at 04:47:26PM -0500, Garrett Goebel wrote:
  A derived interface can loosen input constraints... so it must be
  able to either satisfy all inherited pre-conditions _or_ its own
  pre-conditions.
 
 Looking around, this seems to be regarded as something of a compromise
 because truly determining what a real logical weaking is is hard.

That *is* a logical weakening. Just because the inherited precondition is
C x  10 , doesn't mean that the weakened condition has to be of the form
C x  9  or any other value lower than 10. C a || b  is weaker than
C a 

  Are there
 other ways to do it, just to mull them over?

-- 
Peter Haworth   [EMAIL PROTECTED]
I remember being impressed with Ada because you could write an infinite
 loop without a faked up condition.  The idea being that in Ada the
 typical infinite loop would be normally be terminated by detonation.
-- Larry Wall



Re: Regex query

2002-09-24 Thread Peter Haworth

On 24 Sep 2002 05:21:37 -0400, Aaron Sherman wrote:
 On Tue, 2002-09-24 at 01:46, Trey Harris wrote:
sub push(@target is rw, *@list);
 
 Well, yes, but that wasn't the point. The C*@list will force array
 flattening, thus
 
   push @a, [1,2,3], 4;
 
 will (according to Larry's stated desire to unify arrays and references
 to arrays in terms of behavior) result in four elements getting pushed
 onto C@a, not two.

But the decision on how arguments get passed happens at compile time, not run
time. At that point we can tell the difference between an explicit arrayref
and a flattened array:

  push @a,1,2,3;   # 1 - list
  push @a,(1,2,3); # 2 - list
  push @a,[1,2,3]; # 3 - scalar
  push @a,@b;  # 4 - list
  push @a,*@b; # 5 - list
  push @a,\@b; # 6 - scalar
  push @a,[@b];# 7 - scalar

1 and 2 are the same; parens in a list don't have any effect, and push
receives three elements in its @list parameter. 3 is an explicit arrayref so
gets passed as a single scalar. This is a simple and obvious distinction for
the programmer to make.

4 and 5 are the same due to the *@ prototype; push receives the contents of
@b in its @list parameter. 6 is an explicit arrayref, so that's what push gets
given. I would argue that 7 is like 6, except that it copies @b's elements.


-- 
Peter Haworth   [EMAIL PROTECTED]
Reporter: Mr Gandhi, what do you think of Western Civilization?
Gandhi: I think it would be a good idea.



Re: Hypotheticals again

2002-09-05 Thread Peter Haworth

On Wed, 4 Sep 2002 17:29:27 -0400 (EDT), Trey Harris wrote:
 In a message dated Wed, 4 Sep 2002, Jonathan Scott Duff writes:
  So, each time I use a hypothetical, I have to be concious of which
  variables are currently in scope?  Perl can't help be with this task
  because how does it know if I meant to hypothetically clobber that
  lexical or store something in the match object.  This is only really a
  problem if you expect let variables to always show up in the match
  object and sometimes they don't.  So why not make it so that let
  also always causes these variables to appear in the match object?
 
 It should.  I think everyone has been proceeding under the assumption that
 they are.  If you use a variable name already defined, then you set both
 the match object's attribute of the same name (minus the sigil if sigil is
 '$') *and* the external variable.

That was certainly my assumption, and I'm fine with that. However, what if,
for some reason, you don't want to set the lexical which happens to be in
scope. Or if you do, but you spell it wrong? There needs to be some way of
indicating whether or not the lexical gets set - that way the strict pragma
(or perl6 equivalent) can catch typos.

-- 
Peter Haworth   [EMAIL PROTECTED]
To be considered half as good as Microsoft,
 Linux has to work twice as fast.
 Fortunately, this is easy.



Re: Hypothetical variables and scope

2002-09-03 Thread Peter Haworth

On Mon, 2 Sep 2002 23:50:18 -0400 (EDT), Trey Harris wrote:
 In a message dated 2 Sep 2002, Aaron Sherman writes:
  {
  my $x = 2;
  my $y = The grass is green;
  $y =~ /(gr\w+) {let $x = $1}/;
  }
 
 Yes.  $0{x} would be set to grass.  A lexical variable has been defined
 in the same scope as the hypothetical with the same name, so its value is
 set hypothetically (is hypothetically bound to?) $0{x}.  When the rule
 succeeds, $x's hypothetical value is made permanent.
 
  module foo;
  rule gr_word { (gr\w+) {let $x = $1} }
  my code
  use foo;
  my $x = 2;
  The grass is green =~ /gr_word/;
 
 No.  $0{x} would be set to grass.  $x would stay as 2.  $x is in a
 different scope from the hypothetical, so it doesn't get touched.

Presumably there is some variant of the strict pragma which would catch
misspellings of $x. Actually, I'd like to see something explicit in the
rule which states whether the hypothetical binding applies to the surrounding
scope as well as to the match variables. Unfortunately, the only way I can
think of doing this is to state $OUTER::x, which is pretty horrible, and
doesn't give the impression that both the external variable and the match
variable are being bound.

Also the different operators used (:= inside the rule, = inside the code)
seems a bit confusing to me; I can't see that they're really doing anything
different:

 / $x := (gr\w+) /vs/ (gr\w+) { let $x = $1 } /

Shouldn't they both use C :=  ?

-- 
Peter Haworth   [EMAIL PROTECTED]
 Some more data?
No, no more. Please, no more...
-- Yanick, examining perl's strange behaviour



Re: Autovivi

2002-08-16 Thread Peter Haworth

On Wed, 14 Aug 2002 15:40:35 -0600 (MDT), Luke Palmer wrote:
 We could make arglists exactly equivilent to the way they're done in Perl 5,
 which is a good way.

   sub foo($a, $b, *@c) {...}

 Would be exactly equivilent to Perl 5's

   sub foo { my ($a, $b, @c) = @_; ... }

 Since variables are copy-on-write, you get the speed of pass-by-reference
 with the mutability of pass-by-value, which is what everyone wants.

No you don't. Since the arguments have to be copied into the local
variables, you get the speed of pass-by-value along with its mutability.
That doesn't sound like what everyone wants to me.

 If you have this, why would you want to do enforced const reference?

Because it's the safest and fastest option. Of course this isn't what
everyone wants, either. However, by making the programmer explictly ask for
the other options (of which there are sevaral), we only give them exactly
what they want. Perl 5 gives you the most flexible way by default (pass by
ref, modifiable), and makes one other option (pass by val, modifiable) easy,
but has occassionally surprising results, such as autovivification.

-- 
Peter Haworth   [EMAIL PROTECTED]
E is for emacs, which rebinds your keys, and
F is for fsck, which rebuilds your trees.
G is for grep, a clever detective, while
H is for halt, which may seem defective.



Re: Continuations for fun and profit

2002-07-09 Thread Peter Haworth

On Mon, 8 Jul 2002 16:54:16 -0400, Dan Sugalski wrote:
 while ($foo) {
   $foo--;
 }
 
 Pretty simple. (For illustrative purposes) To do that with 
 continuations, it'd look like:
 
 $cont = take_continuation();
 if ($foo) {
   $foo--;
   invoke($cont);
 }
 
 When you invoke a continuation you put the call scratchpads and lexical
 scratchpads back to the state they were when you took the continuation.

If you restore the lexicals, how does this ever finish?

-- 
Peter Haworth   [EMAIL PROTECTED]
It's not a can of worms, it's a tank of shai-hulud.
-- Jarkko Hietaniemi



Re: Continuations for fun and profit

2002-07-09 Thread Peter Haworth

On Tue,  9 Jul 2002 16:42:03 +0100, Peter Haworth wrote:
  When you invoke a continuation you put the call scratchpads and lexical
  scratchpads back to the state they were when you took the continuation.
 
 If you restore the lexicals, how does this ever finish?

Never mind. It's the *access* to the lexicals, not their values.

-- 
Peter Haworth   [EMAIL PROTECTED]
Would you like ambiguity or something else?
Press any key to continue or any other key to quit



Re: Apocalypse 4 : The Strange Case of the STRANGE CASE

2002-01-24 Thread Peter Haworth

On Wed, 23 Jan 2002 08:30:41 -0800 (PST), Larry Wall wrote:
 Andy Wardley writes:
 : Same with 'last/NEXT' - they're so similar
 : in concept that the implementation details should not matter.
 
 You mean last/LAST and next/NEXT, I suspect.  But there's another
 argument for case differentiation.  By this argument, the rethink should
 go in the opposite direction, giving us catch/CATCH.

I like that, especially because it makes the try with no CATCH read better:

  try { ... } # But what happens if we fail?

  catch { ... } # Implicit CATCH, now made explicit!

-- 
Peter Haworth   [EMAIL PROTECTED]
Jerry Springer- champion of the American free man or penile freak master?
-- something Ashley Pomeroy read in _the Guardian_



Re: Some Apocalypse 4 exception handling questions.

2002-01-23 Thread Peter Haworth

On Tue, 22 Jan 2002 10:03:08 -0800 (PST), Larry Wall wrote:
 At the moment, I see this:
 
 -2. PRE   in order, inherited, no side effects
 -1. FIRST in order
  0. inline code   normal flow
  1. CATCH, CONTROLsingular
  2. NEXT, LAST, KEEP, UNDOin reverse order
  3. POST  in reverse order, inherited, no side effects

This is all very sensible, and I completely agree with it. However, don't we
need some restrictions on what can go in PRE and POST blocks to ensure that
they are still valid in inherited methods?

  class A;
  sub foo($bar,$baz){
PRE{ $bar10 }
my $qux=$baz;
POST{ $qux==$baz }
  }

  class B is base(A); # I forget the syntax for inheritance
  sub foo($x,$y){
# Insert any old random code here
  }

Presumably, PRE/POST blocks will only be able to access their sub's
arguments, since the derived class' sub may not declare the same variables
as the base class (see $qux above). Or, maybe you just can't inherit from
methods with such conditions, but I think that's putting the restriction in
the wrong place. Or, you only inherit conditions which are inheritable, but
that defeats the whole scheme.

Also, these references have to be compiled into accesses to the argument
list, rather than to the lexicals, otherwise they won't be any use at all to
the derived class. Of course, this might be how references to sub arguments
are compiled anyway, in which case there's no problem.

-- 
Peter Haworth   [EMAIL PROTECTED]
Master, does Emacs have the Buddha nature? the novice asked.
 The Chief Priest had been in the temple for many years and could be
 relied upon to know these things.  He thought for several minutes before
 replying, I don't see why not.  It's got bloody well everything else.



Re: Thoughts on constancy/currying

2001-11-12 Thread Peter Haworth

On Fri, 9 Nov 2001 09:08:04 -0800 (PST), Larry Wall wrote:
 Piers Cawley writes:
 : sub assert_with_func (^sub is constant, $^expected is constant,
 :   $^got, $message)
 : {
 : ^sub($expected, $got) or die $message || $default_message;
 : }
 : 
 : Here's hoping it will work.
 
 That's my intention.

Great, since this is the first rendition of that code which I can actually
understand. However, Piers' typo brings up another question. In the body of
such a sub, is it OK to leave out the carets, like $got and $expected do, or
are they required, like ^sub ?

-- 
Peter Haworth   [EMAIL PROTECTED]
In Cyberspace no one can hear you scream, unless they have a sound card.



Re: McNamara's C$# as a property of any array element

2000-08-25 Thread Peter Haworth

[Apologies for the late reply. Still catching up]

On Thu, 17 Aug 2000 20:51:01 -0500, David L. Nicol said:
  What if its a method of anything in an array?  $_ is already
  a reference to the object on the array in for loops rather
  than a copy of it.  What if we make change be not something about
  for loops, but about anything in an array?
  
   print "The index, in its array, of $_ is $CORE::ARRAY_INDEX{$_}"
  
  where %CORE::ARRAY_INDEX is a very magical system-provided hash that
  tells us the index in its array of something that is in an array.  It
  is often undefined; and would get tricky but definable for objects that
  can be in multiple containers at once, I'd think it would be the index
  of the item in the most recent container it was accessed from.
  
  If we are going to have arrays that can be sparse, we've pretty much got
  to keep track of this info somehow anyway, so might as well give a way
  to access it.

What's wrong with defining each() on arrays?

  while(my($i,$v)=each @array){
print "Element at $i is $v\n";
  }

Then if you have a sparse array, you only get the defined elements, otherwise
you get all of them.

Whether for iterates over the defined elements of a sparse array, or all of
them is another question. If that gets optimized into an iterator, you're
only likely to get the defined elements, because that'll probably use the
same mechanism as each(). I suppose there could be two mechanisms, then
implementors could choose whether to make them do the same or different
things. Otherwise, there should be some way of specifying that you want all
elements (or only defined, whatever the default isn't) when creating an
iterator or using a for loop on an array.

  # This is the easy bit
  my $iter1=$array-iter_all;
  my $iter2=$array-iter_def;
  my $iter3=$array-iter; # Default to iter_def ?

  # This isn't
  for(@$array){} # default iterator
  for($array-iter_all){} # Change for to call iterators?
  for($array-iter_def){}

I suppose this also gives you the choice with each():

  while(my($i,$v)=each @$array){} # Default iterator
  while(my($i,$v)=each $array-iter_all){} # All elements
  while(my($i,$v)=each $array-iter_def){} # Defined elements

This is looking like for/each should act on iterators "natively", and create
an iterator if given a list/hash.