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.


[ANNOUNCE] Test::SerialFork

2005-07-28 Thread Peter Haworth
The uploaded file

Test-SerialFork-0.01.tar.gz

has entered CPAN as

  file: $CPAN/authors/id/P/PM/PMH/Test-SerialFork-0.01.tar.gz
  size: 3891 bytes
   md5: 087b258311b0265ad96946bfd7feb0e9

This module allows you to run the same test multiple times, with
different parameters. The forking isolates the runs from each other,
so that interpreter-wide changes made by one test run don't affect
the others.

This module is somewhat similar to Test::MultiFork, in that the test
process forks a specified number of times, and runs your tests in each
child process. The difference is that SerialFork only does one fork at
a time, where MultiFork does them all at once. It's also much easier
to give descriptive labels with SerialFork, so the output of the test
program is much clearer.

-- 
Peter Haworth   [EMAIL PROTECTED]
perl -Mstrict -we '$_ = goto F.print chop;\n=rekcaH lreP rehtona tsuJ;F1:eval'
-- Abigail


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


PDD15: per-class attribute offsets

2004-03-12 Thread Peter Haworth
I have some issues with the way attributes are referenced. According to the
PDD:

 classoffset Ix, Py, Sz
 
   Returns the offset of the first attribute for class Sz in object Py.
 
 getattribute Px, Py, Iz
 
   Returns attribute Iz of object Py and puts it in Px. Note that the
   attribute number is an absolute offset.

So, compilers are expected to know the relative offsets of attributes within
each class? That's reasonable enough, assuming that attributes are only
directly accessed by code whose objects' classes have been declared.

 addattribute Px, Sy
 
   Add attribute Sy to class Px. This will add the attribute slot to all
   objects of class Px and children of class Px, with a default value of
   Null.

Should we just try to ensure that any class which wants to add attributes
to itself always uses the named version of getattribute? Do we allow code
which modifies other classes' attribute lists? Do we need to mark classes
as numeric/named attribute access, and restrict addattribute's use to
classes which use named attributes?

As well as involving much finding of instances, and moving of their attribute
values, this isn't thread safe (please excuse my lack of PASM syntax
knowledge):

  classoffset Ioff, Pobj, Sclass
  # Some other thread calls addattribute on Pobj's class
  getattribute Pattr,Pobj,Ioff
  # Now we have the value of the wrong attribute in Pattr

-- 
Peter Haworth   [EMAIL PROTECTED]
There is no reason to use multithreading except if you are a marketing guy
 at Sun or Microsoft and your analysis says that it is cheaper to ram
 multithreading down people's throats than to fix the insanely huge process
 creation latency of your broken poor excuse of an operating system.
-- Felix Leitner


Re: Some namespace notes

2004-01-28 Thread Peter Haworth
On Thu, 15 Jan 2004 23:00:53 -0800, Jeff Clites wrote:
 I think we shouldn't try to do any sort of cross-language unification.
 That is, if we some day have a Parrot version of Java, and in Perl6 code I
 want to reference a global created inside of some Java class I've loaded
 in, it would be clearer to just reference this as
 java.lang.String.CASE_INSENSITIVE_ORDER, even inside of Perl6 code--
 rather than having to do something like
 java::lang::String::CASE_INSENSITIVE_ORDER. Parrot itself would be
 completely ignorant of any concept of a separator character--these would
 just be uninterpreted strings, and foo::bar and foo.bar would be
 separate namespaces, whatever the language.

What about languages which have the same separator, such as '::' (perl5,
perl6, ruby) or '.' (java, python)? They are going to be unified either way.

 I think it's confusing to try to unify namespaces across languages, and
 doesn't buy us anything.

Without namespace unification, how else are you going to even specify
File::Spec from java, or java.lang.string from perl5? We can obviously
invent suitable syntax for perl6, so that it can cope with arbitrarily named
packages, but we don't have that luxury with most of the other languages we
want to support.

Then the question becomes, What about namespace clashes?, which Tim has
already addressed.

-- 
Peter Haworth   [EMAIL PROTECTED]
Perl 5's goal was to make easy things easy, and hard things possible.
 We want Perl 6 to make easy things trivial, hard things easy,
 and impossible things merely hard.
-- Damian Conway, _Linux magazine_ 2003-04


Re: Object freezing

2003-10-24 Thread Peter Haworth
On Tue, 21 Oct 2003 13:20:34 -0400 (EDT), Dan Sugalski wrote:
 On Tue, 21 Oct 2003, Jeff Clites wrote:
  2) I don't see it as a huge problem that serialization code could end
  up creating additional objects if called from a destroy() method.
 
 User code may, parrot may not. The reasons are twofold--while parrot will
 let you shoot yourself in the foot, it provides the gun, not the foot.
 It should also be possible for carefully written destroy methods to
 serialize but not eat any headers or memory. (I can see this being the
 case in some embedded applications or systems) If we make it so freezing
 is not a guaranteed possibility at destroy time then this can't happen and
 it lessens the utility of the system some.
 
 We can, if we choose, loosen the restriction later if sufficient reason is
 presented. Can't really tighten it, though, so for now...

-- 
Peter Haworth   [EMAIL PROTECTED]
But do not program in COBOL if you can avoid it.
-- The Tao of Programming


Re: Object freezing

2003-10-24 Thread Peter Haworth
On Tue, 21 Oct 2003 11:39:38 -0400 (EDT), Dan Sugalski wrote:
 On Tue, 21 Oct 2003, Juergen Boemmels wrote:
  This is a question of what is allowed at destruction time. You don't
  want to allow memory allocation, but allow freezing. That gets hard,
  because you need at least allocate the STRING where you want to put your
  frozen stream.

 It's more a question of what we we require the engine to do, vs what user
 code is allowed to do. A user program is allowed to write code that can
 fail at destroy time, however the infrastructure we provide (including, in
 this case, freezing--while I don't like it there's no choice) can't fail
 that way. It's the reason the DOD and GC systems don't allocate memory (or
 didn't--they shouldn't) when they run. The engine's not allowed to have
 failure modes in critical sections.

How can you serialise without using any extra memory? Even if you stream the
serialised data directly to disk one byte at a time (which could fail just
as easily as allocating memory to hold the serialised data in memory),
serialisation of anything more complex than a native type is inherently
recursive. Either you use up call stack space recursing over the PMCs, or
you need an explicitly manage a stack/queue of PMCs not yet serialised.

Have I missed some wonder of modern computing, or just something so obvious
I can't see it?

-- 
Peter Haworth   [EMAIL PROTECTED]
What's so unpleasant about being drunk?
You ask a glass of water.
-- Douglas Adams, HHGTTG


Ignore (was Re: Object freezing)

2003-10-24 Thread Peter Haworth
On Fri, 24 Oct 2003 17:33:17 +0100, Peter Haworth wrote:
 [stuff he didn't mean to send]

Sorry. Looks like I hit Send instead of Cancel.

-- 
Peter Haworth   [EMAIL PROTECTED]
this system is slightly less secure than putting your IP address and 
 root password in big letters in a 30-second Superbowl commercial.
 (Though I may be wrong--it's possible I'm underestimating the danger)
-- Dan Sugalski


RE: [RfC] vtable-dump

2003-09-05 Thread Peter Haworth
On Thu, 4 Sep 2003 09:02:18 -0400 (EDT), Dan Sugalski wrote:
 On Wed, 3 Sep 2003, Gordon Henriksen wrote:
  A seen hash is also threadsafe, can be interrupted by DoD, and is safe
  for recursion. (By threadsafe, I mean that unchanged data structures
  can be safely serialized from multiple threads without ill effect or
  possibility of deadlock.)

 While a seen hash is DOD-interruptable (which, admittedly, the scheme I'm
 preferring isn't, or is with a *lot* of care) it's also slower and
 requires a lot more resources when running.

If you're freezing a large graph of PMCs, that's going to take up a lot of
memory, however you do it (other than streaming to disk). What happens when
you run out, and need to garbage collect? With your scheme, this is a big
problem, since as you say, it's either not possible or needs a lot of care.
Actually, it seems like it would need unfeasible amounts of care to me, such
as recording which PMCs are flagged so the flags can be restored after DOD.
Then where's the benefit over a seen hash?

With the seen hash approach, I wouldn't expect the hash itself to take
nearly as much space as the frozen structure; a GC run in the middle of
freezing should only be a problem if you run out of *unreclaimable* memory.

-- 
Peter Haworth   [EMAIL PROTECTED]
Nothing in the definition of the word `word' says
 that a word has to be in a dictionary to be called one.
-- Anu Garg


Re: [RfC] vtable-dump

2003-09-03 Thread Peter Haworth
On Wed, 3 Sep 2003 09:24:22 +0200, Leopold Toetsch wrote:
 One general traverse() vtable is just the simpler interface IMHO.

 Running through each aggregate just once plus updating a seen_hash seems
 simpler and faster to me and doesn't have any negative impact on PMC size
 and DOD speed.

And also makes it threadsafe? If a shared PMC is frozen simultaneously by
two threads under Dan's scheme, will the right thing happen? I can't help
being worried about interactions between any two operations which use
flags on the PMCs to makr their progress (such as freezing and DOD, or
two freezes).

Bear in mind that I have never used threads and can't remember how they work
in parrot, so this may be an irrelevant question.

-- 
Peter Haworth   [EMAIL PROTECTED]
You're not going to watch the eclipse in yesterday's underpants?


Re: Objects, methods, attributes, properties, and other related frobnitzes

2003-02-19 Thread Peter Haworth
On Fri, 14 Feb 2003 15:56:25 -0500, Dan Sugalski wrote:
 I got clarification. The sequence is:

 1) Search for method of the matching name in inheritance tree
 2) if #1 fails, search for an AUTOLOAD
 3) if #2 fails (or all AUTOLOADs give up) then do MM dispatch

Shouldn't we be traversing the inheritance tree once, doing these three
steps at each node until one works, rather doing each step once for the
whole tree. MM dispatch probably complicates this, though.

If my derived class has an autoloaded method which overrides the base class'
method, I don't want the base class method to be called, just because parrot
does things in a peculiar order. Well, I know it's the same order that perl5
does things, but it's still peculiar.

-- 
Peter Haworth   [EMAIL PROTECTED]
I'm converting my data to 64-bit signed times, stored big-endian in 8 bytes,
followed by 8 bytes for nanoseconds and attoseconds just in case. This won't
last for more than a few hundred billion years, but neither will the Sun, and
in any case I plan to throw a big programming party on 1 January 21
to upgrade to 128 bits.-- Dan J. Bernstein



Re: Objects, finally (try 1)

2003-01-15 Thread Peter Haworth
On Wed, 15 Jan 2003 01:00:59 -0500, Dan Sugalski wrote:
 At 8:53 PM -0800 1/14/03, Adriano wrote:
 I think what Jonathan asked for was an operator for returning a method
 (as an object) which can be invoked later with some arguments (or even
 applied with a partial list of arguments for currying). This would be a
 lot more useful than a yes-or-no answer about the existence of a method.

 I thought about this--it's what the find_method vtable method was for in
 the first place. Unfortunately, as was pointed out to me, there's no good
 way to cache the result, since it could potentially be wrong by the time
 the method is actually called.

Is that such a big deal? The same problem exists in perl 5 with the
following code:

  if(my $meth=$obj-can($action)){
# Stuff could happen here which redefines the method in $obj's class
# However, I know it won't get redefined because I wrote the whole system
$obj-$meth();
  }else{
die Some custom error message or appropriate action;
  }

Surely it's up to the person/compiler writing the code to decide whether it
matters that the method has been redefined in the meantime. We shouldn't
prevent something useful just because it's not universally applicable.

-- 
Peter Haworth   [EMAIL PROTECTED]
I can talk on this stuff for hours when given insufficient discouragement.
-- Dan Sugalski



Re: Objects, finally (try 1)

2003-01-13 Thread Peter Haworth
On Fri, 10 Jan 2003 11:49:14 -0500, Dan Sugalski wrote:
 At 1:37 PM + 1/10/03, Peter Haworth wrote:
 On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
   #10 We do MI, but we don't instantiate a class' attributes multiple
 times if its in the hierarchy for a class more than once. If it is,
 the leftmost instance is real, the rest are virtual
 
 This will mean we can't support Eiffel

 Nope. :)

I realised this soon after leaving for the weekend, thus leaving myself
looking stupid for an extended period of time :-)

 Eiffel's classes, IIRC, are compile-time fixed so it can do the necessary
 code cloning and renaming magic to make it all work.

Exactly. At the implementation level you end up directly inheriting once
from the offending class, and reimplementing some/all of the features for
the repeated inheritance, either directly in the derived class, or in a
specially constructed modified copy of the base class which is only used for
inheritance by the derived class.

I'm not an Eiffel programmer either, but I have read OOSC, so I know enough
to make me dangerous.

-- 
Peter Haworth   [EMAIL PROTECTED]
An IRC channel, in ERROR?!  On Undernet no less?!  THE DEUCE YOU SAY!!
 Next thing you're going to tell me the commentary on Slashdot isn't
 totally impartial!
-- Michael G Schwern



Re: Objects, finally (try 1)

2003-01-10 Thread Peter Haworth
On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
 #10 We do MI, but we don't instantiate a class' attributes multiple
   times if its in the hierarchy for a class more than once. If it is, the
   leftmost instance is real, the rest are virtual

This will mean we can't support Eiffel, which allows repeated real
inheritance of the same class. It does this by allowing renaming at the
feature level (thats attributes and methods in perl) when inheritance is
declared. Repeated inherited features are shared if they keep the same name
(and they really are the same feature), or split if they don't.

-- 
Peter Haworth   [EMAIL PROTECTED]
Warning! Your Operating System is out of date!
It can be replaced by a more memory abusive Operating System.
Please contact your System Vendor for details.



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: String Literals, take 3

2002-12-12 Thread Peter Haworth
On Tue, 10 Dec 2002 16:08:25 -0500, Joseph F. Ryan wrote:
 Peter Haworth wrote:

 On Thu, 05 Dec 2002 15:17:57 -0500, Joseph F. Ryan wrote:
 
 Again, C STRING.split(' ')  is different than
  C STRING.split(/\s+/) . The latter will add an empty element to the
 beginning of the string if there is leading whitespace, which is not the
 behaivor  will have (if it acts like qw(), at any rate.)
 
 I hate this special case. Why is there no way of specifying the removal
 of leading empty elements with any other separator string?

 Given that strings and regular expressions are different types of objects,
 maybe the single whitespace rule could be extended to any single
 character delimeter

That's still an unchangeable special case. In some circumstances, I might
want leading empty fields when I specify space as the separator, and in
others I might want them stripped with any random separator string or
regex. There needs to be a way to explicitly specify whether leading blanks
are required.

-- 
Peter Haworth   [EMAIL PROTECTED]
I think that was lobotomy rather than trepanation wasn't it? Important to
 understand the difference if you're considering trepanning yourself at home
-- Robin Houston



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: String Literals, take 3

2002-12-10 Thread Peter Haworth
On Thu, 05 Dec 2002 15:17:57 -0500, Joseph F. Ryan wrote:
 Again, C STRING.split(' ')  is different than
 C STRING.split(/\s+/) .  The latter will add an empty element to
 the beginning of the string if there is leading whitespace, which is
 not the behaivor  will have (if it acts like qw(), at any rate.)

I hate this special case. Why is there no way of specifying the removal of
leading empty elements with any other separator string?

-- 
Peter Haworth   [EMAIL PROTECTED]
[Microsoft is] a potential threat to our nation's economic well-being.
-- Stanley Sporkin



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: String Literals, take 3

2002-12-05 Thread Peter Haworth
On Thu, 5 Dec 2002 04:05:05 -0500, Tanton Gibbs wrote:
  A string inside a \qq[] construct acts exactly as if it were an
  interpolated string. Note that any end-brackets, ], must be escaped
  within the the \qq[] construct so that the parser can read it correctly.

 Note that an end-bracket, ], must be escaped within the \qq[] construct.
 This allows the parser to correctly parse the construct.

Don't embedded qq[] strings obey the normal qq[] rules? That is, will
all brackets need escaping, or just unbalanced brackets? I'd hope for
the latter.

-- 
Peter Haworth   [EMAIL PROTECTED]
i've just returned after having no internet connection for the past
 48+ hours (my isp had a router go down).
 christ, one more hour and i would've gone sane.
-- alek benedict



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-13 Thread Peter Haworth
On Tue, 12 Nov 2002 14:30:24 +, Peter Haworth wrote:
 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?

I'm an idiot. Why not make the closure a coroutine itself?

  sub consume(@bar){
my $next=sub{ yielf $_ for @bar; return; };
while my $val = $next() {
  do_stuff($val,$next);
}
  }

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

-- 
Peter Haworth   [EMAIL PROTECTED]
The term `Internet' has the meaning given that term in
 section 230(f)(1) of the Communications Act of 1934.
-- H.R. 3028, Trademark Cyberpiracy Prevention Act



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: [netlabs #801] [PATCH] PerlArray in scalar context

2002-09-05 Thread Peter Haworth

On Wed, 4 Sep 2002 22:51:53 -0700 (PDT), Sean O'Rourke wrote:
 On Wed, 4 Sep 2002, Brent Dax wrote:
  Sean O'Rourke:
  # On Wed, 4 Sep 2002, Brent Dax wrote:
  #  What if (say) @b is a two-dimensional array?
  #
  # Then you get interesting values of undef :).  Seriously, I
  # suspect one of the following:
  #
  # 1 - runtime error
  # 2 - each row (or column) of @b numified to its length
  # 3 - the first element of each row/col of @b
  # 4 - the other arrays boosted to the highest dimension
  #
  # I like #2, because it is easy and keeps hyper-operation
  # simple.  If those aren't just numeric operators, but some
 
  It's already been defined to be #4.

Where? I just re-skimmed A3 and E3, but didn't find that. All A3 says is
that scalars get promoted to arrays, which makes sense. Going any further
doesn't necessarily DWIM.

 Argh.  Then I need to whinge a bit -- what if it's a ragged array?  What
 if different elements have different dimensions themselves, e.g.
 [1,[2,3]]?  I think there's serious can-of-worms potential here, and by
 making hyping more intelligent, we'll actually make it useful in fewer
 cases.

I defintely agree. Wouldn't it be simpler to just ignore the
extra-dimensionality? Especially when it's a user defined operator;
it could actually want one scalar and one array operand. Maybe we should
have multiple carets to denote hyper-hyper-operators if that's what the
user wants:

  @a = @b ^^* @c;

If hyperoperators get transformed into loops behind the scenes, this
shouldn't be too hard to implement.

-- 
Peter Haworth   [EMAIL PROTECTED]
Override self destruct? (y/n@^%i@$#
NO CARRIER



Re: [netlabs #801] [PATCH] PerlArray in scalar context

2002-09-04 Thread Peter Haworth

[OSCON has left me way behind in reading my mail, so apologies for the late reply]

On Wed, 14 Aug 2002 16:45:09 -0500 (CDT), David M. Lloyd wrote:
 Here's how I'd expect these expressions to be executed internally, in
 gross pseudocode, ignoring for the moment the multimethod vaporware:
 
 $r = $a + $b; # $a-add($a, $b, $r)
 $r = @a + $b; # $t = @a-get_pmc(@a); $t-add($t, $b, $r)
 $r = $a + @b; # $t = @b-get_pmc(@b); $t-add($a, $t, $r)
 $r = @a + @b; # $t = @a-get_pmc(@a); $u = @b-get_pmc(@b);
   # $t-add($t, $u, $r);

get_pmc() seems a bit vague to me. Shouldn't it be get_scalar(), or even
get_number()?

I've reordered the next bit to make my point more obvious.

 @r = @a ^+ @b;# @a-add(@a, @b, @r), easy

As Sean says in his reply, making the array vtable perform hyper operations
probably means having some code duplication. However, you can get around this
by using a helper function which will do the hyper bits, iterating through a
pair of array PMCs, applying a supplied function (with a supplied default for
the case where one array is exhausted). This means that array vtable functions
would mostly just consist of calls to the helper function. However, see below.
  
 @r = @a ^+ $b;# Does this distribute? If so,
   # @a-add(@a, $b, @r) else see above

It does distribute. However, you can't do the detection of this case entirely
in the vtable, because then C @a ^+ $b  and C @a ^+ @$b  would end up
being indistinguishable (though you probably wouldn't do the first very often
with an arrayref).

Having the iteration done in the bytecode could make this simpler, although
at the expense of needing more bytecode. You can probably have bytecode ops
specifically for hyping operators though, so it might not be too bad. Also,
it means we can use the same mechanism for hyping non-vtable methods.

 @r = $a ^+ @b;# See above

Yes, but I'm not convinced that scalar-type PMCs should be responsible for
detecting array-type PMCs passed as the second operand. Having the bytecode
do the iteration in this case means that the appropriate vtables get used,
and the scalar-type vtable routines don't get complicated with hyperoperator
decisions, which will probably be a minority of cases for the first operand
being a scalar.

 @r = $a ^+ $b;# Something that makes one-elment arrays and
   # uses add method on array object?  Or perhaps
   # error

Bytecode iteration means that this just ends up calling the normal scalar op,
and stuffing the result into an array.


Looks like I'm in favour of bytecode iteration for hyperoperators after all.

-- 
Peter Haworth   [EMAIL PROTECTED]
I is for indent, which rarely amuses, and
J is for join, which nobody uses.
K is for kill, which makes you the boss, while
L is for lex, which is missing from DOS.
-- The ABC's of Unix



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: matrix design

2002-06-21 Thread Peter Haworth

On Thu, 20 Jun 2002 11:11:39 -0600 (MDT), Luke Palmer wrote:
  If the hyperness of a vmethod depends on the type of PMC it belongs to, we
  need to force every operand to a specific type (scalar or list/array), even
  if it looks like it's already the right type:
  
$r = \@a;  # Or is it just $r=@a ?
$r + 3;
 
 What the hell?  I'm confused here.  What are you trying to do?
 
  We don't want to accidentally turn that into a hyperplus on @a's PMC, when
  it should really be a plus on the scalar version of @a.
 
 Which is a reference.  You're adding to a reference?  You can't do that 
 (or does it somehow scalarify to the length or something?).

I was thinking it would be the length. Apocalypse 2 doesn't mention this
explicitly, but mentions that +%hash will return the number of elements. It
should be safe to assume that +@array does the same.

-- 
Peter Haworth   [EMAIL PROTECTED]
If you are going to have delusions, you may as well have really good ones
-- Marcus Cole, B5



A5 implies perl6's real timescale

2002-06-11 Thread Peter Haworth

A5 says this:

 I'm accepting the basic premise of this RFC that the ?...? construct is
 going away, one way or another.

and perlop (from 5.6.1) says this:

 ?PATTERN?
 ...
 This usage is vaguely deprecated, which means it just might possibly
 be removed in some distant future version of Perl, perhaps somewhere
 around the year 2168.

That's a long time for implementation :-)

Well, this is really only a problem for p52p6, I suppose.

-- 
Peter Haworth   [EMAIL PROTECTED]
At IBM, we have no hesitation to steal or borrow other companies'
 technologies ... well, we don't steal of course.
-- Bill Etherington



Re: Non-vtable functionality on PMCs?

2002-05-23 Thread Peter Haworth

On Tue, 21 May 2002 12:18:50 -0400, Dan Sugalski wrote:
 At 8:44 AM -0500 5/20/02, brian wheeler wrote:
 I've been trying to catch up with parrot again (darn it, babies take more
 time than I thought :) and I've come up with a question... how do you do
 other things to PMCs that aren't normal ops?

 Call methods on the perl-level classes that map to the PMCs.

What if the functionality required isn't available through any number
of vtable method calls? Is this what user/language defined ops are for,
or do even more vtable methods have to be defined? If the latter, where
do we stop?

 In particular, I was wondering about shift/unshift, push/pop on the
 PerlArray PMC. Am I missing something obvious?

 Ah, those. In that case you use the vtable methods I've forgotten. :)

Will these all map to a splice vtable method, or will there be a
method for each?

-- 
Peter Haworth   [EMAIL PROTECTED]
I defy you to use the documentation to understand ... the ANSI C++ draft
 standard.  It's not for nothing that comp.lang.std.c++ has a FAQ sixteen
 times the thickness of the Hong Kong phone book.  -- Felix Gallo



Re: parrot rx engine

2002-01-31 Thread Peter Haworth

On Wed, 30 Jan 2002 17:45:58 +, Graham Barr wrote:
 On Wed, Jan 30, 2002 at 09:32:49AM -0800, Brent Dax wrote:
  # rx_setprops P0, i, 2
  # branch $start0
  # $advance:
  # rx_advance P0, $fail
  # $start0:
  # rx_literal P0, a, $advance
  #
  # First, we set the rx engine to case-insensitive. Why is that bad? It's
  # setting a runtime property for what should be compile-time
  # unicode-character-kung-fu. Assuming your CPU knows what the gritty
  # details of unicode in the first place just feels wrong, but I digress.
  
  That i does a once-off case-folding operation on the target string.
  All other input to the engine MUST already be case-folded for speed.
 
 Hm, is that going to work ? What about a rx like /^a(?i:b)C/ where the
 case insensitivity only applies to part of the pattern ?

Or worse, in /^a(b)c/i, where you want to capture the original character,
not the case-folded version?

-- 
Peter Haworth   [EMAIL PROTECTED]
The term `Internet' has the meaning given that term in
 section 230(f)(1) of the Communications Act of 1934.
-- H.R. 3028, Trademark Cyberpiracy Prevention Act



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: Thoughts on constancy/currying

2001-11-08 Thread Peter Haworth

[Apologies if you see this as a duplicate. I sent the original to perl6-all by mistake]

On Thu, 08 Nov 2001 11:10:43 +, Piers Cawley wrote:
 I keep coming back to the ruby/smalltalk
 block approach
 
 assert_with_func := {
 | ^sub is constant, $^expected is constant, $^got, $message |
 ^sub($^expected, $^got, $message);
 };
 
 Note that the suggested syntax is merely a 'port' from Ruby. I've not
 really considered whether this syntax would fit well with perl. The
 first | is reasonably obvious, but I'm not sure we can reliably spot
 the closing one.

I remember fretting about the same thing when I wrote a Smalltalk parser,
and being surprised when it turned out not to be an issue. I think this was
due to the limited kinds of expressions Smalltalk allows, but it was over a
decade ago, and my memory may be faulty.

Anyway, couldn't you say this?

  assert_wth_func :=
sub(^sub is constant, $^expected is constant, $^got, $message){
  ^sub($^expected, $^got, $message);
};

I'm not sure if that still curries appropriately, though.

-- 
Peter Haworth   [EMAIL PROTECTED]
``Sarathy was concerned by the use of a whole bit for this task''
-- Simon Cozens



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.