Fatal/autodie exception hierarchies for Perl 5

2008-06-01 Thread Paul Fenwick

G'day p6l and p5p,

I'm currently working on the 'autodie' pragma for Perl 5, which is 
essentially 'Fatal' but with lexical scope.  It's similar to the 'fatal' 
pragma described in S04/Exceptions.


autodie is implementing an exception hierarchy for in-built functions. 
Essentially we have a tree that looks like:


  :all
  :USER
  :CORE
  :math
  atan2
  :io
  :file
  open
  close
  :filesys
  opendir
  :socket
  accept
  bind
  connect
  ...

Currently, when testing exceptions from autodie, we can use:

given ($@) {
when (undef)   { say "No errors here" }
when ('open')  { say "Open died" }
when (':file') { say "Some sort of file error" }
when (':io')   { say "Some other error" }
when (':CORE') { say "Some other CORE error" }
when (':USER') { say "A non-CORE error" }
when (':all')  { say "Any autodie exception at all." }
default{ say "Not an autodie exception." }
}

There's a 5 minute presentation on what autodie is and how it currently 
works at:


http://pjf.id.au/blog/?position=540

This also looks very similar to what I remember is the desired plan for P6 
exception handling, although my memory may be playing tricks on me as I 
can't seem to find the document where I read this.


So, why does p6l care?  Well, if there's already a p6 exception hierarchy 
designed for built-ins, I'd like to use it.  It saves me work, and saves 
surprises for the developers.  If there isn't a p6 exception hierarchy yet, 
then I'd like for p6 to have the option of stealing mine, for essentially 
the same reasons.


Questions I'm seeking answers to are:

* Is there a document that describes the current p6l exception hierarchy? 
My searching skills seem to be impaired today.


* Does anyone have any input they'd like to make before I start fleshing out 
the hierarchy for p5 autodie?


* Is this an appropriate question for p6l?  While it relates to a p5 pragma, 
I hope to make the behaviour as compatible with p6 as possible.


Many thanks,

Paul

--
Paul Fenwick <[EMAIL PROTECTED]> | http://perltraining.com.au/
Director of Training   | Ph:  +61 3 9354 6001
Perl Training Australia| Fax: +61 3 9354 2681


Re: assignable mutators (S06/Lvalue subroutines)

2008-06-01 Thread Jon Lang
Jon Lang wrote:
> This approach could be functionally equivalent to the "proxy object"
> approach, but with a potentially more user-friendly interface.  That
> is,
>
>  sub foo (*$value) { yadda }
>
> might be shorthand for something like:
>
>  sub foo () is rw {
>return new Proxy:
>  FETCH => method { return .doit() },
>  STORE => method ($val) { .doit($val) },
>  doit => method ($value?) { yadda }
>  }

Correction:

  sub foo (*$value) { yadda }

might be shorthand for something like:

  sub foo () is rw {
return new Proxy:
  FETCH => method { return .() },
  STORE => method ($val) { .($val) },
  postcircumfix:<( )> => method ($value?) { yadda }
  }

i.e., it can be called like a regular function as well as via
assignment semantics.

-- 
Jonathan "Dataweaver" Lang


Re: assignable mutators (S06/Lvalue subroutines)

2008-06-01 Thread Jon Lang
David Green wrote:
> It seems overly complex to me, but perhaps I'm missing good reasons for such
> an approach.  I see lvalue subs mainly as syntactic sugar:
>
>foo(42);  # arg using normal syntax
>foo <== 42;   # arg using feed syntax
>foo = 42; # arg using assignment syntax
>
> Feeds are a way of passing values to a function, but work like assignment
> when used on a variable; assignment is a way of giving a value to a
> variable, so it should work like passing args when used on a function.  Then
> you can easily do whatever you want with it.
>
> In fact, it could work just like a feed, and pass values to the slurpy
> params, but I think assignment is special enough to be worth treating
> separately.  Maybe something like:
>
>sub foo ($arg1, $arg2, [EMAIL PROTECTED], =$x) {...}
>
>foo(6,9) = 42;   # the 42 gets passed to $x
>
> That example uses a leading "=" for the "assigned" param (parallel to the
> leading "*" for the slurpy param), but I'm not crazy about it for various
> reasons (and =$x refers to iteration in other contexts).

OK; my take on it:

An "lvalue sub" is a sub that can be assigned to - the operative word
being "can".  There's a reason why Perl 6 talks about "is rw" and "is
ro" so much, but has yet to (and may never) officially approach the
idea of "is wo".  You don't _have_ to assign to an lvalue sub in order
to use it.  As such, an lvalue sub needs to be written in such a way
that it can be called to assign a value or to return a value.  The
current "proxy object" approach makes this explicit by mandating
separate FETCH and STORE methods to handle the two uses.  This has the
benefit of a fully consistent mechanism for handling "assignable
routines": return an assignable object; if a value was going to be
assigned to the subroutine, it is instead assigned to the returned
object.  Simple, and straightforward.

And sometimes messy.  Let's consider the following alternative,
inspired by David's suggestion:

(I'm thinking aloud here, exploring possibilities and looking for
problems as I go.  Please bear this in mind.)

If a routine is rw, you may optionally define a single "slurpy scalar"
(e.g., '*$value') in its signature.  This scalar counts as the last
positional parameter, much like slurpy arrays and hashes must be
declared after all of the positional parameters have been declared.
You do not need to pass an argument to it; but if you do, you may do
so in one of two ways: through the usual arguments syntax, or via
assignment syntax.

If an assignable routine does not have a slurpy scalar in its
signature, it operates exactly as currently described in S06: it
returns something that is assignable, which in turn is used as the
lvalue of the assignment operator.  If the slurpy scalar is present in
the signature, then an attempt to assign a value to the sub passes the
value in through the slurpy scalar, while an attempt to read the value
that the sub represents doesn't pass anything to the slurpy scalar.
The routine then replaces the normal assignment operation and returns
a value in much the same way that the assignment operator would.

This approach could be functionally equivalent to the "proxy object"
approach, but with a potentially more user-friendly interface.  That
is,

  sub foo (*$value) { yadda }

might be shorthand for something like:

  sub foo () is rw {
return new Proxy:
  FETCH => method { return .doit() },
  STORE => method ($val) { .doit($val) },
  doit => method ($value?) { yadda }
  }

-- 
Jonathan "Dataweaver" Lang


Re: ordinal access to autosorted hashes

2008-06-01 Thread Jon Lang
David Green wrote:
> Jon Lang wrote:
>> Would it be reasonable to allow hashes to use .[] syntax as something
>> of a shortcut for ".iterator in list context", thus allowing
>> autosorted hashes to partake of the same sort of dual cardinal/ordinal
>> lookup capabilities that lists with user-defined array indices have?
>
> I thought it already did, but apparently it's something that we discussed
> that didn't actually make it into S09.  I agree that .[] should apply to
> hashes just as .{} can apply to arrays.  The hashes don't even need to be
> sorted -- %h[$n] would basically be a shorter way of saying
> @(%h.values)[$n], in whatever order .values would give you.

I believe that the order that .values (or is that :v?) would give you
is determined by .iterator - which, if I'm understanding things
correctly, means that any use of :v, or :k, :p, or :kv, for that
matter, would autosort the hash (specifically, its keys).

Or am I reading too much into autosorting?

Bear in mind that keys are not necessarily sortable, let alone
autosorted.  For instance, consider a hash that stores values keyed by
complex numbers: since there's no way to determine .before or .after
when comparing two complex numbers, there's no way to sort them -
which necessarily means that the order of :v is arbitrary, making
%h[0] arbitrary as well.  This is why I was suggesting that it be
limited to autosorted hashes: it's analogous to how @a{'x'} is only
accessible if you've actually defined "keys" (technically,
user-defined indices) for @a.

-- 
Jonathan "Dataweaver" Lang


Re: ordinal access to autosorted hashes

2008-06-01 Thread David Green

On 2008-May-27, at 8:32 pm, Jon Lang wrote:

[...]
Would it be reasonable to allow hashes to use .[] syntax as something
of a shortcut for ".iterator in list context", thus allowing
autosorted hashes to partake of the same sort of dual cardinal/ordinal
lookup capabilities that lists with user-defined array indices have?


I thought it already did, but apparently it's something that we  
discussed that didn't actually make it into S09.  I agree that .[]  
should apply to hashes just as .{} can apply to arrays.  The hashes  
don't even need to be sorted -- %h[$n] would basically be a shorter  
way of saying @(%h.values)[$n], in whatever order .values would give  
you.



Side issue: S09 doesn't specify whether or not you need to explicitly
declare a hash as autosorted.  I'm assuming that the parser is
supposed to figure that out based on whether or not .iterator is ever
used; but it isn't immediately obvious from reading the "Autosorted
hashes" section.  As well, there might be times when explicitly
declaring a hash as autosorted (or not) might be useful for
optimization purposes.


Does the parser need to know?  All hashes have an .iterator method,  
but you can override it to force elements to be returned using some  
particular ordering.


Providing a flag for optimisation sounds useful... although since Perl  
doesn't do any sorting for you, if you want something more optimised  
than making .iterator re-sort the hash every time it's called, you'd  
have to replace the innards of the Hash type yourself anyway.
But if you did make a Hash::Sorted class, defining an "is sorted"  
trait might be a nice way to use it.



-David



Huffman encoding (was Re: treatment of "isa" and inheritance)

2008-06-01 Thread David Green

On 2008-Apr-30, at 1:29 pm, Brandon S. Allbery KF8NH wrote:

On Apr 30, 2008, at 15:14 , Jon Lang wrote:

On a side note, I'd like to make a request of the Perl 6 community
with regard to coding style: could we please have adverbal names that
are, well, adverbs?  "is :strict Dog" brings to my mind the English


-ly suffixes everywhere conflicts with Huffman coding, which per  
@Larry is a primary design concern.  Consider the leading colon to  
be the Perl6 equivalent.


Logically, yes, a ":" on the front of a word is as good an indicator  
of an adverb as an "ly" on the end.  Psychologically, however, it  
isn't; for one thing, my mind doesn't pronounce punctuation the same  
way as letters.  Whatever the reason, I've been reading English for  
decades longer than I have P6 (and by the time I've spent that many  
decades getting familiar with P6, I'll be even more familiar with  
English... which is of course one of the reasons why Perl tries to  
look kinda sorta like English in the first place; it may as well try  
to look like half-decent English!).


But the more general point I wish to make is that extra characters  
don't necessarily conflict with the goal of Huffman encoding.  I  
assume the idea was that extra 'ly's everywhere take up space that  
isn't needed -- of course Huffman himself was concerned with  
minimising bits, but in terms of Perl what we're interested in is  
efficient understanding, not efficient storage.


Now "short code" is not a bad first approximation to "understandable  
code", since longer reading-time will contribute to longer  
understanding-time.  But that's only a very rough rule of thumb: if  
something is too short, it will take even more work to figure out what  
it's saying, and thus any time saved by shortness will be swamped by  
the much greater effort to figure out what the heck it means.


(In this particular example, it seems quite reasonable that the  
cognitive dissonance from seeing an adjective where one's English- 
trained brain is expecting an adverb will outweigh the negligible time  
it takes to scan a couple of extra letters.)


That's why Perl6 has abandoned all the punctuation-variables from P5  
in favour of their "use English" equivalents.  Real words are longer  
to read (and write) but easier to understand overall.


(Of course, more characters are less efficient to type, but except for  
throw-away one-liners, code gets written once and read multiple times,  
so Huffman meta-encoding dictates that we should optimise for  
reading.  And anyway, making code more efficient to write is the job  
of one's text-editor, not the language.  Maybe we should work on auto- 
completion files for popular editors that will expand things like  
":str" into ":strictly", etc.)



-David



Re: assignable mutators (S06/Lvalue subroutines)

2008-06-01 Thread David Green

On 2008-May-27, at 9:40 am, Dave Whipp wrote:

TSa wrote:

  method inch
  {
  yield $inch = $.mm * 25.4;
  self.mm = $inch / 25.4;
  }
Would you regard that as elegant?


That looks functionally incorrect to my eyes: if the caller resumes  
at the time of the "yield" statement, and immediately assigns a new  
value to the "mm" attribute, then there is a race between the two  
updates to "mm".


It seems overly complex to me, but perhaps I'm missing good reasons  
for such an approach.  I see lvalue subs mainly as syntactic sugar:


foo(42);  # arg using normal syntax
foo <== 42;   # arg using feed syntax
foo = 42; # arg using assignment syntax

Feeds are a way of passing values to a function, but work like  
assignment when used on a variable; assignment is a way of giving a  
value to a variable, so it should work like passing args when used on  
a function.  Then you can easily do whatever you want with it.


In fact, it could work just like a feed, and pass values to the slurpy  
params, but I think assignment is special enough to be worth treating  
separately.  Maybe something like:


sub foo ($arg1, $arg2, [EMAIL PROTECTED], =$x) {...}

foo(6,9) = 42;   # the 42 gets passed to $x

That example uses a leading "=" for the "assigned" param (parallel to  
the leading "*" for the slurpy param), but I'm not crazy about it for  
various reasons (and =$x refers to iteration in other contexts).   
Perhaps it could be identified as "$x is assigned" -- but that doesn't  
look quite right to me either.  However it's written, it would be  
simpler than having to use proxies.



-David