Re: [perl6/specs] 89cc32: Spec Bag.kxxv

2014-04-15 Thread David Green
On 2014-April-13, at 11:03 pm, Damian Conway wrote:
  Spec Bag.kxxv
 It's a clever name...but maybe too clever?
 I find it unfortunate that a method that only returns keys has a 'v'in its 
 name.
 Up to now, we've had a more predictable pattern to naming these accessors.

It could be called unpack, because that's what one does to bags. Of course, 
there's already a $str.unpack, which isn't necessarily a problem, but it would 
more justified if there were a common concept that could be fleshed out. 
Different things can get unpacked in different ways, but I'm not sure there's 
enough of an underlying unification to be made.


-David



Floating-point equality (was Re: How to make a new operator.)

2012-03-24 Thread David Green
On 2012-March-23, at 12:01 am, Damian Conway wrote:
 [...] we ought to allow for the inevitable loss of significant digits within 
 the two preliminary division ops, and therefore compare the results with an 
 suitably larger epsilon.
 That would not only be computational more justifiable, I suspect it might 
 also produce more least surprise. ;-)

I think that comparisons for floating-point values should take some kind of 
'significance' adverb and complain if it's missing.  Having to be explicit 
makes for the least surprise of all.

   π == 22/7   # error
   π == 22/7 :within(0.002)# true
   π == 22/7 :within(0.2)  # false

Probably with something like 'use epsilon :within(0.0002)' as way to declare 
the fuzziness for a given scope if you have a lot of comparisons.  And of 
course you could use (the equivalent of) 'use epsilon :within(0)' to say, I 
know what I'm doing, just give me straight what I ask for and I'll take the 
consequences.

Alternatively, maybe have float-comparisons give an error or warning, and 
introduce an approximation operator: π == ~22/7 :within($epsilon).  (Except 
~ is already taken!)


[I was going to suggest that as a way to handle stopping points in a sequence: 
1, 3, 5 ... ~10, but that still wouldn't work without treating the Num::Approx 
values as a special case, which defeats the purpose.  Though with a postfix up 
from operator, you could say: 1, 3, 5 ... 10^.]


-David



Not-so-smart matching (was Re: How to make a new operator.)

2012-03-24 Thread David Green
On 2012-March-21, at 6:38 pm, Daniel Carrera wrote:
 The idea of smart-matching a function just doesn't quite fit with my brain. I 
 can memorize the fact that smart-matching 7 and foo means evaluating foo(7) 
 and seeing if the value is true, but I can't say I understand it.

Maybe it just needs a better name.  Match implies that two (or more) things 
are being compared against each other, and that's how smart-matching started 
out, but it's been generalised beyond that.  The underlying .ACCEPTS method 
suggests acceptance... but that's too broad (a function can accept args 
without returning true).  Agreement fits, in the sense of that [food] agrees 
with me, but I think it suggests equality a bit too strongly.  Accordance?  
Conformance?  Validation?  That seems a good match (ahem) for the concept: 
~~ checks whether some value is valid (or desired?) according to certain 
criteria.  The obvious way to validate some value against a simple string or 
number is to compare them; or against a pattern, to see if the value matches; 
but given a function, you check the value by passing it to the function and 
seeing whether it says yea or nay.  

I'm not sure validation or validity is the best name, but it conforms 
better to what smart-matching does.  Or conformance  Hm.  But 
terminology that sets up the appropriate expectations is a good thing.


-David



Re: pattern alternation (was Re: How are ...)

2010-08-05 Thread David Green
On 2010-08-05, at 8:27 am, Aaron Sherman wrote:
 On Thu, Aug 5, 2010 at 7:55 AM, Carl Mäsak cma...@gmail.com wrote:
 
 I see this particular thinko a lot, though. Maybe some Perl 6 lint tool or 
 another will detect when you have a regex containing ^ at its start, $ at 
 the end, | somewhere in the middle, and no [] to disambiguate.

I think conceptually the beginning and the end of a string feels like a 
bracketing construct (only without symmetrical symbols).  At least that seems 
to be my instinct.  Well, it doesn't in / ^foo | ^bar | ^qux /, but in 
something like /^ foo|bar $/, the context immediately implies a higher 
precedence for ^ and $.  Maybe something like // foo|bar // could work as a 
bracketing version?

 You know, this problem would go away, almost entirely, if we had a :f[ull] 
 adverb for regex matching that imposed ^[...]$ around the entire match. 

I was thinking of that too.

 I suspect :full would almost always be associated with TOP, in fact. Boy am
 I tired of typing ^ and $ in TOP ;-)

Does it make sense for ^[...]$ to be assumed in TOP by default?  (Though not 
necessary if there's a shortcut like //...//.)


-David



Re: How are unrecognized options to built-in pod block types treated?

2010-08-04 Thread David Green
On 2010-08-04, at 7:43 pm, Darren Duncan wrote:
 A parallel solution would be that POD can declare a version, similarly to how 
 Perl code can declare a Perl version, whose spec it is expected to be 
 interpreted according to.

I thought that was more or less how it worked anyway.  You can make Pod do 
anything you want by extending or replacing the grammar (just like [any other 
part of] Perl 6).  So an unrecognized directive should be an error like an 
unrecognized method or rule, but presumably you'd be using whatever modules are 
necessary to recognize them.

On 2010-08-04, at 8:05 pm, Damian Conway wrote:
 I think it's a dreadful prospect to allow people to write documentation that 
 they will have to rewrite when the Pod spec gets updated. Or, alternatively, 
 to require all Pod parsers to be infinitely backwards compatible across all 
 versions. :-(

But nobody will have to rewrite anything, any more than you have to rewrite all 
your old code. Nor create a mega-parser that combines all possible versions.  
Just continue to use the original modules it was designed for, which, with 
proper versioning, will happen automatically.  Isn't handling such versioning 
worries one of the best features of P6? (After all, docs aren't special to Perl 
— it's all just code that it will parse and process any way you tell it to.)

Darren:
 Explicit versioning is your friend.

Yes, always!


-David



Re: Smart match isn't on Bool

2010-08-03 Thread David Green
On 2010-08-02, at 2:35 pm, TSa (Thomas Sandlaß) wrote:
 On Monday, 2. August 2010 20:02:40 Mark J. Reed wrote:
 [...] it's at least surprising.  I'd expect (anything ~~ True) to be 
 synonymous with ?(anything)
 Note also that ($anything ~~ foo()) just throws away $anything.

No; only if foo() returns a Bool.  Do check the section on Smart-Matching in 
S03 and Switch Statements in S04; the specced behaviour isn't just a mistake.  
There are only two cases where ~~ ignores the LHS: one is a block that takes no 
args.  A block that takes one arg runs foo($_) (and of course if it takes more 
args, that's an error), but if the block can't take any args, how would you 
apply $_ anyway?  If you want to compare $_ against its result, then you should 
call the block instead of using the Callable code object directly.

 Could someone please give a rational for the interspersing technique
   given $anything { when $one {...} when two() {...} when $three {...} }
 where two() returning a true value prevents the case $three. 

That's the other case that ignores $_: not merely returning a true value, but 
a Bool (whether that Bool is true or false).  Trying to match a literal True or 
False will warn you, so even if you're surprised by it, you won't be caught 
unaware.  If that's what you really want to do, say ?* or !* (which even 
happens to be shorter than 'True' or 'False'!).

The rationale for ignoring the topic with a non-literal Bool is that when 34 
will tempt people to read that like if 34.  (Human beings don't interpret 
context rigidly enough for the Principle of Least Surprise to be consistent!)  
Saying when /foo/ or when bigger-than(4) obviously call for something to 
compare against, i.e. the topic, but 34 or foo()  $bar *look* like 
complete conditionals.  So people will get it wrong occasionally no matter 
which way it's specced.  

However, it's arguably more useful to accept conditions in 'when' without 
comparing the result to $_ because that is surely the more common case.  If you 
really want something like ?$_ == (foobar) then you can say that — since the 
result of that expression is itself boolean, when ?$_ == (foobar) will do 
the right thing.  (Instead of really doing $_ ~~ (?$_ == (foobar)), which is 
almost definitely the wrong thing!)

On the other hand, if you do want to see whether $_ is true or not, you'll 
probably be using if.  Given/when is particularly useful if you have a long 
list of comparisons, so you don't need to repeat a possibly-long topic every 
time, or even to repeat the $_ ~~ each time.  But with if you only need to 
write the big-long($something.whatever) ~~ once anyway, and the only other 
possibility is simply else.  

Now, this does mean that the special case for Bool is best suited for use with 
'when'.  You're unlikely to expect $foo ~~ (34) to ignore the LHS, I think, 
simply because if that's what you meant, you would just leave off the $foo~~. 
 You can't do that with a 'when', which is what makes it a useful shortcut 
there.  Maybe such a case could raise a warning.  Or why not have the special 
case apply only to when and not to ~~ in general?  

Anyway, given an example like Aaron's:
   if !$dishes-status  $dishes-status ~~ $trash-status {...}
you would use == instead of ~~, and then there's no problem.  Or more likely, 
write !$dishes  !$trash or even none($dishes, $trash).  A warning here 
would certainly help catch cases where you want == or === instead of ~~. 

   given $anything { when $one {...} if two() {...} else { when $three {...} } 
 }
 still smart match $anything with $three? Or is the topic the return value of 
 two() at that point?

No, if two() returns false, then the 'else' is executed with the original 
topic.  (Well, unless two() sneakily changed its parent $_, which, being Perl, 
is possible.)  
Now it seems Rakudo breaks out of the 'else' block when $three is true, but 
then continues with the rest of the 'given' block — I think that's a bug, 
because it ought to break out of the scope that took $_ as a param, i.e. it 
should break directly out of the 'given'.

 I would opt for a regularization of the smart match table. First of all the 
 generic scalar rule should coerce the LHS to the type of the RHS and  then 
 use === on them.

And that's close to what it does, except when the RHS is something 
indeterminate like a regex or a range or a type.  The Any-Any case just does 
$_ === $X, which instead could arguably cast $_ to the type of $X first.  That 
might be quite useful, especially if there's a way to tell 'when' to use 
another operator (like plain ===) when you need it.

Apart from that, the Bool cases have been optimised for ordinary use in typical 
given/when blocks (as opposed to staring at the smart-match table and saying, 
Why isn't it more consistent??).  They are more obviously exceptional used 
directly with ~~, but also less likely to occur (although to some extent this 
does rely on having a habit of using ? or == to 

Re: Smart match isn't on Bool

2010-07-31 Thread David Green
 On 2010-07-30, at 4:57 pm, Aaron Sherman wrote:
 given False { when True { say True } when False { Say False } default { 
 say Dairy } }
 I don't think it's unreasonable to expect the output to be False.
 However, it actually outputs True. Why? Well, because it's in the spec 
 that way. So... why is it in the spec that way?

Well, if you want to do a boolean test, you'd probably use if instead; but 
something that already gives you a Bool, like when time$limit, is likely to 
be the result you want to test itself rather than comparing it against $_ 
(which is likely not to be a Bool).  

So Perl is trying to be helpful by doing something useful instead of making the 
useful thing much harder at the expense of something that isn't useful anyway.  
The catch is that I think that comparing against a boolean IS useful. The fact 
that this question keeps coming up, even on the p6l list, seems to demonstrate 
that the helpful way isn't completely natural or obvious (at least, not to 
everyone).

On 2010-07-31, at 1:33 am, Moritz Lenz wrote:
 sub test() { True };
 given 0 { when test() { say OH NOEZ } }
 I don't think it's unreasonable to expect the output to be OH NOEZ.

It's not unreasonable, especially if that's what you expect.  But it's even 
more reasonable to expect this to work:
given $something { 
when True { say That's the truth! }
when 42 { say Good answer! }
when viaduct { say You guessed the secret word! }
}

In both these examples, the intent is fairly clear from the context.  It's 
easier to forget that Bools behave differently from other types when you only 
have some variable that could be any type:
if $guess ~~ $answer { say Correct! } # hope your question wasn't T/F!

Maybe we can't please everyone, but we can at least try not to displease 
anyone.  Perl is awfully clever at keeping your eaten ponies, and there is a 
way we can have both the helpful syntax and the consistent one:

given $who-knows-what {
when True { say It's a true thing! }
when 42 { say It's numbery! }
whenever timeout() { say Who cares what you say, time's up! }
whenever $override { say Whatever, switching to automatic 
override }
}

This way (or something similar) is just as clear when reading something in 
context, but also makes it clear(er) when the context doesn't help (like 'when 
who-knows()') or when you reasonably expect more consistent matching.  [Or do I 
mean whenever??]


-David



Re: Smart match isn't on Bool

2010-07-31 Thread David Green
On 2010-07-31, at 12:47 pm, Patrick R. Michaud wrote:
 On Sat, Jul 31, 2010 at 10:56:47AM -0600, David Green wrote:
   given $something { 
 when True { say That's the truth! }
 when 42 { say Good answer! }
 when viaduct { say You guessed the secret word! }
   }
 I'm not so sure about this.  There's an argument to be made that the Cwhen 
 42 and Cwhen viaduct cases should never be reachable, since both C42 
 and Cviaduct are considered true values...

Oops, no, I don't want it to do a value-and-type-check.  I guess in this case 
the when True could be moved last, but it's still not a great example.  
Aaron's example with when True as a fallback at the end of a block is better.


 [re Aaron's example with:  if time  $limit { say tick } ]
 The problem with this formulation is that a successful 'when' exits the 
 block, while a successful 'if' does not.  This is one of the significant 
 differences between 'if' and 'when'.

It's possible to break out with an explicit leave or succeed.  Slightly 
less elegant, but still straightforward and it doesn't require any exceptions.  
And it makes the different tests look different.


Meanwhile, from one of your earlier replies:
 The problem is that there are at least two interpretations of a true result 
 of expr:
when True { ... }# execute when $_ is exactly True
when foo() { ... }   # execute when foo() returns true

Except that the latter 'when' isn't executed when foo() returns true; only when 
it returns True!  Well, maybe by true you meant Bool::True -- after all, 
that's a comment, not code; or maybe you were even thinking True and the 
lowercase T was a typo.  At any rate, it confused me for several moments.


-David



Re: Smart match isn't on Bool

2010-07-31 Thread David Green
On 2010-07-31, at 11:38 am, Brandon S Allbery KF8NH wrote:
 Thank you; *that* is the real point I was trying to make.  That, and that 
 special-casing one particular type is *not* actually helpful; it means I must 
 remember a special case, when one of the goals of Perl 6 was supposedly to 
 eliminate all the special cases in Perl 5, helpful or no.

I don't know if it was supposed to eliminate *all* special cases, but I'm happy 
that it eliminates lots of them.  I think some exceptions can be justified if 
it's a way humans naturally think (though it may be exceptional to a 
machine), or if there is some construct that isn't useful at all (if it has no 
legitimate use, why not use that syntax to mean something else? — but in that 
case, the trade-off is remembering an exception [of something you'd never want 
to do anyway] versus remembering extra syntax to do the other thing).  

I'm even prepared to accept exceptions for something that isn't meaningless.  
(My no-exception rule has exceptions!)  0 but true in P5 is a good example.  
The exception is that it suppresses a warning, and that warning isn't totally 
useless; there *could* be a situation where you accidentally get that exact 
string when you wanted a pure number, but it's unlikely *and* the warning 
doesn't actually do anything — the code works the same way with or without the 
warning.

$foo ~~ True is different.  It may be less useful than the exception in that 
it's less frequent; but it still has a legitimate (non-exceptional) meaning.  A 
bear of little memory like me will see when timeout() but instead of 
internalising P6 handles when $bool differently from when $anything-else, I 
will take away Perl DWIM.  And then I'll expect it to DWIM in 
$true-false-queston ~~ $bool-answer.


-David



Re: Smart match isn't on Bool

2010-07-31 Thread David Green
On 2010-07-31, at 5:55 pm, Darren Duncan wrote:
 I would prefer if given/when was nothing more than an alternate syntax for 
 if/then that does comparisons. 

And that breaks out of its enclosing scope.

 On the other hand, Perl 6 has multiple equality comparison operators, eqv, 
 eq, ==, ===, etc, and hence ~~ semantics instead of eqv may seem to make some 
 sense, though I think that would cause more problems.

Yes, since if you've got a whole list of when's to compare against, it's not 
unlikely that they're different types of things, so ~~ would be more useful 
than === or eqv.  Of course, given the bool-exception spec, one workaround is 
when $_ eqv $x.  But I was already thinking of a more elegant possibility.

Using when ~~ $bar is problematic because Perl couldn't know whether to 
expect a term or an operator after when.  But what if ~~ were merely the 
default operator, and you could override it?

given $foo :using( [===] ) { ... }
given $foo :using(binary-func) { ... }

such that any 'when's inside the block use ===, or the provided 
operator/function instead, of ~~.  Actually, the option should be on 'when', so 
that above line would mean something like:

given $foo { my when = when.assuming( :using( [===] )) ... }

...er, except 'when' isn't a function, so that doesn't actually work.  Anyway, 
the idea is that there could be some way to set the default operation to use 
for 'when' in a given scope.  


Here's another thought: 'when' is different from 'if' in two ways.  One is that 
it does an implicit comparison on the topic; the other is that it breaks out of 
its enclosing block.  Maybe the comparison could be indicated another way, 
leaving 'when' and 'if' to differ in breaking out or not.  Suppose a colon 
indicated compare against $_ using ~~, or whatever the default operation is 
(we're not using the colon for anything else, are we?!?):

when $a  $b { ... }
if $foo.does($bar) { ... }

when: /foo/ { ... }
if: .defined { ... }


-David



Re: Smart match isn't on Bool

2010-07-31 Thread David Green
On 2010-07-31, at 2:00 pm, TSa (Thomas Sandlaß) wrote:
 On Saturday, 31. July 2010 18:56:47 David Green wrote:
   given $who-knows-what {
 when True { say It's a true thing! }
#  ^--oops, this still shouldn't come first!
 when 42 { say It's numbery! }
 whenever timeout() { say Who cares what you say, time's up! }
 whenever $override { say Whatever, switching to automatic override }
   }
 
 Am I getting your intention to be that when honors the given and whenever 
 just checks truth? Couldn't we use if for this? That would avoid the new 
 keyword.

Right; except that whenever still breaks out, unlike if.  I like having a 
new keyword because it makes it perfectly clear that whenever $foo does not 
mean the same thing as when $foo (though it suggests something related by 
having when in the name).  

However, as suggested in my previous message, we could also distinguish them 
with something like when vs. when:.  The colon there isn't quite a new 
keyword, but it still is something to make the distinction visible.  Plus it 
allows us to extend the same useful behaviour to if vs if:.


-David



Unwanted warnings (was Re: Something wrong with str.reverse)

2010-07-31 Thread David Green
On 2010-06-18, at 10:48 am, Larry Wall wrote:
 If you make it the default to not warn, then the people who really need the 
 warnings will almost never turn them on.  If you make it default to warn, 
 then people will have to turn off the warnings forever.

Doesn't the site-policy policy help here?  I could turn certain warnings off in 
my policy file instead of having to turn them off in every new program.  Of 
course, such settings should arguably apply per-project or 
per-person-who-wrote-the-code; so maybe any file should adopt settings from a 
.policy.pm in its own dir, if there is one.  Actually, no, it should probably 
use Some::Policy, but there should be a way for a policy module to identify 
itself as such so Perl knows whether it should override or be overridden by 
other policy modules.

Also, certain warnings could be suppressed if the code is compiled, on the 
grounds that compiling the code is a way of saying, I'm finished with this, it 
all works and I don't expect to be changing it any more.  Library modules will 
presumably be compiled, so that would prevent warnings from code you didn't 
even write.  (Although if a module you installed from somewhere else is full of 
warnings, maybe you do want to know, hm)


0123;  # warns
0123; # ok!# suppresses this warning here
0123; # OK!# suppresses this warning from now on
 
 Though I'm hesitant to use comment syntax for that.  A statement prefix might 
 be more appropriate.  We've currently reserved quietly for simple run-time 
 warning suppression, but that's kinda long, and not defined for compile-time 
 warnings yet.  Admittedly, it would be rather amusing to have to shout at 
 Perl 6 to make it shut up:
 my $x = QUIETLY 0123;


Call it sh?  (for suppression handler, of course)

Using comments doesn't feel quite right to me either, but on the other hand, 
almost anything else seems distracting for something that is supposed to avoid 
drawing attention.  Maybe a statement suffix?  


-David



Re: series operator issues

2010-07-31 Thread David Green
On 2010-07-23, at 4:25 am, Moritz Lenz wrote:
 I'm still not convinced.  [that there should be a special index variable]
 Yes, it would be convient, but I've yet to see a non-contrived example where 
 it's actually necessary, and which can't be implemented trivially with other 
 Perl 6 tools.

I see it like the situation with self.  Sure, it's not necessary, it's easy 
to specify it explicitly, and so on, but nevertheless it feels somehow too 
heavy not to deserve some sugar.  My own first instinct was to use map or a 
loop to produce those a series of squares or factorials or whatever... on the 
other hand, the series operator does naturally come to mind when you're 
thinking about a series!

 The series code is already rather complex (and thus slow), and having to add 
 introspection to find out whether the production code object accepts a named 
 parameter 'i' is not going to help in any way.

I do agree that having a special named parameter isn't the way to do it, 
though.  What if there were a special keyword instead? (Again, like the 
situation with 'self'.)  If you used the word index (or counter or n?) in 
a loop or series or anywhere else suitable, it could be detected at 
compile-time.  It shouldn't be any worse than making your own counter, and 
might even be better (since Perl needs its own counter for some loops, maybe it 
could make it available rather than having to define one of your own as well).


-David

Re: Command-line args (weekly contribution to P6)

2010-05-27 Thread David Green
On 2010-05-26, at 8:52 am, Larry Wall wrote:
 On Wed, May 26, 2010 at 07:22:36AM -0700, jerry gay wrote:
 : On Wed, May 26, 2010 at 00:53, Moritz Lenz mor...@faui2k3.org wrote:
 :  sub MAIN(:name(:$n))
 :  then $n has two names, 'name' and 'n', and we could consider all 
 one-letter
 :  parameter names as short names

Presumably you could have :n($name) or :name($n), depending on whether you 
wanted to use the shorter name in your code, and either way, consider 
one-letter names as short.


 Also, it's a bit antisocial to get people used to using certain short 
 switches and then cancel them out when they get ambiguous. 

I feel that may also apply to having -abc be able to mean -a -b -c or -a=bc.  
The spec doesn't give a rule, but I'd say combining short switches is the 
handier shortcut, and just require the = to set a value.  (And again, if you 
need to, you can always parse the params yourself.)

That does raise a question of what to do about -vvv.  Repeating a switch as a 
kind of incrementing is a venerable tradition, but it doesn't really get us 
anything more than -v=3.  Also, I assume that when repeating a long name, the 
last use overwrites any previous uses, so to be consistent, -vvv would mean -v 
-v -v which would mean simply -v.  In which case, is it worth giving a warning 
to that effect, in case the user was expecting it to mean -v=3?


Another detail: the spec mentions exact Perl 6 forms like :namevalue or 
:name(value); I don't see any particular reason not to allow --namevalue or 
--name(value) as well.  (And it's one less arbitrary difference between --name 
and :name.)


Also, setting any value that contains a comma will get it split.  If you don't 
want a list, you'd have to join the pieces back together (or don't use the 
default parsing), which seems reasonable to me.  However, the splitting could 
also be limited to params that were declared as arrays.


Finally, the spec mentions the usual practice of ending named params at the 
first positional arg.  Of course, some commands continue to process named 
params either way.  For programs like Perl itself, e.g. perl --args --for 
--perl some-script.pl --args --for --script, continuing past the positional 
arg would not do the right thing.  But is this common enough to be the default? 
 You can always use -- to force positional treatment, but not the other way 
around. 


-David



eqv and comparing buts

2010-05-26 Thread David Green
On 2010-05-26, at 1:53 am, Moritz Lenz wrote:
 The tests might need fixing too, since I'm not sure whether eqv (as used by 
 is_deeply) would cover that, or whether it would take a separate test in 
 bool context.
 
 probably the latter.

I guess it would have to -- that is, but creates an ad-hoc new class, so even 
if you take two identical objects and but them the same way, there's probably 
no good way that eqv can tell they are the same.  At best, it could know that 
one or both of its operands had been tampered with, and report false.

(If you wanted to manipulate two or more objects the same way, then you'd have 
to make a new class with the appropriate overloaded methods and then eqv could 
compare my NumButFalse $n1 to my NumButFalse $n2.)

In order to compare two objects that were created and modified on the fly, you 
could see what roles/methods they actually have, and compare the values in 
whatever way is suitable.  I guess you could see whether an object has extra 
roles with something like:
all($x.roles) === all ($x.WHAT.roles)


Still, it's important to be able to tell whether two things can be expected to 
work the same way, so perhaps there can be an adverb for eqv that says to pay 
attention to ad-hoc changes (or vice versa).  Since 'but' is special syntax, 
maybe there's even a way to compare snapshots of all the types that were 
'but'ed in to the base type, but I don't know how feasible that is.


-David



Re: [perl #72972] [BUG] False ~~ True in Rakudo

2010-02-22 Thread David Green

On 2010-Feb-22, at 2:08 am, Moritz Lenz wrote:
At least I'd find it more intuitive if smart-matching against Bool  
would coerce the the LHS to Bool and then do a comparison, much like  
smart-matching against strings and numbers work.


The downside is that then: given $thing { when some_function($_)  
{...} }
won't work as intuitively expected if $thing is false and  
some_function

returns True.



The problem is the same construct is trying to do two different  
things.  I agree that Any ~~ Bool should compare both sides as bool,  
because that's more consistent, and there should be another way to  
ignore the LHS.


I propose whenever: it suggests that any time whatsoever that the  
RHS is true, the block will be executed.  It's like when, because it  
is related, but it also has the hand-waving, dismissive feeling of  
whatever, as in, Given $foo?  Whatever!!  I'm ignoring that and  
looking only at this particular value now!



  say Q: $question (Y/N)?;
  my Bool $answer = %answers{$question};
  my Bool $guess = get-response;

  given $guess
  {
  whenever now()  $limit  { say Time's up! }
  when $answer  { say That is correct! }
  default  { say Sorry, wrong answer }
  }



-David



Re: But vs. With

2009-12-04 Thread David Green

On 2009-Dec-3, at 8:42 pm, Jon Lang wrote:
but _can_ change existing behavior, but doesn't have to.  So  
with becomes the safe version of run-time composition,  
guaranteeing that whatever you mix in won't disturb existing  
behavior, and but becomes the unsafe version that you can fall  
back on when you need to change said behavior.
[...] I suppose you could allow for both, with the default being  
fail on conflict and an adverb being available to force it to  
quietly resolve the dispute.


Yes; I guess but could have an adverb to control its strictness too,  
come to that.  But not requiring but to change behaviour seems  
reasonable -- I would read it as but make sure that X, where you  
want to draw attention to X even though it might technically be  
redundant.



-David



But vs. With

2009-12-03 Thread David Green
I'm wondering whether we can make use of the contrary sense implied by  
the word but, and have it apply specifically to cases where  
something is being overridden.  In cases where there isn't something  
to override we could use a different word, such as with.


E.g.
 $x = Tue but Today;
replaces the normal or default Str value of Day::Tue with Today.

However,
 $x = Today with Day::Tue;
mixes in a new Day method where none existed before.

Saying: Tue with Today, or Today but Tue, could warn you that your  
expectations are back to front.  As well, by allowing the meanings to  
be closer to the English use of but or with, the code can better  
suggest its intent.



Actually, I'm not sure where is the most practical place to draw the  
line.  Lots of things will have default stringifications, say, that  
may not always merit the contrary force of but.  Maybe but should  
be needed only when a method has already been mixed in anonymously.   
So: $x = Tue with Today; $y = $x but Tomorrow.




-David




Re: But vs. With

2009-12-03 Thread David Green
Lots of things will have default stringifications, say, that may not  
always merit the contrary force of but.  Maybe but should be  
needed only when a method has already been mixed in anonymously.


Oops, that would wreck the canonical example of 0 but true. Since  
the Bool(Int) method already exists, but is indeed the appropriate  
choice to override it.



-David



Re: new enumerations

2009-11-29 Thread David Green

On 2009-Nov-28, at 1:56 pm, pugs-comm...@feather.perl6.nl wrote:

+Fri.name# 'Fri'


Since enums are like hashes, why not .key instead of .name?  (Also  
might be less confusing should you happen to have an enum where the  
keys are numbers and the values are names.  (Of course, enum  
Key(hopeful=A, wild=B, gay=C, triumphal=D,  
boisterous=E, peaceful=F, serious=G) will be confusing no  
matter what.))




+3 ~~ Day# True, using Day as a subset of Int


Should enums be subsets or subtypes?  A subset is a shorthand for  
certain members of a class, but an enum seems like a way to represent  
a different kind of thing.  Weekdays aren't particular ints the way  
natural numbers are, and it seems useful to be able to tell that  
$foo is a Day and not a Month or a Colour.


3 == any(Day.mapping.values) would work if you really want to go by  
values (a bit more verbose, but the actual values are a kind of  
implementation detail that the user shouldn't be concerned with most  
of the time anyway).  Or defined Day(3).


(At first I wrote ?Day(3), but that wouldn't work if there was value  
that was false.  On the other hand, shouldn't enums typically be  
true?  Does it fit the common case better for enums to start at 1  
instead of 0, or maybe start at 0 but true?)



-David



Re: unusual invocants

2009-10-20 Thread David Green

On 2009-Oct-20, at 7:55 am, Matthew Walton wrote:
On Tue, Oct 20, 2009 at 2:32 PM, Mark J. Reed markjr...@gmail.com  
wrote:
On Mon, Oct 19, 2009 at 11:47 PM, Jon Lang datawea...@gmail.com  
wrote:

Because a method is part of a role, and ought to abide by the same
terms by which the role abides.  If Logging doesn't do Numeric, it
shouldn't have any methods in it that won't work unless it does.


100% agreed.

So what the OP wants to do is declare a method that is available on  
all those invocants - and only those invocatnts - which do all of  
roles X, Y, and Z.  Granted, you can declare a new role XandYandZ  
that does X, Y, and Z, and define the method there, but that won't  
work on $foo unless you declare explicitly  '$foo does  
XandYandZ' .  The goal is to have the method show up no matter how  
$foo comes to do all three roles.


Right.

This is an interesting idea.  Currently, it doesn't work because  
there's no place for such a method to live, so perhaps there could  
be a way to declare a method space for arbitrary combinations of  
roles, a sort of meta-role.  It's an odd duck, but it does sort of  
fall out of the multiple-dispatch semantics, which already let you  
base implementation chioce on arbitrary combinations of roles...


Yes, and while the answer could always be don't do that, the concept  
doesn't seem particularly strange or undesirable.  Maybe rather than  
hide a Numeric method inside a Logging role where people wouldn't  
expect to find it, we could do it this way:


role Numeric Logging { method log {...} }

or something alone those lines.

Well, if you could put a where clause on your invocant you could do  
that...
method m($invocant where { $_ ~~ X and $_ ~~ Y and $_ ~~ Z }:  
Int $a, Int $b) { ... }



I would expect $foo where {$_ ~~ X} and X $foo simply to be  
different ways of writing the same thing, but whatever works!



-David



Re: lvalue methods

2009-10-20 Thread David Green

On 2009-Oct-20, at 8:04 am, Jon Lang wrote:
The above example is of course trivial.  A more serious example  
might be one based off of a coordinate system:


   role point {
   has Num $x, Num $y;
   method angle() is rw( { $.x = .r * cos($_); $.y = .r *  
sin($_) } ) { return atn($.y/$.x) }
   method r() is rw( { $.x = $_ * cos(.angle); $.y = $_ *  
sin(.angle) } ) { return sqrt($.x * $.x + $.y * $.y ) }

   }

This strikes me as being much more readable than the current  
approach of explicitly returning a proxy object.  I'd even be fine  
if the above were treated as syntactic sugar for the creation of a  
proxy object -


And/or some sugar for using special STORE methods on a variable, e.g.:

has $angle is set { $.x = .r * cos($_); $.y = .r * sin($_) };

(Well, in this example that makes extra storage space for the $angle  
attribute which we don't actually want, but there are many cases where  
an easy way to override STORE is really what is useful rather than an  
lvalue sub.)


But one of the problems with lvalue subs that don't simply return a  
variable (or equivalently, my is set example) is that you can't say  
things like temp lvalue() unless temp is receiving an actual  
variable to work on.


In the case where angle() (or $.angle) is changing $.x and $.y, should  
trying to temporize it do temp $.x and temp $.y as well?  Should  
it be impossible?  Can Perl tell whether it should be impossible or  
not?  Does it need to be illegal to change other variables inside a  
STORE?



Meanwhile, the flip side to wanting an easy way to do is set is that  
often when someone reaches for an lvalue sub, all he really wants is a  
way to pass an arg to the sub that looks like assignment.  For example  
wanting foo($x) = $y to be a prettier way to write foo($x, $y).   
This could be handled by, say, having a special rvalue keyword in  
signatures, e.g.:


sub foo($x, rvalue $y?) { ... }

foo(42); # $y is undef
foo(42) = 24;# $y is 24
foo(42, 24); # syntax error

This has the advantage of often doing what people want, and the  
disadvantage of not working with temp, etc.  At least Perl could  
know that temp isn't allowed to work with such subs, though.  On the  
other hand, something that looks like an assignment ought to work like  
an assignment, including temp


Especially since if you want something that looks more assignment-y  
than passing a regular arg, we already have a way to do that, namely,  
using the == syntax to feed args into a slurpy parameter.  But in  
your angle example, we really do want an assignment because the net  
result is to assign stuff.  Perhaps method angle is setting ($.x,  
$.y) ... to indicate that whatever is done to angle should really  
affect $x and $y, and any other attributes that aren't specified may  
not be used.



-David



Re: Aliasing methods in CPAN roles

2009-10-19 Thread David Green

On 2009-Oct-18, at 3:44 pm, Jon Lang wrote:

David Green wrote:

I would expect that   role Logging { method log(Numeric $x:) {...} }
means the invocant is really of type Numeric  Logging, without  
Logging having to do Numeric.  On the other hand, I can see that  
strictly that might not make sense, so perhaps I really do need to  
create a compound NumLog type first, so I can have method  
log(NumLog:)?

I think you should need to do this.


That's cumbersome, though.  I don't want to create some new type, that  
happens to do Numeric and Logging (in addition to other stuff it might  
do); I want to affect everything else that does both roles.  That is,  
I don't want my special log() method to work only for other types that  
explicitly do NumLog; I want it to work for any type that directly  
does Numeric does Logging.


In fact, I can already refer to that combination without needing to  
create a compound type; for example, in a signature I can say  
(Numeric Logging $x:).  I want my log() method to apply to $x there,  
even though it's Numeric Logging and not NumLog.


I don't like dangling methods outside of any role though, either.   
What I want to be able to do is say:

role Logging { method log(Numeric $x:) {...} }

and have it treat the invocant as something that does Logging  
(naturally, since it's part of the Logging role), and that also does  
Numeric (as specified in the sig).  It's too reasonable a thing to do  
not to have a reasonable way to express it.


Of course, I could do something like this:
role Logging
{
method log
{
given self
{
when Numeric {...}
when Stringy {...}
etc.
}
}
}

that is, I can do the dispatching myself.  But I shouldn't have to,  
especially in cases that are more complex than this simple example.



(But I'll suggest something new for - in general: what if $x -  
Numeric with no $n variable were shorthand for $x - Numeric $x  
is rw, i.e. a shorthand that used the same variable name inside  
the block as the one being passed in?  That would be useful in  
cases like this where we don't particularly want to rename $x.)


It wouldn't always be workable; for instance, @a - Numeric,  
Stringy { ... } would grab the first two element of @a and would put  
them into parameters; but there would be no obvious names to assign  
to those

parameters.


Yes, and I think it's OK for a shortcut like that to be available only  
in simple cases.



-David



Re: unusual invocants

2009-10-19 Thread David Green

On 2009-Oct-19, at 5:50 pm, Jon Lang wrote:

In Aiasing methods in CPAN roles, David Green wrote:
I don't want my special log() method to work only for other types  
that explicitly do NumLog; I want it to work for any type that  
directly does Numeric does Logging.


But if Logging doesn't do Numeric, why should it be expected to
provide a method that assumes that it does?


Well, I don't want all objects that do Logging to do Numeric; I just  
want to have custom methods for those that do happen to do both.


I could declare a sub log(Numeric Logging $x) that would work when its  
arg does both, but it has to be called like a sub, not a method.


If I can put ad hoc compound types into a signature, e.g. foo(Numeric  
Logging) instead of foo(NumLog), then why shouldn't it be possible to  
define a method that way?  Or conversely, should compound types in  
signatures be disallowed, and forced to use NumLog/whatever also?



-David



Re: Aliasing methods in CPAN roles

2009-10-18 Thread David Green

On 2009-Oct-17, at 1:55 am, Jon Lang wrote:
This implies that both Logging and Math do Numeric, since the  
invocant ought to be of a type that the class does.


I would expect that
role Logging { method log(Numeric $x:) {...} }
means the invocant is really of type Numeric  Logging, without  
Logging having to do Numeric.  On the other hand, I can see that  
strictly that might not make sense, so perhaps I really do need to  
create a compound NumLog type first, so I can have method log(NumLog:)?


Or can I create a method outside of any role:
role Numeric {...}
role Logging {...}
method log(Numeric Logging $x:) {...}

(of course, that might be implicitly creating an anonymous compound  
type for me...)



I think that what you're actually looking for (for the purpose of  
illustration) is Logging::log:(Numeric $x:) and Numeric::log: 
(Numeric $x:).


Oh, yes!

If $x does Numeric and $x does Logging, then it has a class that has  
already encountered the potential conflict and resolved it in some  
way.  For example:


   class Baz does Numeric does Logging {
   method log(Numeric $x:) {$x.Numeric::log;}
   method log(Logging $x:) {$x.Logging::log;}
   } #`Baz postpones the decision until it knows which role it's  
being asked to play: Numeric or Logging.


Baz illustrates my proposal: if $x is a Baz, it will need to check  
the context to see if it's supposed to be acting like a Numeric or  
like a Logging, and will act accordingly - or it will complain about  
ambiguity if it can't figure out which role to play.  And the  
definition for Baz works because Logging does Numeric.


I suppose given that I want Logging's method log(Numeric Logging:)  
rather than its log(Any Logging:), the second method there should  
really be:

method log(Numeric Logging $x:) {$x.Logging::log;}

You cannot define a class that does Logging and does Numeric without  
defining at least one log method, because they conflict; and a class  
must somehow resolve all such conflicts.


OK; although it seems reasonable to have some sugar for the obvious  
kind of keep them all methods like in this example.  In fact, we  
probably have that already, by declaring a proto log that makes the  
others all work according to their sigs.  And my mistake was thinking  
that you could have the same sig doing different things, but really  
the second sig is log(Numeric Logging:).


(The only way to have the same sig twice would be something like if  
Logging defined a special version of log() for Numeric objects, while  
Numeric defined a special log() for Logging objects -- but  
semantically that ought to mean the same thing in both cases, so we do  
want a single method to handle that.)


In the Baz case, it addresses the matter by making two options  
available according to the role being played: Numeric or Logging.   
All you have to do then is to somehow indicate which role is being  
played.


If you can't tell by the routine's signature, my own preference  
would be to make it explicit by means of a given block:


   given Logging $x { .log } # logs like a Logging
   given Numeric $x { .log } # logs like a Numeric


I also thought given sounded good for this, but it would have to  
work differently from a normal given: if $x doesn't do Logging, then  
it needs to skip the block.  (Also, it looks very close to casting:  
given Logging($x).  Maybe something a bit more visually distinctive  
would be helpful, something like given $x as Logging, etc.?)



But I could see other alternatives:
   .log given Logging $x; # assumes the inclusion of a given  
statement modifier.


I think given, as either a modifier or a block, is the prettiest  
syntax.



   $x - Numeric $n { ... ; $n.log ; ... }


What I like about this is using a sig to apply the context, so no new  
syntax is needed.


(But I'll suggest something new for - in general: what if $x -  
Numeric with no $n variable were shorthand for $x - Numeric $x is  
rw, i.e. a shorthand that used the same variable name inside the  
block as the one being passed in?  That would be useful in cases like  
this where we don't particularly want to rename $x.)



   $x.log:(Logging:);



And I like this way because it's the most compact, inline way to  
indicate it.



-David



Re: Aliasing methods in CPAN roles

2009-10-16 Thread David Green

On 2009-Oct-16, at 12:54 am, Richard Hainsworth wrote:
Is there syntactic sugar for aliasing the conflicting method? Eg.  
something like

does XML :db-writexml-db-write;


There needs to be something more than sugar: making a new class or  
role with different methods will break substitutability.  However, we  
could have a feature which aliases a method name in a given scope or  
context; elsewhere, the original name would still be visible.  So you  
could pass your new XML-plus-SQL object to do-xml-stuff(XML $x) and it  
would know to treat it as an XML object with the proper .db-write  
method.


(Incidentally, we could use something similar for renaming imported  
symbols, though in that case it would be only sugar.  Currently, we  
can choose to import something or not, but if a module exports  
something, it presumably has a good reason; rather than simply not  
importing the sub/etc., it would be handy to be able to import it  
under another name.


use Bar foo;# import Bar::foo
use Baz :fooboo;# import Baz::foo as boo()
use Baz foo='boo';   #  or spelled this way
)


Moreover, suppose that the two modules have roles with the same  
name, eg., suppose XML-Database-Module and SQL-Database both define  
a role 'Writable'. How could these one (or both) of these roles be  
aliased?



I suppose the polite thing would be for them to define roles (or  
anything else) inside their own namespaces: XML-Database- 
Module::Writable.



Meanwhile, on 2009-Oct-14, at 7:58 pm, Jon Lang wrote:
Another clarification: there's a subtle but important difference  
between $dogwood.bark:(Dog:).() and $dogwood.Dog::bark().  The  
former calls a Dogwood method that has an invocant that does Dog;  
the latter calls a Dog method.  That is:


   $dogwood.bark:(Dog:).(); # calls Dogwood::bark:(Dog:)
   $dogwood.Dog::bark();# calls Dog::bark:()


Aha, so the bark:(Dog:) syntax identifies the method by its signature  
as well, thus distinguishing it from the .bark:(Tree:) method.  This  
works fine when the sigs can distinguish the invocants, which is very  
common.  However, I could have ambiguous methods even including the  
signatures.  Suppose I have a Logging role that provides a log()  
method for printing some info about a variable.  In particular, I have  
method log(Numeric $x:) { ... } because I want to handle Nums  
specially (say, round them off before printing).  Meanwhile, suppose I  
also have Math::log(Numeric $x:).


If $x does Numeric and does Logging, then $x.log won't be able to  
decide which method to call, unless maybe it's in a sub like  
foo(Numeric $x) that can know to provide Numeric context to $x.   
Outside foo, or inside a sub like bar(Any $x), I need some other way  
to indicate which log method I mean.  $x.log:(Numeric:) won't work  
here, because both roles provide a method with that name and signature.


What if all roles' methods got automatic aliases, to a long(er) name,  
e.g. the .log method could be referred to as such, or  
as .Logging`log()?  That at least would provide a fully-qualified way  
to refer to methods no matter where they came from originally, and  
also allow short names to be used where unambiguous.


(I guess this parallels what we already have for subs, etc., except  
methods would be automatically exported into new roles or classes so  
that we can use short names.  I don't know what the actual syntax  
should be -- I only used ` above for lack of anything better, since  
the obvious .Logging::log means something else.)



-David



Re: Freezing role methods

2009-10-14 Thread David Green

On 2009-Oct-14, at 8:52 am, Ovid wrote:

--- On Wed, 14/10/09, Jon Lang datawea...@gmail.com wrote:
The initial possibility that springs to mind would be to use  
longnames to disambiguate between the two options - specifically,  
by means of the invocant:
...or something to that effect.  You'd still have a disambiguation  
issue, in that you'd somehow need to specify which hat an object  
of class C is wearing when you try to call the method.


Good, that's what I was looking for the last time this came up.  (http://www.nntp.perl.org/group/perl.perl6.language/2009/07/msg32164.html 
)


Except that if a consumer of C needs foo(), they have to fully  
qualify the call to foo().  That violates encapsulation.


I don't see that as an encapsulation problem.  A leaky encapsulation  
means we have to know how something works, but when I have to  
distinguish between $dogwood.Dog::bark and $dogwood.Tree::bark, I'm  
distinguishing between two wholly unrelated actions (that they happen  
to have some of the same letters in their names is completely  
coincidental).  So I have to know *what* a Dogwood object does; but I  
still don't have to know how it does it.


Or to look at it the other way around:  Since we refer to things by  
name, those names have to be unique everywhere; so let's start out  
with long, fully-qualified names everywhere: $dog.Dog::bark(),  
$tree.Tree::bark(), $i.Int::succ, etc.  Now everything's fine --  
except that our fingers are getting tired from all that typing.  We  
want to use shortcuts to say things like $dog.bark, because there's  
only one place that $dog can legitimately find a bark() method, and  
that's in the Dog class, so both we and Perl can easily figure out  
what is meant.


On the other hand, $dogwood.Dog::bark cannot be simplified by leaving  
out the Dog:: because then it would be ambiguous.  But if we look at  
it as starting with full names everywhere, and seeing what we can  
leave out (rather that starting with short names and having to add  
stuff in), I think it's not surprising.



In other cases, there may be no way to implicitly disambiguate.  In  
those cases, there would need to be an explicit way to decide which  
hat the object is wearing.


I really don't think that deferring the decision works.  The  
freezing technique described in the paper allows the consumer, C,  
to statically bind the method foo() in the methods in the  
appropriate role which call it.


The problem with freezing some methods into private ones is that  
those methods weren't meant to be private; if my role provides a .bark  
method, I need to be able to call it.


Dynamic binding defers the decision which causes implementation  
details to leak to consumers of C.  This means that if you change  
your roles, your consumers will potentially need to be rewritten.


But if you merely change the implementation of how bark() works  
(either one), nothing needs to be rewritten.  If you want to change  
from Tree::bark-ing to Dog::bark-ing, then you *should* be rewriting  
code, because you're completely changing what is going on, no less  
than if you changed from bark()ing to fetch()ing.



-David



Re: Freezing role methods

2009-10-14 Thread David Green

On 2009-Oct-14, at 2:00 pm, Jon Lang wrote:

David Green wrote:
On the other hand, $dogwood.Dog::bark cannot be simplified by  
leaving out the Dog:: because then it would be ambiguous.


On the gripping hand, if we have a function train(Dog $d), then we  
can safely assume that within the lexical scope of train, $d is  
supposed to be treated as a Dog.  So within that lexical scope, it  
should be safe to leave off the Dog::.


Yes; and then my question from last time is whether the sig (Dog $d)  
soft-casts the arg such that the non-doggy bits of $d still remain,  
e.g. if inside train() we call a function chop(Tree $t), chop() will  
unambiguously see the Tree-half of the original Dogwood object.  Or  
will it be hard-cast such that the non-doggy bits are simply lost?   
(And if so, does an ordinary cast Foo($d) do the same thing, or is one  
hard and one soft, etc.?)


The soft way -- being able to cast $dogwood as a Dog and treat it  
unambiguously so, then to do the same thing treating it as a Tree  
object -- is the most flexible.  Split-personality Dogs may be rare,  
but I can imagine wanting to call common  utility roles (e.g. Logging)  
from any point down a calling chain.


However, I expect that my Dog $d = $dogwood would strip out  
everything else, on the grounds that you explicitly requested a pure  
Dog object.  Otherwise you could have said my $d = Dog($dogwood) or  
maybe my $dogwood.^WHAT $d = $dogwood instead.



-David



Re: Parsing data

2009-10-07 Thread David Green

On 2009-Oct-7, at 5:18 pm, Aaron Sherman wrote:

This should be powerful enough to match any arbitrarily nested set of
iterable objects. I think it will be particularly useful against parse
trees (and similar structures such as XML/HTML DOMs) and scanner
productions, though users will probably find nearly infinite uses for
it, much like original regular expressions.


I agree that being able to parse data structure would be *extremely*  
useful.  (I think I posted a suggestion like that at one time, though  
I didn't propose any syntax.)  There is already a way to parse data --  
Signatures, but not with the full power that grammars can apply to text.


Data-grammars could do everything that Signatures do, and more, though  
it's still worth having special syntax designed to fit the special and  
ubiquitous case of sub signatures.  Trying to expand signature-syntax  
to cover everything grammars can do would probably end up too ugly;  
nevertheless, if we had full grammars to build on, I'm sure the Sig- 
syntax could be extended quite a lot before it got too cumbersome.  It  
would also open the way for people to build custom sig-parsers (with  
their own special syntax or not).


It also might be worth inventing a whole new syntax design for parsing  
and manipulating data structures, but your suggested extensions seem  
pretty good to me.



-David



Re: Overloading Roles

2009-10-07 Thread David Green

On 2009-Oct-5, at 3:41 pm, Jon Lang wrote:
Concerning that last one: would it be reasonable to have a Discrete  
role

that provides a .succ method, and then overload the Range role?


I think a type needs to be Discrete and Ordered for successors to make  
sense (e.g. consider a discrete unordered type like Complex ints).


I'm still thinking a Discrete type is the same as a Set; so perhaps  
Discrete  Ordered means Positional?  But that doesn't feel right --  
although any ordered set can be represented as an array, that seems to  
confuse the idea of order that is intended.


(And perhaps Discrete should be a different type from Set even if  
they do work out the same, simply to better document one's intent.)




-David



Re: r28597 - docs/Perl6/Spec/S32-setting-library

2009-10-05 Thread David Green

On 2009-Oct-4, at 2:07 pm, Moritz Lenz wrote:

Michael Zedeler wrote:
It doesn't, because succ should always give the next, smallest  
possible

element given some ordering relation.


Where's that definition from?


The dictionary.  =)  It would be confusing to have a successor  
method for something that isn't orderable and discrete.  An ordered  
continuous type like Real could have .inc and .dec; it just happens  
that in the common case of Ints, .succ and .inc mean the same thing.


Complex could have an .inc method, but I don't think there's any  
especially obvious choice (because .inc probably wants an ordered  
type).  Would it add 1? or 1+i?  Better to spell it out explicitly.



Well, Real implies ordering (at least to me ;-), I don't think we  
have a

class or role for countability.


A Discrete role would be useful, but is Set good enough for that?



-David



Re: [perl #69194] rakudo 2009-08 and when with lists

2009-09-21 Thread David Green

On 2009-Sep-20, at 12:48 am, Larry Wall wrote:

Yes, I think it's fair to say that either list context OR a :by turns
a Range into a RangeIterator that matches like a list.  Hence, this
ought to match:

   (1,3,5) ~~ (1..5 :2by)


OK; but I still have to ask why it returns a RangeIterator instead of  
a SeriesIterator or any other plain Iterator.  Is there some reason to  
make :by work on Ranges that way instead of being, say, an adverb on  
...?  I can see that it's obvious and useful to get a list by  
filling in the values between two endpoints, but that also applies to  
a pair, or a list of two items.


Having :by effectively work like a list at least reduces the confusion  
in the case of numbers, but we're still left with a puzzle when it  
comes to strings: Is b ~~ a..az false because it's not the case  
that a  b  az, or is it true because expanding the list produces a,  
b, c, ... ax, ay, az?  The former according to spec; but the latter  
according to someone who expects a parallel with ints.  (Apparently  
Rakudo expects that too, at least for the moment.)  Of course, in this  
case :by doesn't help because there is only one way to increment  
strings.


If we give up the Range/RangeIterator duality, we still have the two  
different concepts, but I think people will be less tempted to try  
making them line up together mentally.  (Different things should look  
different.)  I don't see that we would lose any functionality (make  
the :by features work with ...; or keep .. and ... as two ways  
to make series, and use infix:to for Ranges; or anything else that  
distinguishes ranges from iterators).  What's the big advantage in  
keeping it the way it is?



-David



Re: [perl #69194] rakudo 2009-08 and when with lists

2009-09-19 Thread David Green

On 2009-Sep-18, at 8:44 am, Moritz Lenz wrote:

Aaron Sherman wrote:
2,3 constructs a list. 2..3 also constructs a list, unless it's in  
a given/when condition in which case it's just a range.
No. 2..3 is always a range. It's just list context that turns it  
into a list.



That seems confusing.


It sounds like the split personality of Ranges strikes again.  I still  
think it makes more sense to have one Series-only type and one Range- 
only type, rather than one Series type and one Range-plus-Series type.



-David



Re: [perl #69194] rakudo 2009-08 and when with lists

2009-09-19 Thread David Green

On 2009-Sep-19, at 5:53 am, Solomon Foster wrote:

On Sat, Sep 19, 2009 at 6:48 AM, Carl Mäsak cma...@gmail.com wrote:

David (),
It sounds like the split personality of Ranges strikes again.  I  
still think
it makes more sense to have one Series-only type and one Range- 
only type,

rather than one Series type and one Range-plus-Series type.


If for no other reason than to contribute a contrasting viewpoint,  
I'm

not sure I see the problem in this case. A range is an object in Perl
6, in a much more palpable way than in Perl 5. This might be what
causes the mental mismatch for Perl5-ers.


Well, I wonder if the journey from a P5 point of view is the  
historical reason why we ended up with Range+series .. and Series  
  Otherwise what's the rationale for having Range-:by separate  
from ...?


As far as I can see, the range object already is of your proposed  
Range-plus-Series type,


But that's the problem; I'm proposing there shouldn't be a Range-plus- 
Series type, because it mixes two different concepts.  As a range it  
works one way (basically representing an ordered pair of endpoints),  
but if you use :by() it looks like a discrete list... even though  
really it still is just a Range object.


and when I apply list context to the range, I get your proposed  
Series-only type (which happens to be an ordinary list, but still).


I think a Range shouldn't turn into a list, at least not implicitly.   
Some ranges have an obvious coercion (e.g. a..c becomes a b c),  
but some don't (e.g. 1..5, which should encompass all nums between 1  
and 5, not just the Ints.  Unless we distinguish Int(1)..Int(5) from  
Num(1)..Num(5), which only raises the potential for confusion).



The one thing that worries me about this is how :by fits into it all.
	rakudo: given 1.5 { when 1..2 { say 'between one and two' }; say  
'not'; };

rakudo: given 1.5 { when Range.new(from = 1, to = 2, by = 1/3) {
makes me very leery.  I know :by isn't actually implemented yet, but  
what should it do here when it is?


Exactly: 1.5 is between 1 and 2, but if you're counting by thirds,  
1.5 is not in the list(1..2 :by(1/3)).  Sure, we can stipulate that  
this is simply how the rules work, but people are still going to get  
confused.  On the other hand, we can get rid of the list/series/:by  
part of Ranges without losing any power (move that capability to ...  
instead), and cut down on the confusion.



-David



Re: Synopsis 02: Range objects

2009-08-28 Thread David Green

On 2009-Aug-27, at 3:11 pm, Mark J. Reed wrote:
Given how easy chained relational ops make explicit range checking  
with endpoints, e.g.

$a = $x = $b
I'd be perfectly happy with a Range smartmatching only the elements  
that you get out of the RangeIterator.


Yes -- although sometimes that would require separating out the $a and  
the $b parts, which is why having something to mean between would be  
handy.



On 2009-Aug-27, at 11:08 am, TSa wrote:
Note that order is not a prerequisite for a notion of range and  
range iteration. I think of ranges more like set and set iteration.


Except the meaning of the word range and the spec both indicate  
order: (S03) A star on both sides prevents any type from being  
inferred other than the COrdered role.  Instead, can't the existing  
series operator take on the series aspects of ..?


... can take a function on the RHS that generates new values, or it  
can take * to generate an arithmetic or geometric sequence.  If only a  
single value is given as the LHS, it could use .succ, so 1...* or  
a...* would work like C.. does.


I think the reason C... doesn't take a value other than * as the RHS  
is because of the problem of how to figure out whether the series will  
ever reach that value or not.  But that's easy to figure out in the  
case of an arithmetic or geometric sequence, so 1, 3, 5 ... 99 should  
be OK, and 1, 3, 5 ... 100 should probably be an error.  Maybe * ||  
100 as an endpoint could mean go on forever or until hitting this  
value.


Similarly, it's simple to figure out whether .succ applied to strings  
will reach the endpoint or not.  For an arbitrary function, it's not  
so easy.  However, each type could have a you can't get there from  
here function for figuring out whether an endpoint is part of a  
series or not; if the endpoint passes that test, then you can use it;  
if it doesn't, or if there is no such function that can tell you, the  
only valid endpoint is *.


The :by adverb as applied to C... could take a value, which would be  
added (or handled according to the appropriate type when not dealing  
with Nums) just like it was with ..; or :by could take a block,  
which would run that function.  So 1 ... {foo} would be short for  
1 ... *||Nil :by({foo}).


This way all the series stuff is gathered together, and a Range can  
simply represent a pair of starting and ending points without trying  
to be a list iterator as well.  I expect its main use would be meaning  
between: $foo ~~ $range.  If a Range is not a Series, then there's  
no confusion as to whether being in the range means being in the  
series or not.



S03:
Alternately, we could treat an ellipsis as special when it follows a  
comma to better support traditional math notation.


That seems like an easy mistake to make, so treating it specially  
would be a good quirk.




-David



Re: versioning same-auth forks/branches

2009-08-27 Thread David Green

On 2009-Aug-26, at 3:54 pm, Darren Duncan wrote:
The question I have is what to do when a single same authority wants  
to release multiple forks or branches of the same module, each  
presumably targeting a different use case, and the version numbers  
for each fork/branch are not supposed to be interrelated.



We could allow arbitrary components in the name; that would give  
people as much latitude as they want in making up names and splitting  
them into pieces that are presumably meaningful to a human.  Archives  
like CPAN could either use the whole name as identification (as long  
as the full thing is unique), or they could pick particular pieces  
that they will pay attention to (e.g. name + auth + vers) and ignore  
the rest.


Conventions for other components might evolve over time (e.g. a  
standard meaning for :branch might become customary); the main use is  
for documentation and classifying modules so people can search for  
them, etc.Perl shouldn't care what the name is, long or short,  
other than having a unique way to identify each module.  (We could  
even have an ID separate from the name, but if the names weren't  
unique that would be confusing for people too, so I don't see any  
reason not to keep the long name for that purpose.)


Flagging stable vs. dev releases could be done via a designated  
component in the long name; or it could be a trait on the module (e.g.  
is statusbeta, is statusdev, etc.).  Either way, the info is  
available so you can instruct Perl not to use any alpha modules, or so  
on.




-David



Re: Synopsis 02: Range objects

2009-08-25 Thread David Green

On 2009-Aug-24, at 4:17 pm, Daniel Ruoso wrote:

Em Seg, 2009-08-24 às 23:50 +0200, Michael Zedeler escreveu:

The most elegant solution would be if the data types themselves
indicated their capabilities.

One thing I think you missed entirely is the fact that the infix:..
operator is a multi sub, so it falls to regular dispatch semantics,


But Michael's point was not about what's *possible*, but rather what's  
*reasonable*.  Given that Ranges can act in two ways that lead to  
inconsistency, it would be less confusing to separate the list-kind  
from the interval-kind.


For certain discrete ordered types, like Int, both ways work out the  
same, and since Ints are the most common and most obvious use for  
Ranges, it's easy to overlook the confusion.  The case with strings is  
a good example: it really doesn't make sense that a value not produced  
by a range nevertheless lies between its endpoints.  Why not have a  
separate Interval type?


A Range might get implicitly cast to an Interval by using its  
endpoints; that leaves us open to the same confusion, although the  
context would help.

# Assuming infix:between (Any, Interval)
say 5 between [1, 10];
say 5 between 1 .. 10;

say 'aaa' ~~ 'aa' .. 'ba';  # false
say 'aaa' between aa ba;  # true
say 'aaa' between 'aa'..'ba';   # hm...


Come to think of it, the word range suggests ordering (like the  
related word rank), so perhaps Range is the right name for the  
interval-type, and Series should be the type that produces a series  
of values that may or may not have an innate ordering.  (For example,  
you could produce a Complex series with: 5+5i .. 10+10i :by(1+1i).)




-David



Re: Last IO discussion

2009-08-19 Thread David Green

On 2009-Aug-19, at 5:00 am, Troels Liebe Bentsen wrote:
My idea of working with file names would be that we default to  
locale or
filesystem settings, but give the options of working with paths/file  
names as

binary or a specific encoding.


As mentioned in the old thread, encoding is only vaguely related to  
locale.
The problem (or one of them) is that if I create a file today, and  
then change my locale tomorrow, I end up with a garbled filename.  Of  
course, people don't as a rule change to a different locale every day,  
but I still think this is a situation where we need to put the onus on  
the user.


That is, either Perl can determine the encoding (e.g. because the  
filesystem indicates it in some way), or else the user needs to pick  
one explicitly.  If you get a list of files from reading a dir, and  
don't need to display the names or anything, you might get away with  
treating them as undistinguished bytes; but as soon as Perl does  
anything that needs an encoding and one hasn't been specified, it  
should complain bitterly.


It's the same reasoning why I think specifying a timezone should be  
required: it's not that much work for the user to add use  
IO::Encoding $volume = utf-8, and at least that way naive users  
will be alerted to the fact that something's going on.  It's up to  
them how much effort they think is worth devoting to the issue, but at  
least they will be warned that there's an issue there to grapple with.



-David



Re: [perl #64566] @a[1..*] adds trailing undef value

2009-08-19 Thread David Green

On 2009-Aug-19, at 8:07 am, Jon Lang wrote:
On Wed, Aug 19, 2009 at 5:37 AM, Jan Ingvoldstadfrett...@gmail.com  
wrote:
On Wed, Aug 19, 2009 at 1:54 PM, Moritz Lenz via RT perl6-bugs-follo...@perl.org 
 wrote:
It doesn't mention how the postcifcumfix:[ ] is supposed to  
introspect
those to find out if the WhateverCode object constructed by 1..*  
needs

to receive self.elems or self.elems-1 as an argument.


The * can tell when it's in a range, and set some range-flag on the  
resulting object, right?  Then .[] will test for $whatever.range- 
flag.  Or am I missing the point?



Given that it's relatively easy to say 1..^*, I wouldn't mind
standardizing this so that '*' always refers to the element just past
the last one, at least when dealing with the standard index.


I like the DWIMmery, but the more I think about it, for such a little  
difference, it seems more worthwhile to be consistent than to be  
DWIMy.  So, yes, either * always means last+1, and use 1..^*, or make  
* mean the last index, and use [*+1] to append.



But there is a problem with sparse arrays, isn't there?


Sparseness is an implementation detail.  Arrays all look the same to  
the user; sparseness just means perl is smart enough to do  
@foo[1]=$bar without trying to suck up a zillobyte of  
RAM.



-David



Re: directories of interest, a multiplicity alternative to CWD

2009-08-19 Thread David Green

On 2009-Aug-19, at 2:08 am, Darren Duncan wrote:

 %DOI{'mycwd'} = %DOI{'fscwd'};
 %DOI{'mycwd'} ~= 'subdir';
 # later
 my $fh = IO.open( 'mycwd/myfile.txt' );

For ease of use, we can still have vars like $*CWD, which might be  
an alias for a doi with a specific name.


I've been thinking of something similar, but you should be able to do  
this with any directory object.


my $dir = $*CWD;  # returns an IO object, not merely  
a string
my $dir ~= subdir;  # $dir is now an object  
representing the subdir

my $file = io $dir/filename;

{
temp $*CWD = $dir;
...
}


So the set of default standard dirs would just be a hash of IO  
objects: $IO::DOI{home}, $IO::DOI{docs}, etc.  Actually, different  
OS's would provide different sets of standard named dirs, and you  
should be able to import them:


# Assume I'm running on a Mac, so $IO::DOI::MacOSX is  
automatically loaded
use IO::DOI Home Music Downloads;  # names that ::MacOSX makes  
available


say $Home; # /Users/david
say $Music;# /Users/david/Music
say $Downloads;# /Users/david/Junk drawer


There will be a few names that should be standard as much as possible  
across OS's, e.g. Home even though on a Mac the dir is actually  
called Users.  Trash might be another one (which will be undef if  
the OS doesn't handle it).



This doesn't address the security side of things; dir objects might  
have a flag you can set so that it will warn you (perhaps fatally) if  
you try to use $dir.parent or $dir/.., etc., but you could always  
get to an outside dir some other way.  I think a more explicit way to  
set a chroot is better, such as:


$IO::Root = $*CWD;
$IO::Root = $Home;
temp $IO::Root = $IO::DOI{Docs};

Similarly, if a Perl thread does not see any DOI at all, then they  
effectively are denied access to the filesystem period.



Hm, undef $IO::Root?

Of course, that still doesn't cover everything your suggestion does,  
because your way allows for multiple roots.  But you also weren't  
suggesting a specific syntax, and I'm leaning to something like my  
example above.  Perhaps along the lines of:


$IO::Root{file} = /; # default root (assumes file://)
$IO::Root{http} = http://;;   # means any website
$IO::Root{ftp} =  ftp://;;# etc.

Every time you use IO::Some_protocol_name, it would set a default  
$IO::Root{protocol-name}.  But there's nothing special about the  
names; you can add or change $IO::Root as you wish.


$IO::Root{file} = /foo;
$IO::Root{more files} = /bar;
# Now can access only files that come under /foo or /bar

$IO::Root$_.delete for «file more files»;
# Now there are no more file:// roots, cannot access any files

$IO::Roothttp = http://localhost/~david/;;
# Now can access only URLs from my section of the local website


Hm, having just written that, it obviously should be the case that  
$IO::Rootfile should be a hash with all the available file: roots,  
i.e. $IO::Root is a hash-of-hashes where the keys are {protocol-name} 
{arbitrary-name}.  And the default arbitrary-name might just be  
default.




-David



Re: Filename literals

2009-08-19 Thread David Green

On 2009-Aug-18, at 7:20 am, Timothy S. Nelson wrote:

On Tue, 18 Aug 2009, David Green wrote:
Some ways in which different paths can be considered equivalent:   
Spelling: ... Simplification: ... Resolution: ... Content-wise: ...
	Ok, my next commit will have canonpath (stolen directly from p5's  
File::Spec documentation), which will do No physical check on the  
filesystem, but a logical cleanup of a path, and realpath (idea  
taken from p5's Cwd documentation), which will resolve symlinks,  
etc, and provide an absolute path.  Oh, and resolvepath, which  
does both.  I'm not quite sure I followed all your discussion above  
-- have I left something out?


I think there's a difference between canonical as in a webpage with  
link rel=canonical, and cleanup as in Windows turning PROGRA~1  
into Program Files.  There could also be other types of  
normalisation depending on the FS, but we probably shouldn't concern  
ourselves with them, other than having some way to get to such native  
calls.


	Anyway, my assumption is that there should be a number of  
comparison options.  Since we do Str, we should get string  
comparison for free.  But I'm expecting other options at other  
levels, but have no idea how or what at this point.


As Leon Timmermans keeps reminding us, that really should be delegated  
to the OS/FS.  I think $file1 =:= $file2 should ask the OS whether it  
thinks those are the same item or not (it can check paths, it can  
check inodes, whatever is its official way to compare file-thingies).   
Similarly, $file1.name === $file2.name should ask the OS whether it  
thinks those names mean the same thing.  And if you want to compare  
the canonical paths or anything else, just say $file1.name.canonical  
=== $file2.name.canonical, or use 'eq', or whatever you want to do,  
just do it explicitly.


	According to my last commit, p{} will return a Path object that  
just stores the path, but has methods attached for accessing all the  
metadata.  But it doesn't do file opening or things like that  
(unless you use the :T and :B thingies, which read the first block  
and try to guess whether it's text or binary -- these are in Perl 5  
too).


There are two things going on here: the user-friendly syntax for  
casual use, which we basically agree should be something short and  
pithy, although we have but begun to shed this bike, I'm sure.


$file = io /foo/bar;
$file = p{/foo/bar};
$file = Q:p/foo/bar/;
$file = File(/foo/bar);

However we end up spelling it, we want that to give us unified access  
to the separate inside parts:


IO::Data# contents of file
IO::Handle  # filehandle for using manually
IO::Metadata
IO::Path

I'm not sure why Path isn't actually just part of IO::Metadata...  
maybe it's just handy to have it out on its own because pathnames are  
so prominent.  In any case, $file.size would just be shorthand for  
something like $file.io.metadata{size}.  The :T and :B tests probably  
ought to be part of IO::Data, since they require opening the file to  
look at it; I'd rather put them there (vs. ::Metadata, which is all  
outside info) since plain ol' $file abstracts over that detail  
anyway.  You can say $file.r, $file.x, $file.T, $file.B, and not care  
where those test live under the hood.


We might actually want to distinguish IO::Metadata::Stat from  
IO::Metadata::Xattr or something... but that's probably too FS- 
specific.  I don't think I mind much whether it's IO::Path or  
IO::Metadata::Path, or whether they both as exist as synonyms


	I think we want many of the same things, I'm just expressing them  
slightly differently.  Let's keep working on this, and hopefully we  
end up with something great.


Yes.  A great mess!  Er, wait, no

And there's no perfect solution, but it would be useful for Perl to  
stick as closely as the FS/OS's idea of types as it can.  Sometimes  
that would mean looking up an extension; it might mean using (or  
emulating) file magic; it might mean querying the FS for a MIME- 
type or a UTI.  After all, the filename extension may not actually  
match the correct type of the file.


	My suggestion would be that it's an interesting idea, but should  
maybe be left to a module, since it's not a small problem.  Of  
course, I'm happy to be overruled by a higher power :).  I'd like  
the feature, I'm just unsure it deserved core status.


Well, it's all modules anyway... certainly we'll have to rely on  
IO::Filesystem::XXX, but I do think this is another area to defer to  
the OS's own type-determining functions rather than try to do it all  
internally.  What we should have, though, is a standard way to  
represent the types in Perl so that users know how to deal with them.   
I think roles are the obvious choice: if the OS tells you that a file  
is HTML, then $file would do IO::Datatype::HTML, which means in turn  
it would also do IO::Datatype::Plaintext, and so

Re: Custom object constructors

2009-08-19 Thread David Green

On 2009-Aug-19, at 4:37 pm, Kevan Benson wrote:
I'm aware there's a default constructor that allows named parameters  
to be set, but I think the usefulness of allowing specific  
constructors that take defined parameters and initialize the object  
as needed should not be overlooked.  E.g.

   my DateModule $d .= new('2007-03-12');


My first thought is also coercion: say my DateModule $d = '2007-03-12'  
and let DateModule::.(Str) worry about making the new object.


(Or does that need to be my DateModule $d = DateModule('2007-03-12')?   
That seems unnecessarily redundant.)



-David



Re: r28017 - in docs/Perl6/Spec: . S32-setting-library

2009-08-18 Thread David Green

On 2009-Aug-18, at 2:29 am, Carlin Bingham wrote:

chdir provides functionality that would be quite convoluted to mimic
through manually setting $*CWD, such as changing to a relative
directory.


Maybe setting $*CWD just calls chdir() under the hood?  Same  
implementation, brand new shiny Perl-style interface!



-David



$*CWD and chdir()

2009-08-18 Thread David Green

On 2009-Aug-18, at 3:27 am, Timothy S. Nelson wrote:

On Tue, 18 Aug 2009, David Green wrote:
Maybe setting $*CWD just calls chdir() under the hood?  Same  
implementation, brand new shiny Perl-style interface!
	That was my intent, but we had some discussions on IRC about the  
whys and wherefores, and it will return as soon as I do my next  
commit (hopefully sometime within the next 4-5 hours).  Unless you  
can think of a good way to do relative paths.


In my naiveté, I would do:

class IO::CurrentDir;  # the type of $*CWD

  sub STORE($self: IO::Path $new)
  {
  chdir($new);
  $self = getcwd();
  }

or however that would work in P6.  It may have problems, but by  
definition they're the same problems as chdir() has.  What am I missing?



On 2009-Aug-18, at 3:12 am, Jan Ingvoldstad wrote:
It may seem cool, but I don't like secondary effects like that. They  
break the principle of least surprise.


It doesn't seem that surprising to me, especially after seeing the  
docs the first time.  Are there environments where you can set a  
variable like $*CWD and it doesn't do something like chdir?
(And we can always keep chdir() as well, so old dogs aren't forced to  
learn new tricks.)



On 2009-Aug-18, at 3:52 am, Mark J. Reed wrote:

If $*CWD is really a Path object and not a Str, then it should be easy
to use mutator methods to change to a relative directory and do other
chdir()ish things.  Say, concatenation works in terms of path
components, for instance:
$*CWD ~= $subdir;   # chdir($subdir)


Yes.  Though $*CWD = subdir should also work; subdir is not the  
same path as /subdir, so it knows whether you're assigning a  
relative path or not.  Or rather, our path-type would know, and  
implicitly prepend the current dir when it parses/forms the actual  
pathname, so $CWD would effectively get a fully specified path every  
time.



With a method for getting the parent:
given $*CWD { $_ = $_.up ~ $sibling }   # chdir(../$sibling)


I like that.


and so on.  My favorite kshism is cd old new which does a
search/replace on the current working directory; the bash equivalent
cd ${PWD/old/new} which is not quite as handy.  $*CWD could make
that simple, too.


Ditto.


-David



Re: Filename literals

2009-08-18 Thread David Green

On 2009-Aug-17, at 8:36 am, Jon Lang wrote:

Timothy S. Nelson wrote:
   Well, my main thought in this context is that the stuff that  
can be

done to the inside of a file can also be done to other streams -- TCP
sockets for example (I know, there are differences, but the two are  
a lot
the same), whereas metadata makes less sense in the context of TCP  
sockets;


But any IO object might have metadata; some different from the  
metadata you traditionally get with files, and some the same, e.g.  
$io.size, $io.times{modified}, $io.charset, $io.type.



if (path{/path/to/file}.e) {
   @lines = slurp(path{/path/to/file});
}
   (I'm using one of David's suggested syntaxes above, but I'm  
not

closely attached to it).


I suggested variations along the line of: io /path/to/file.  It  
amounts to much the same thing, but it's important conceptually to  
distinguish a pathname from the thing it names.  (A path doesn't have  
a modification date, a file does.)  Also, special quoting/escaping  
could apply to other things, not limited to filenames.  That said, I  
don't think it's unreasonable to want to combine both operations for  
brevity, but the io-constructor should have built-in path parsing, not  
the other way around.


   I guess what I'm saying here is that I think we can do the  
things
without people having to worry about the objects being separate  
unless they
care.  So, separate objects, but hide it as much as possible.  Is  
that

something you're fine with?


Yes -- to me that means some class/role that wraps up all the pieces  
together, but all the separate components are still there underneath.   
But I'm not too bothered about how it's implemented as long as it's  
transparent for casual use.


my $file = io p[/some/file];
my $contents = $file.data;
my $mod-date = $file.times{modified};
my $size = $file.size;


Pathnames still are strings, so that's fine.  In fact, there are  
different
   As for pathnames being strings, you may be right FSVO  
string.  But
I'd say that, while they may be strings, they're not Str, but they  
do Str


Agreed, pathnames are almost strings, but worth distinguishing  
conceptually.  There should be a URL type that does Str.


Actually, there are other differences, like case-insensitivity and  
illegal chars.  Unfortunately, those depend on the given filesystem.   
As long as you're dealing with one FS at a time, that's OK; it  
probably means we have IO::Name::ext3, IO::Name::NTFS, IO::Name::HFS,  
etc.  But what happens when you cross FS-barriers?  Does a case- 
sensitive name match a case-insensitive one?  Is filename-equality not  
commutative or not transitive?  If you're looking for a filename foo  
on Mac/Win, then a file actually called FOO matches; but on Unix it  
wouldn't.


(Actually, Macs can do both IO::Name::HFS::case-insensitive and  
IO::Name::HFS::case-sensitive.  Eek.)


I'd like Perl 6's treatment of filenames to be smart enough that  
smart-matching any of these pairs of alternative spellings would  
result in a successful match.  So while I'll agree that filenames  
are string-like, I really don't want them to _be_ strings.


Well, the *files* are the same, but the pathnames are different.  I'm  
not sure whether some differences in spelling should be ignored by  
default or not.  There are actually several different kinds; S32 has a  
method realpath, but I think canonical is a better name, because  
aliases can be just as real as the canonical path, e.g. a web page  
with multiple addresses.  Or hard links rather than soft links --  
though in that case, there is no one canonical path.  It may not  
even be possible to easily tell if there is one or not.


Some ways in which different paths can be considered equivalent:
Spelling: C:\PROGRA~1, case-insensitivity
Simplification: foo/../bar/ to bar/
Resolution: of symlinks/shortcuts
Content-wise: hard links/multiple addresses

Depending on the circumstances, you might want any of those to count  
as the same file; or none of them.  We'll need methods for each sort  
of transformation, $path.canonical, $path.normalize, $path.simplify,  
etc.  Two high-level IO objects are the same, regardless of path, if  
$file2 =:= $file2 (which might compare inodes, etc.).  There should be  
a way to set what level of sameness applies in a given lexical scope;  
perhaps the first two listed above are a reasonable default to start  
with.


There's something that slightly jars me here... I don't like the  
quotation returning an IO object.
But doesn't normal quoting return a Str object?  And regex quoting  
return an object (Regex?  Match?  Something, anyway).


Certainly, but a regex doesn't produce a Signature object, say.  I  
don't object to objects, just to creating objects, then doing  
something with them, then returning another kind of object, and  
calling that parsing.  If we're parsing the characters, we should  
end up with an IO::Name.  If 

Re: $*CWD and chdir()

2009-08-18 Thread David Green

On 2009-Aug-18, at 4:59 am, Carlin Bingham wrote:

2009/8/18 Timothy S. Nelson wayl...@wayland.id.au:
   It's not in the revised spec, but I think that, even though  
we've revived chdir, we should still have it so that changing $*CWD  
will do a chdir under the hood.


While in the spirit of TIMTOWTDI, having a magic variable that  
behaves differently from other variables when it's being set would  
be rather odd.


But really, it isn't different  After all, a current path IS  
just a string; it's a string that shells helpfully insert for you at  
certain points to save you some typing.  The automatic insertion may  
be magical, but the string itself is quite ordinary.



The metaphor of being in a directory is quite fascinating, really.   
Directories are not something you can be in -- they're lists that  
hang on the walls of office buildings, or get printed on the pages of  
a phone book.  They're pointers, dir-ections to where you can find  
something -- an office, a telephone, or a file on a disk.  Literally  
*on* the disk, not in it (disk platters are flat!).  But this image  
of working in a directory seems to come quite easily and naturally.



It wouldn't seem magical if we always wrote like this:
ls $PWD/foo/bar
PWD = $PWD/foo
ls $PWD/bar

That would still save a lot of typing, but not having to type the $PWD  
saves even more.
But perhaps the apparent magic is that $*CWD = /foo sets the CWD to  
/foo, but setting it to foo does not set the CWD to foo, but  
rather to $OLDCWD/foo.  But that's not $*CWD's doing, that's our  
path-quoting.


~ p[/foo/bar] eq /foo/bar# path literal cast to Str
~ p[foo/bar] eq $CWD/foo/bar

Not so strange to anyone familiar with the idea of relative paths, and  
no more magical than... say, the fact that a literal series of digits  
gets parsed as though it had an implicit 0d in front of it.  (Of  
course, I suspect that $*CWD should be able to be set to a plain Str,  
but the Str will be cast to an IO::Path because that's what  
$*CWD.STORE() will take in its signature.)



-David



Default path restrictions

2009-08-18 Thread David Green

On 2009-Aug-18, at 1:24 am, pugs-comm...@feather.perl6.nl wrote:

+=head3 Default constraints
+
+The default p{} only allows / as separator and does not allow  
path elements to contain
+characters that won't work on modern Windows and Unix like \ / ? %  
* : |   ,

+etc. The reason for this is that portable paths are the default. If
+platform/filesystem specific behavior is really needed it should be  
shown in

+the code by applying different sets of constraints (see below).


I dunno, doesn't portability in the 21st century mean compatibility  
with the web rather than with DOS??
I'd be inclined to default to whatever works with the user's own OS/ 
FS.  Of course, if you don't like any default setting in P6, all you  
need to do is slap use something-else into your ~/Policy.pm file, so  
it's not a big deal.  Nevertheless, there's more to respecting other  
systems than simply doing without punctuation.  For example, a  
suitable pathname on Unix might be:


~/.foorc

Whereas on a Mac, it might be more polite to use:

~/Library/Application Support/Foo/Startup Settings

which is certainly beyond the scope of p{}-quoting.


-David



Re: $*CWD and chdir()

2009-08-18 Thread David Green

On 2009-Aug-18, at 5:48 am, Jan Ingvoldstad wrote:
On Tue, Aug 18, 2009 at 1:02 PM, David Greendavid.gr...@telus.net  
wrote:
It doesn't seem that surprising to me, especially after seeing the  
docs the first time.  Are there environments where you can set a  
variable like $*CWD and it doesn't do something like chdir?


Yes, and that's normal and expected behaviour.


Huh.  Thank you, I did not know that.  It makes sense (in that I  
understand what's going on now that I see it, and indeed it seems  
almost obvious), but I certainly couldn't call it expected because I  
didn't.  And I can guarantee I'm not the only one; in fact, I have no  
qualms about classifying that as a bug.



-David



Re: S26 - The Next Generation

2009-08-18 Thread David Green

On 2009-Aug-18, at 3:29 am, Jan Ingvoldstad wrote:
In general, executable documentation is a bad thing. It's been shown  
to be a bad thing many times over.


Well, tons of programs have --help options, which could be considered  
executable documentation, and it's very useful.  Emacs brags about  
being self-documenting.


It's worth it because it's more work the computer can do instead of  
humans (and often do a lot better).  It's annoying when a printed book  
says the default setting is $foo when it isn't because somebody  
changed the defaults, or the config file is at $some/$path when it  
isn't because it was installed using a non-standard layout -- but it's  
understandable, because there's not much you can do about that.  It's  
a lot more frustrating when you're looking at docs on a programmable  
computer that actually knows the real settings/paths/etc. and *could*  
tell you, but doesn't.


But it's a lot more than that: although it can help the end-user, it  
also helps authors.  I can weave together my (il)literate POD in the  
most convoluted way Pod6::Order::Labyrinthine can handle.  I can have  
it pull values out of my code so that's impossible for the docs to get  
out of date because I forgot to change them.  That's still a big help  
even if my end users look only at a static copy of the docs once  
they're produced.


If we absolutely must have some sort of executable documentation,  
then if I could, I would insist that it wouldn't be a feature  
complete language. That is: absolutely no IO in the language, no way  
of executing code that's foreign to the doc, and so on.



Well, perl-doc can't run any POD-executing modules that never get  
installed.  But surely it's possible to forbid IO, no?  Disallow any  
actual IO functions, as well as anything that could be used to sneak  
them in (eval).  I guess you'd want to allow Perl itself to load  
installed modules (but maybe nothing from the current dir, or outside  
the official library location).  Having perl-doc run in lock-down  
mode, or run in display-precompiled-static-file-only mode by default  
might be a good idea, though I'm not convinced it's completely  
necessary.



-David



Re: r90210 - in docs/Perl666/Spec: . S0S-upsetting-library

2009-08-18 Thread David Green

On 2009-Aug-18, at 7:05 am, Mark J. Reed wrote:
On Tue, Aug 18, 2009 at 6:59 AM, Carlin Binghamcar...@theintersect.org 
 wrote:

2009/8/18 Timothy S. Nelson wayl...@wayland.id.au:

On Tue, 18 Aug 2009, Mark J. Reed wrote:

   It's not in the revised spec, but I think that, even though  
we've
revived chdir, we should still have it so that changing $*CWD will  
do a

chdir under the hood.


You're quoting the wrong person.  That wasn't me.


Technically of course, he quoted Tim quoting you without any of the  
double-quoted material but with the quoted attribution referring to  
your non-quoted quote.  I wish e-mail programs were smart enough to  
catch when somebody's text has all been snipped out but the dangling  
attribution hasn't.


Hey, what if P6 had built-in mail software that used a Grammar to  
analyse messages and store the nested levels in a Tree structure -- we  
could have a special A: quoting mechanism for literal attributions,  
and maybe some variations like aa: to allow for interpolated names, or  
a:dates to parse -MM-DD, etc. as automatically inserted date  
formats.  On could be a special macro so you don't even need quotes  
around an attribution line.  Oh, and people use different languages to  
say On $date, $foo wrote, but that's pretty easy to fix: just  
include a working version of babelfish.com (it's just a few textareas  
-- you could probably whip it up in a day using Catalyst).









Plus it should disallow / \ ? * $ @ % ☹ unless preceded by (##`=☞,  
and not run any executable code when you're looking at it.  And  
there's a magic plural-\s (s/://g), but it works only if the  
attributee is Larry Wall.




-David is it bedtime yet? Green




Re: S26 - The Next Generation

2009-08-17 Thread David Green

On 2009-Aug-17, at 12:27 pm, Moritz Lenz wrote:

However it seems we have to pay a price: each act of rendering a Pod
file actually means executing the program that's being documented (at
least the BEGIN blocks and other stuff that happens at compile time),
with all the security risks implied. So we'll need a *very* good
sandbox. Is that worth it?


Yes.  In general, if you've installed a module, it's because you're  
going to use it, and you already trust it.  So this is a problem only  
if you're looking at the documentation for the first time to decide  
whether you do want to use the module (and didn't already read the  
docs on CPAN.org first or something).  Of course, CPAN will need a  
static copy of the docs anyway, so the solution is that authors should  
provide a static file (preferably in a few formats, at least text and  
HTML).


Sites like CPAN will probably make a static doc file a requirement,  
and even the cpan shell could warn users about any modules that don't  
include static docs -- in fact, I think it would be reasonable to  
refuse to install such modules by default.



-David



Re: S26 - The Next Generation

2009-08-16 Thread David Green

On 2009-Aug-16, at 2:26 pm, Damian Conway wrote:

It's Sunday evening and, as promised, here's the new draft of S26.


Yay!  (To the contents, that is, not to the posting of it.  Well, to  
the posting too, since otherwise it would have been much harder to  
read.)



Perl that accesses $=POD and/or the .WHY and .WHEREFORE methods


My favourite part is that it's actually called WHEREFORE.  (Take  
that, all-other-programming-languages!)



Hopefully this is something close to the final draft...and something  
that every stakeholder and faction in this long discussion can  
dislike equally. ;-)



I like it very much.  But don't worry, I'll think of something to  
quibble about!



-David


P.S. to format it using perldoc2xhtml, I had to change the =begin  
item at line 589 to =for item.




Files and IO and all

2009-08-14 Thread David Green

On 2009-Aug-14, at 4:34 am, David Green wrote:
There's a lot of scope for a nice, friendly, high-level IO view;  
perhaps we need an IO-working group to assemble knowledge about what  
is and isn't possible with different filesystems and design an  
interface around it all.



It won't be possible to unify every different FS function, but it can  
keep the basics (like open) as consistent as possible across  
platforms, and provide idiomatic Perl expressions so everything at  
least tries to feel perlish.  Some things may simply be impossible  
to manage transparently (like filenames with no identifiable  
encoding), but even having an organised way to identify the possible  
problems will be helpful.  (A lot of similar issues apply to  
databases, despite which -- or because of which -- it's so nice to  
have the DBI project.)


All the low-level features have to be there, of course, to open files  
and seek through them, etc., etc., but Perl is not a low-level  
language; we have (in P5) the magical , but the easy way to deal  
with files should always apply (that is, be available anywhere you  
don't absolutely need to manipulate low-level details).


The idea is to treat files as data, because that's what we're really  
interested in: their contents, not all their surrounding metadata.  If  
you're writing a file-manager, then you need lots of FS-specific  
detail; in fact, you probably don't care about the contents of files  
but only their metadata.  However, it's more usual to care only about  
the contents and use a bit of metadata (like the name) merely as a way  
to get the contents.  The high-level interface shouldn't be concerned  
with file handles or pointers, but simply with files, and not even  
as concerned with files as with *data*.



In other words, the focus should be on a data-structure, not on the  
file itself.  A text file is really just a way to store a string; an  
XML file is a way to encode and store a structured tree object.


my Str $poem = io file://jabberwocky.txt;
my Image::JPEG $camel = io file://dromedary.jpg;
my XHTML::Doc $x is readonly = io http://foo.org/a%20doc;

Then you simply work with your string, or tree, or image-object.  An  
XHTML::Doc object, for instance, would really contain nodes, but it  
would know how to encode or decode itself as a series of plain-text  
tags for reading or writing to disk.  The old-fashioned way to handle  
this is to open the file, get a filehandle, read the filehandle into a  
string, take the string[s] and XHTML::Doc-parse() them.  The new way  
would be to have the parse(Str) method be how XHTML::Doc objects do  
the IO::input() role, and the IO class takes care of the opening and  
reading behind the scenes.


Anything could mix in the basic IO role so that an object can load or  
save itself.  Different data structures would override the necessary  
methods to format the data the right way.  The type of IO object would  
determine how metadata works (i.e. whether it's a file or an HTTP  
stream or a directory, etc.).



Objects would handle other functionality in whatever ways make sense  
for that object.  For example, iterating a plain-text file would split  
it into lines.  (This suggests that maybe ordinary Strings could split  
into lines in @-context?  Hm.)  A Spreadsheet::OpenOffice object might  
instead provide a list of worksheets when acting like an array (or  
hash, with sheet names as the keys). A raw binary file of  
uninterpreted data would just be a simple Blob object.


Assuming that there existed a consistent definition of Table objects  
that could be coerced one to another, we could do things like:


my Table::SQL $input is readonly := io dbi:Pg:employees/active;
my Table::Spreadsheet::Excel $output := io file://Active-Emp.xls;

$outputSheet #1 = $input;# read from input, write to output
say Data from $input.io.name() saved to $output.io.name();


Now of course there are lots of things that such a broad interface  
isn't prepared to handle, but that's what the lower levels are for.   
If .io provides access to the intermediate interface, then you can  
start with course-grained control, and delve into the particulars if  
or when you need finer control (access to OS- or FS-specific calls).   
Above that, there is room for a very high-level IO functionality that  
glosses over a lot of details, because an awful lot of code just  
doesn't need all the specifics.



-David



Re: Filename literals

2009-08-14 Thread David Green

On 2009-Aug-14, at 5:36 am, Richard Hainsworth wrote:
Would it be possible to remove the special purpose of \ from strings  
within IO constructs?


It's P6, anything's possible!  I probably wouldn't change [what look  
like] ordinary quoted strings, but maybe something with a qf//-type  
construct (or would that be qf\\ ?!).  My idea of using a macro was to  
grab almost anything that wasn't whitespace, and it doesn't have to be  
parsed like a normal string, so \ could be interpreted as a dir  
separator.


Of course, / has become so standard, that it even works on Windows  
(kind of); on the other hand, being able to use either (or both) would  
be convenient for a lot of people.



On 2009-Aug-14, at 7:18 am, Leon Timmermans wrote:

I don't think that's a good idea. In general, parsing an URI isn't
that easy, in particular determining the end is undefined AFAIK. In
your example the semicolon should probably be considered part of the
URI, even though that's obviously not what you intended.


Well, we can encode a URI any way we like -- I was thinking of  
anything up to the next whitespace or semicolon, maybe allowing for  
balanced brackets; and internal semicolons, etc. being %-encoded.  I  
guess the argument would be that using an encoding that looks almost- 
but-not-quite like other popular ways of representing URIs could be  
confusing, and people would be tempted to paste in addresses from  
their browser without re-encoding them the P6 way.


Maybe it's more practical to permit only URIs with little to no  
punctuation to be unquoted, and quote anything else?  Not that quoting  
is such a great hardship anyway



On 2009-Aug-14, at 7:41 am, Timothy S. Nelson wrote:
	And in response to David Green and his comment about working with  
file data vs. metadata, as a systems  programmer, I've written a  
fair number of programs that have worried a fair bit about the  
metadata in the filesystem; sometimes you want to read data, and  
sometimes metadata.


Of course; and when I referred to low-level and high-level, there  
isn't really a distinct dividing line between the two.  Is getting (or  
setting) the modification date on a file low-level because it's  
metadata, or high-level because it's a simple, ordinary task?  I  
don't particularly care about the classification; I just wanted to  
make the point that P6 should make it possible to gloss over anything  
that's over-glossable.



-David



Re: Embedded comments: two proposed solutions to the comment-whole-lines problem

2009-08-13 Thread David Green

On 2009-Aug-11, at 1:38 pm, raiph mellor wrote:

For a quick backgrounder, Larry had talked of reserving backtick for
use as a user defined operator [1], Mark had suggested its use as a
(tightly bound) comment [2], and James et al had suggested using it to
declare units [3].


I'd like to see units, but as I've pondered it in the back of my mind,  
I've realised we don't need special symbols for them.  A unit is just  
an object that has methods for converting to other units; sugar can be  
provided by postfix operators that cast their operand to the  
appropriate type: 42ft calls Unit::Length::Foot(42).



I've long been in Mark's camp about a lightweight and attractive
docstring syntax being likely to be helpful for encouraging habits
that would likely contribute to improved long term maintainability of
code with comments, and was mulling that.


Me too.  It's not just making it easier to write documentation as you  
go -- and POD already makes it fairly easy -- but more than that, it's  
a matter of making it easier to *structure* that documentation.  P6 is  
so powerful that equally powerful docs are going to be needed to take  
advantage of it.  For example, there needs to be a way to pull out the  
docs for a specific function, or a specific parameter of a specific  
function: perldoc --module=Foo::Bar --method=baz --param=Title


In P5, there's a sort of coincidental structure available, in that you  
can put a chunk of POD next the function it describes, but the  
relationship needs to be more formal if, say, your editor is to be  
able to pull out that information to display it when you click on a  
keyword, or to auto-complete argument names, etc.  Happily, Damian  
posted a while back that he is working on a way to associate docs with  
code.


The other problem related to that is the need for end-user  
documentation to have its own structure and order, which often will  
not be the same order supplied by the code.  There needs to be a way  
to override and extend the structure, either by specifying a recipe  
for assembling the finished doc out of separate chunks of POD  
scattered about the code; or else by writing the docs in order and  
then link pieces the associated units of code.


(Of course, we're also faced with a poverty of tools: there's no  
technical reason we couldn't view the same file in code mode and  
doc mode... but it's no fun writing features that people can't use.   
On the other hand, nobody writes tools for features that don't exist,  
so you have to start somewhere.)



-David



Re: Rukudo-Star = Rakudo-lite?

2009-08-09 Thread David Green

On 2009-Aug-9, at 6:30 am, Richard Hainsworth wrote:
Its just that */star/whatever doesnt convey [to me] the fact that  
its a sub-set of of Perl6.


I like *... it has more personality than lite.  (Or even light.)  
Though since it's a subset, we could always call it Rakudo ⊂!



On 2009-Aug-9, at 12:29 pm, Henry Baragar wrote:

Ruby anyone?  See http://en.wikipedia.org/wiki/Rake_(software).


You mean call it Rakudo Ruby because Ruby has only part of the  
features of P6?  We could name interim releases after competing brands  
as they get left behind: Rakudo Ruby, Rakudo Python, Rakudo P5   
(We're already too late for Rakudo PHP, I'm afraid.)



On 2009-Aug-9, at 3:57 pm, Tim Bunce wrote:
Perhaps it's worth asking what we might call the release after that  
one.

Rakudo not-quite-so-lite?


Rakudo ** (aka Rakudo Exponentiation)?  Though I think Patrick is  
optimistic that development will proceed exponentially enough that a  
single interim release will be enough to hold us over until Christmas.



-David



Re: Reusing code: Everything but the kitchen sink

2009-07-12 Thread David Green

On 2009-Jul-10, at 4:37 pm, Jon Lang wrote:
This is one of the distinctions between role composition and class  
inheritance.  With class inheritance, the full tree of inherited  
classes is publicly accessible; with role composition, the methods  
of the combined role are the only ones that are made available to  
the class.



OK, that's actually about what I was thinking, despite the peculiar  
way I expressed it.  I meant the full names to refer to methods  
directly in the composed role, not somewhere else.  Of course, there's  
already a way to refer to methods with the same name -- using the long  
name that includes the signature.  So my example should have used  
bark(Canine: ...) and bark(Tree: ...); and whichever one actually  
gets called depends on whether the invocant does Canine or does Tree.


so Dogwood::bark ought to consider its context (am I being called to  
behave like a Canine, a Tree, or something else?) and decide what to  
do based on that.  If Dogwood::bark isn't defined, you should get an  
implementation conflict error, because the class failed in its duty  
to provide an implementation.



Yes, and Dogwood::bark could handle it by something like: if  
$self.does(Canine) {...} elsif $self.does(Tree) {...} -- but Perl  
already knows how to handle multiple dispatch based on type, so I  
shouldn't have to write it out manually.  In fact, this works with  
Rakudo: you can have both barks if you declare them as multis, and  
then it will accept them without having to declare a Dogwood::bark.   
(But of course if you try calling it, you get an Ambiguous dispatch  
to multi 'bark' error, because a $dogwood object equally satisfies  
both signatures.)


(I tried to see what would happen if you cast the $dogwood object to  
Canine or to Tree, but either Rakudo doesn't do it yet, or I got it  
wrong.)


Needing to say multi makes sense if you wanted multiple methods of  
the same name *within* a role (or class or any other namespace), but I  
don't think it should be necessary across different Roles.  Since they  
already exist in different namespaces, we know they're supposed to  
mean different things, and it's a simple fact of life that sometimes  
the same term will get used in different places for completely  
different meanings.  If you have to do the dispatching manually, I  
guess that's only a slight annoyance as long as it's possible.  (Maybe  
it's better to force the programmer to do it, not because Perl  
couldn't, but to prevent potential surprises? Hm.)




   role R { method foo() { say foo }
   role R1 does R { method bar() { say bar }
   role R2 does R { method baz() { say baz }
   class C does R1 does R1 { }

The question is whether or not Rakudo is smart enough to realize  
that R1::foo is the same as R2::foo, or if it complains that R1 and  
R2 are both trying to supply implementations for foo.  The former is  
the desired behavior.


Conversely, in this case the same name means the same thing, so it  
does seem perl ought to be able to tell that both foo's are really a  
single foo() here; since they both come from the same role (R), they  
have to mean the same thing, and C has to know that it does R.




In any case, then the question is how to know what role something  
does, which is really a question about casting and passing args rather  
than anything to do with Roles per se.  I can't tell just from  
$dogwood.bark which kind of barking is wanted; but I could have  
Dogwood::bark_like_a_dog() instead, perhaps.


However, in
   sub nighttime (Canine $rover) { $rover.bark if any(burglars()); }

I can only call .bark because all I know for sure is that I have  
something which does Canine; if I pass it a $dogwood object, I see  
three possibilities:


1) $rover in the sub is just the Dogwood object that was passed in,  
and calling $rover.bark cannot know what to do.  I also can't call  
$rover.bark_like_a_dog or anything else, because that method exists  
only for Dogwood objects, and the sub doesn't always receive  
Dogwoods.  So I'm stuck, and I don't see any way around that the way  
things are.


2) $rover does Canine and only Canine -- the Tree-half of $dogwood  
that was passed in is invisible inside the sub, and thus $rover.bark  
calls bark(Canine:) which is what we want.  (Of course, it calls  
Dogwood's bark(Canine:) when passed a Dogwood object -- it's not  
magically jumping back to the original Canine role.)  If nighttime()  
in turn calls something-else($rover), the something-else sub also gets  
only a Canine object.


3) $rover acts like a Canine, but the rest of the original $dogwood  
arg (the Tree parts) are still there; they just aren't used unless  
somehow explicitly brought out; for example, by casting $rover to a  
Tree, or by passing it to some other function that is looking for a  
Tree object.  This is how I'd like it to work, because that's the most  
flexible.


Maybe there should be hard casting and soft casting: by hard  

Re: RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-12 Thread David Green

On 2009-Jul-12, at 12:43 pm, Daniel Ruoso wrote:

role R1 {
  method foo() {...} # degenerates to interface
}


Just wondering: since merely declaring an interface will be common  
enough, should we be able to say simply method foo; inside a role,  
and drop the {...}?



class Bla does R2 {
  method foo {
# implementing here is natural, since the role only
# declared a stub, it's even a warning not to implement it
  }
  supersede method bar  {
# explicitly tells that I want to ignore the implementation
# in the role. nextsame wouldn't find the role implementation.
  }
  augment method baz {
# explicitly tells that I want to provide an additional
# implementation besides the one in the role. nextsame would find
# the role implementation.
  }
}


Works for me.  I thought having suggest to make it work the other  
way around sounded useful too, but perhaps you think in practice it  
wouldn't be worth it?



-David



Re: Reusing code: Everything but the kitchen sink

2009-07-10 Thread David Green

On 2009-Jul-7, at 5:28 am, Jonathan Worthington wrote:
The spec is right in that you need to write a method in the class  
that decides what to do. This will look something like:


  method fuse() { self.Bomb::fuse() }



That makes sense for using the combined role on its own, but can we  
still handle separate roles that get mixed together?  That is, after  
defining that method so I can call $joke.fuse(), can I still call  
$joke.Bomb::fuse and $joke.Spouse::fuse as well?


I'm thinking that it's useful to be able to refer to the fully- 
qualified names for anything composed into a role or class; often  
there will be no ambiguity, so the full name won't be necessary.  If  
the names aren't unique, then you can specify them fully, and perhaps  
add an unqualified fuse() that does one or the other (or both? or  
neither??) for convenience.  That shouldn't be necessary, I think --  
it just means you would have to spell out exactly which method you  
wanted.


In the case Ovid also mentioned where two roles have a method of the  
same name because both methods really are doing the same thing, there  
ought to be a way to indicate that (though if they both come with  
implementations, you'd still have to pick one or write your own).


Of course, in a perfect world, the common method would come from its  
own role: if Foo.fuse and Bar.fuse really mean Foo.Bomb::fuse and  
Bar.Bomb::fuse, then doing Foo and Bar together should automatically  
give you a single .fuse method (again, at least as far as the  
interface is concerned).



I guess being able to create a role by dropping some bits from an  
existing role would be useful sometimes, but it seems to lose one of  
the most useful benefits of roles: as Jon Lang pointed out,  
R1 :withoutfoo bar would effectively be a new role, one that  
doesn't do R1.  But you want something to do a role in the first place  
so that it will work anywhere else there is code looking for that role.


So supposing:

   role Canine { method bark { say ruff; } };
   role Tree   { method bark { say rough } };

   class Dogwood does Canine does Tree { ... };
   my Dogwood $dw;

   sub nighttime (Canine $rover) { $rover.bark if any(burglars()); }
   sub paper (Canine $rex) { $rex.bark if newspaper(:delivered); }
   sub paper (Tree $nodes) { $nodes.bark == flatten; ... }

What happens when I call nighttime($dw)?  Obviously, it's meant to  
call $dw.Canine::bark. Since nighttime() is looking for something that  
does the Canine role, any method calls in that function can safely be  
assumed to be short for .Canine::bark (since all we know for sure is  
that any arg passed in will do Canine, and we can't know it will do  
anything else).


If I want to call paper(), then I would have to cast $dw to either one  
of the roles, e.g. paper(Tree($dw)), and that would presumably strip  
off or hide the Canine part of its nature.  It doesn't seem  
unreasonable for any non-Tree attributes to be inaccessible inside  
paper(Tree), since all it can guarantee is the arg does Tree; but on  
the other hand, I think it would be OK but would require you to use  
the fully qualified names for anything non-Tree.


If Dogwood defines its own .bark method, I can see it meaning one of  
two things: either it's yet another bark(), specifically  
$dw.Dogwood::bark(), that can be used only where we're expecting a  
Dogwood object.  (It might bear no relation to Canine::bark or  
Tree::bark, although in that case it would probably be a good idea to  
pick a different name!)  Or else, it could mean a consolidation of the  
two mixed-in .bark's, i.e. $dw.Canine::bark and $dw.Tree::bark would  
both now be implemented by plain $dw.bark, aka $dw.Dogwood::bark (all  
three full names would mean the same thing for Dogwood objects).




-David



Huffman's Log: svndate r27485

2009-07-10 Thread David Green

On 2009-Jul-8, at 3:41 pm, pugs-comm...@feather.perl6.nl wrote:

=item log
+ our Num multi method log ( Num $x: Num $base = Num::e ) is export
 Logarithm of base C$base, default Natural. Calling with C$x ==  
0 is an error.


It occurs to me that log is a pretty short name for a function I  
rarely use.  (In fact, I'm not sure I've ever used it in perl.)  On  
the other hand, I -- and a thousand or so CPAN modules -- are always  
logging stuff in that other popular computer sense.  (All right, that  
number isn't exactly the result of a rigourous study... I did find 57  
modules that mentioned logarithms.)


The inertia of tradition weighs heavily here, but perhaps we could  
call it ln(). (If anyone asks, I'm prepared to say with a straight  
face that it stands for log (numeric).)  And/or log(), but with  
the :base arg mandatory -- then as long as your status logging doesn't  
have a :base, you can have both.



-David



Re: YAPC::EU and Perl 6 Roles

2009-07-10 Thread David Green

On 2009-Jul-8, at 1:49 pm, Ovid wrote:
That being said, roles also have two competing uses (though they  
don't conflict as badly).  As units of behavior, they provide the  
functionality your code needs.  However, they can also serve as an  
interface.



Maybe there are Interfaces, which are, well, just interfaces, and  
there are Roles, which are Interfaces plus a partial or full  
implementation.  Like roles and classes, roles and interfaces could be  
transparently interchanged when suitable.  Add some bodies to an  
Interface and you've got a Role; cast a Role to an Interface and you  
strip out everything but the declarations.



Behavioral:  if you are primarily relying on roles to provide  
behavior (as we do at the BBC), then silently discarding the role's  
behavior by providing a method of the same name in your class can  
lead to very confusing bugs.  I've lost a lot of time debugging this  
behavior.



role Stuff
{
suggest method foo { ... }
method bar { ... }
}

class Thing does Stuff
{
method foo { ... }
supersede method bar { ... }
}


Since foo() is only suggested by this role, you can easily override  
it; whereas bar() needs to be explicitly superseded.  (Or maybe it  
should be method foo :suggested)


The idea being that certain methods are expected to work by accepting  
what's provided in the role most of the time, so you should rarely  
have to supersede them; or they're merely suggestions, and therefore  
you are expected to role^H^H roll your own most of the time.  (And if  
you find yourself getting annoyed that you have to type supersede so  
much, that's probably a good clue that something went wrong somewhere  
in the design.)


Either that, or just have suitable warnings that can be toggled on or  
off depending on what sort of policies you need.  That was actually my  
first thought, and I think we should have adjustable warnings for  
everything anyway, but the more I look at the above example, the more  
it's growing on me.



-David



Re: New CPAN

2009-05-30 Thread David Green

On 2009-May-30, at 6:56 am, Andrew Whitworth wrote:

I'm not saying we *can't* create a general repository for all sorts of
nonsense, I'm saying that we *shouldn't*.


Holiday photos is just a whimsical example.  The problem is that  
it's hard enough keeping up with what Perl6 is today, let alone what  
it will be tomorrow.  Or what Perl 7 will be, or what some other  
programming language/system will be that isn't even invented yet.   
Mark's point is that any arbitrary restrictions put in place now will  
seem short-sighted in 10 years' time, so we need something flexible.   
And it's all just 1s and 0s to the computer, so you *could* use it for  
photographs; that shouldn't matter to the software.



If you want to create an infrastructure that is vastly extensible and
too clever by half, that's you're prerogative.


Sure, it's always possible to go too far.  But on the other hand,  
isn't Perl 6 all about being too clever by half?  It's certainly about  
being vastly extensible, anyway.



-David



Re: New CPAN

2009-05-30 Thread David Green

On 2009-May-30, at 12:06 pm, David Green wrote:

...what Perl6 is today, let alone what it will be tomorrow.


Actually, we do kind of know what Perl will look like a decade from  
now, because P6 is deliberately extensible enough that we may never  
need a Perl 7.  But that simply means that holiday photos are already  
a possibility:


perl -MSteganography::Images pics/2009/ceylon.jpg

In fact, you could do that in Perl 5


On 2009-May-30, at 9:32 am, Daniel Ruoso wrote:

If you replace holiday pictures by 'YAPC pictures', 'Talk slides',
'Code Snippets', 'Perl related scientific articles' it does look much
more closer to a very good use of CPAN.


Hm, all we need is the right grammar, and your slides can be their own  
code!



-David



Re: renaming or adding some operators

2009-05-30 Thread David Green

On 2009-May-29, at 7:53 pm, Darren Duncan wrote:
Thirdly, there are I'm sure a number of other aliases that could be  
added to other ops, such as ≤ and ≥ for = and =, and ≠ for  
one of the inequality operators, although that last one would  
probably make more sense if = was the equality test operator, so  
maybe best to avoid ≠ then.


Probably.  I would really like to see the obvious symbols defined,  
though, for two reasons:


1) Being able to use real symbols (e.g. ≤ instead of crude ASCII  
approximations) will make Perl code look ever so pretty and make all  
the other kids envious.  (Envy is, of course, one the great  
programmers' virtues, the one that makes us steal all the best bits  
from other languages!)


2) It will discourage people from abusing operators that already have  
well-defined standard meanings.  For example, if there is no ∑,  
somebody might be tempted to use it for multiplication; or to use √  
for checking something; or + for concatenating strings, etc.



However, I think some set ops could also be used with hashes.  For  
example, an alternate way of spelling exists %foo{$bar} is $bar  
∈ %foo or %foo ∋ $bar.


I think that one's ambiguous as to whether $bar exists as a key or a  
value.


$bar ∈ @foo; $bar ∈ %foo.keys; $bar ∈ %foo.values;  ∃ %foo{bar}



-David



Re: deciphering infix:cmp

2009-03-27 Thread David Green

On 2009-Mar-26, at 10:50 pm, Patrick R. Michaud wrote:
But what to do with something like C 3 cmp '3' , or any   
infix:cmp where the operands are of differing types? Do we  
constrain Ccmp to only work on similarly-typed operands (in which  
case my sort above would fail), or am I overlooking something obvious?


Failing makes sense to me (you can't compare apples to oranges, at  
least not without explicitly saying you want compare them only as  
coerced to general Fruit types).  The other way I can think of that  
might be useful practically is to compare first by type, then by  
value; but that should probably be a different operation.


say sort { $^a.WHAT leg $^b.WHAT || $^a cmp $^b }, a, 1, b,  
2 , c, 3, d, 4;




-David



Re: a junction or not

2009-03-17 Thread David Green

On 2009-Mar-17, at 2:16 am, Jon Lang wrote:

$choice.perl will return the same thing that the following would:
any($choice.eigenstates.«perl)

That is, it would return a Junction of Str, not a Str.  So the
question is how to get something that returns an expression to the
effect of:
'any(' ~ $choice.eigenstates.«perl.join(',') ~ ')'


say $choice.perl

...which will ultimately call (junction-of-.perl's).Str, and  
Str(Junction:) is what produces the any(XXX) string.  [Unless it  
ends up being implemented some other way, of course!]




The other question is: given $choice as defined above, how do I find
out which type of junction it is?


I guess really Junctions need two public methods: .eigenstates for the  
values, and, er, .eigenop(?!) to return how they're joined -- I'm  
thinking it would return a code ref, i.e. any, all, etc.



-David



Re: Recursive Runtime Role Reapplication Really Rebounds

2009-03-10 Thread David Green

On 2009-Mar-9, at 3:32 am, Ovid wrote:
Since you cache resultsets if they've not changed, you could easily  
have the XML

and YAML roles getting reapplied at runtime multiple times.

Could this issue be mitigated with temp variables?
  {
 temp $resultset does Role::Serializable::YAML;
 print $resultset.as_string;
 }


I suppose, but is there a reason why you want to apply roles instead  
of coercing the results?


$x = Role::Serializable::XML $resultset;
$y = Role::Serializable::YAML $resultset;



-David



Re: Masak's S29 list

2009-02-26 Thread David Green

On 2009-Feb-26, at 7:46 pm, Timothy S. Nelson wrote:

# Object has .print and .say.
[...]


My question is, would we be better off having the string conversion  
routine for arrays worry about the input/output record/field  
separators, rather than the IO object?  The downside I can see is  
that you couldn't have separate separators for different IO objects;  
you'd have to code specially if you wanted that functionality.


What about having separators that exist in different scopes?  Objects  
could define their own separators, or if they don't, default to those  
defined on the IO item, which in turn could default to whatever is  
defined in the current block, working outwards from there.


This may also mean we don't need .print and .say methods on Object.   
Am I missing the reason why such methods would exist, other than to  
allow certain objects to define their own special distinctions between  
printing and saying (presumably because simply adding a newline  
wouldn't be suitable)?
In that case, all the object would need to do is to define its own  
record-separator.




-David



Re: min= (from Rakudo Built-ins Can Now Be Written In Perl 6)

2009-02-24 Thread David Green

On 2009-Feb-23, at 11:30 pm, Carl Mäsak wrote:
For what it's worth, I write a lot of Perl 6, and I'm already used  
to it.


OK.  Of course, you might be smarter than the average coder, but I  
agree it's not a huge deal.



On 2009-Feb-24, at 9:29 am, Mark J. Reed wrote:
On Tue, Feb 24, 2009 at 11:16 AM, Ruud H.G. van Tol rv...@isolution.nl 
 wrote:

David Green wrote:

   my $foo is limited(100..200);
   $foo = 5;   # really does $foo = 100


Where does that MySQ smell come from?  Why not undef (or NaN)?
How about Failing instead of any of the above?   Silently replacing  
the assigned value seems like a Bad Idea.


MySQL does stuff like that silently, which is a problem.  But it's OK  
if you ask for it.

In fact, why not all of the above:

my Int where {100 = $_ = 200} $foo;
$foo = 5;# failure!

my Int where {100 = $_ = 200} $foo is silently-set-to(NaN);
$foo = 5;# does $foo = NaN

my Int where {100 = $_ = 200} $foo is auto-kept-within-limits;
$foo = 5;# does $foo = 100

Except with better names...


On 2009-Feb-24, at 10:30 am, Larry Wall wrote:

Alternately, if you want a purer FP solution:
   take $foo clamp 100..200;
   take $bar clamp $midpoint ± $epsilon;


That's a much better name!  But why take instead of $foo clamp=  
100..200?

(Maybe the answer is why not?, but I might be missing the point.)


-David



Comparing inexact values (was Re: Temporal changes)

2009-02-23 Thread David Green

On 2009-Feb-23, at 10:09 am, TSa wrote:

I also think that time and numbers in general should be treated in
a fuzzy way by smart match.


My thought is to have == take a :within adverb, at least for imprecise  
types like Num, that could be used to specify how close values need to  
come in order to be considered equal.


So instead of:
if abs($x-$y)$epsilon { ... }

you could say:
if $x==$y :within($epsilon) { ... }

which makes your tests for equality look like tests for equality.

I'd even suggest that the :within be mandatory, to guarantee that the  
coder is aware that $x==$y is probably not DWIM.  Of course, there  
should also be an easy way to set epsilon across a scope, like:


use Num :precision(0);# force exact matches in this block



-David



min= (from Rakudo Built-ins Can Now Be Written In Perl 6)

2009-02-23 Thread David Green

On 2009-Feb-23, Jonathan Worthington posted to Rakudo.org:
Applied a patch from bacek++ to get min= and max= working ($foo  
min= 100 will assign 100 to $foo if it's smaller than what is in  
$foo).


Nice -- except I first read that backwards, i.e. even though it  
follows straight from the definition of [op]=, it made me think of  
forcing a minimum value, which would actually be max=.


I can think of a few ways to deal with this:

1) Get used to it.  Maybe document it somewhere to catch fewer people  
off-guard, but otherwise simply expect people to check their code.



2) Override it by defining an explicit infix:min= operator that does  
max=, and vice versa.  People like me will never notice that something  
fishy is going on, but it penalizes the folks who are actually paying  
attention to what min= ought to mean!



3) Avoid the potential for confusion by having another way to set min/ 
max values, such as:

$foo.min = 100;
min($foo) = 100;# lvalue function
$foo = get-foo() :min(100); # adverb on =

I'm not crazy about any of those, but that did suggest what is  
probably a better way to approach it anyway: setting limits at  
declaration rather than repeating them every time the variable is  
assigned to:


my $foo is limited(100..200);
$foo = 5;   # really does $foo = 100



-David



Re: Temporal revisited

2009-02-22 Thread David Green

On 2009-Feb-20, at 7:17 am, Dave Rolsky wrote:
Define really basic math. [...] you could say all math is done in  
terms of seconds, but then there's literally no way to add 1 month.


Oh, I meant only adding or subtracting seconds (as mentioned  
elsewhere); adding a month is certainly advanced enough to require a  
module.



I also think some really basic parsing would be suitable -- no more  
than the ability to understand strings in the same default ISO format  
used for displaying dates and times, e.g.


my Temporal::Date $christmas = 2009-12-25;


As I said in the spec, you _can_ get an observance for a given epoch  
value quite easily. This tells you the offset from UTC, whether DST  
is in effect, and a short name identifier (like CST).


OK, but I wasn't sure how required it was -- shouldn't there be  
something to disallow an undefined observance?  And plain Date or Time  
objects don't have a TZ observance at all.


I can see that a time or date might not have a specific timezone, such  
as Dates for a calendar program; you'd want to be able to highlight a  
certain day, not a range of 24 hours that shifted as you changed  
timezones.  But that's really a floating or lazy local TZ; the zone is  
defined at any given moment, it just might change if the (effective)  
location of the computer changes.


That's still different from having no TZ info at all... although using  
undef to represent that floating value seems reasonable.  I would  
still argue that however it's represented, it should be necessary to  
specify a fixed TZ or some special value for the floating zone.



On 2009-Feb-20, at 10:01 am, Mark J. Reed wrote:
Why can't we just have time() that takes a :tz adverb and dispense  
with gmtime() and localtime()?
If an Instant object also represents a point in time irrespective of  
location, then there's likewise no point in a :tz adverb.


Oh, of course, I was even thinking that the TZ would only be need to  
be specified for times coming from somewhere else.



-David


Re: r25445 - docs/Perl6/Spec/S32-setting-library

2009-02-21 Thread David Green

On 2009-Feb-20, at 11:17 am, Larry Wall wrote:

Certainly, we'll be depending on the type system to keep these things
straight.  I'm not suggesting the user use bare Nums as anything other
than naive durations for APIs such as sleep().


If we have some units to make suitable objects, we can say  
sleep(5`min), etc.  That would mean we can always take time-types, and  
avoid the $t*1000*60*60*24 idiom to boot.


[...]I suppose Temporal is as good a module name as any, though  
Temporal::Instant

does seem a bit redundant...


Well, it distinguishes it from Coffee::Instant...


-David



Re: Temporal and purity (was: Re: IO, Trees, and Time/Date)

2009-02-19 Thread David Green

On 2009-Feb-19, at 4:39 pm, Martin Kealey wrote:
2. Date isa Instant works sensibly: anywhere that expects an  
Instant, you
can give it a Date. (Assuming we all agree that dates start at  
midnight, but

then we *are* talking specifically Gregorian dates.)


I don't like dates just starting at midnight because I've run into too  
many awkward cases where $time  $date doesn't do what you mean  
because it assumes 0:00:00 when you meant 23:59:59.  I'd rather have  
dates becomes time-ranges.


Or perhaps don't make them coercible and require an explicit  
conversion via $date.morning or $date.evening or something.   (Maybe  
require $time ∩ $date or $time ⊂ $date?)



-David



Re: Temporal revisited

2009-02-19 Thread David Green

On 2009-Feb-19, at 11:26 am, Dave Rolsky wrote:
What I want to see in Perl 6 is a set of very minimal roles that can  
be used to provide a simply object from gmtime() and localtime().  
These objects should not handle locales, proper Olson timezones,  
string parsing, user-defined formatting, or math.


Yes; I myself haven't had to worry about leap-seconds before, and may  
very well never have to.  Really basic math is common enough that it  
seems reasonable to include, though.  And we get that by being able to  
numify times, though I'm not sure about officially making time()  
return a Num -- isn't that exposing an implementation detail?  If I  
need an epoch value, I'd expect to have to say $time.epoch or  
$time.epoch(1970) or something.

our Time::localtime(:$time,:tzGMT)


Why can't we just have time() that takes a :tz adverb and dispense  
with gmtime() and localtime()?  I also think that timezones should be  
required, so that it's impossible to have a time and not know what TZ  
it's supposed to be.


If there's no simple enough way to do minimal timezones, then allow  
only GMT (and require using a suitable module to recognise any other  
TZ).  If you really don't care because you know for sure the TZ will  
never matter, say use timezone GMT.  (You may as well not care  
that all the times are GMT in that case.  But if it turns out someday  
that you do care, you can't say you didn't know.)


Or maybe allow any string as a timezone by default.  If all your times  
use the same TZ, that's fine; but as soon as you try to work with two  
times with different zones, you'll get an error, unless you're using a  
module that knows how to convert between those zones.


(While we're at it, why is time zone still officially two words?   
Usually I like to side with the dictionary, but I can't figure out how  
timezone has escaped becoming de facto standard English.)


((I also prefer Instant to DateTime unless we end up using both,  
as in Darren Duncan's suggestion.))



-David



Re: Support for ensuring invariants from one loop iteration to the next?

2008-12-18 Thread David Green

On 2008-Dec-17, at 5:15 pm, Aristotle Pagaltzis wrote:

The way Template Toolkit solves this is far better: the loop body
gets access to an iterator object which can be queried for the
count of iterations so far and whether this is the first or last
iteration.


Well, I prefer a built-in counter like that, but I thought the point  
was that you wanted some kind of block or something that could be  
syntactically distinct?




-David



Re: Support for ensuring invariants from one loop iteration to the next?

2008-12-16 Thread David Green

On 2008-Dec-6, at 7:37 am, Aristotle Pagaltzis wrote:
Funnily enough, I think you’re onto something here that you didn’t  
even notice: [...]
if we had a NOTFIRST (which would run before ENTER just as FIRST  
does, but on *every* iteration *except* the first), then we could  
trivially attain the correct semantics and achieve all desired  
results:


   repeat {
   @stuff = grep { !.valid }, @stuff };
   NOTFIRST {
   .do_something( ++$i ) for @stuff;
   }
   } while @stuff;

The really nice thing about this is that the blocks are nested, so  
that any variable in scope for the invariant enforcement will also  
be in scope in the NOTFIRST block without the user ever having to  
arrange another enclosing scope.


Oh, yes!  So what if we had LOOP $n {} that executed on the nth  
iteration?  LOOP 0 {} at the beginning would be like FIRST {}, LOOP  
* {} at the end would be like LAST {}, and LOOP 1..* {} would give  
us the NOTFIRST block.  Presumably you could have multiple LOOP blocks  
too.


(Actually, you couldn't quite do FIRST/LAST using LOOP $n, because  
FIRST/LAST occur outside ENTER/LEAVE, whereas LOOP would occur  
inside.  But perhaps you could have LOOP blocks inside ENTER/LEAVE  
blocks?)



-David



Re: Support for ensuring invariants from one loop iteration to the next?

2008-12-16 Thread David Green

On 2008-Dec-16, at 6:21 pm, Timothy S. Nelson wrote:
	Or, instead of having a new block, just add the iterator indicator  
to the NEXT block, and get rid of ENTER and LEAVE.  That way, you'd  
have this sequence:

-   FIRST {}
-   NEXT 0 {} # Replaces ENTER
-   NEXT 1..* {} # Does NOTFIRST
-   NEXT * {} # Replaces LEAVE
-   LAST {}

Would that do it?


Not quite -- the idea is that you could put the LOOP block anywhere in  
the body of the loop, and it would execute at that point.  NEXT and  
friends always occur at the end (or beginning) of their block.


Nor would it work to take an existing block like NEXT and allow it to  
be positioned in the middle of the body, because it wouldn't be  
possible to duplicate what they already do -- in this example, the  
NEXT wouldn't get executed when next if something() occurs:


loop
{
next if something();
a;
NEXT { ... }
b;
}



On Tue, 16 Dec 2008, Jon Lang wrote:

How do you compute '*'?  That is, how do you know how many more
iterations you have to go before you're done?


	In some cases, it won't have to be computed, in some cases it won't  
be computeable (which should be an error).  I'd say it'd be fair  
enough to say that 1..(*-1) should be an error in non-bounded(?)  
loops (ie. while).


That sounds right to me.  Does 'for @foo' take a snapshot of @foo, or  
can you change the bounds by changing @foo while the loop is running?   
In which case trying to count back from * might be an error for  
anything except constant bounds.



-David



Re: r24325 - docs/Perl6/Spec

2008-12-15 Thread David Green

On 2008-Dec-14, at 11:21 am, Moritz Lenz wrote:

Uri Guttman wrote:


how is sort ordering specified?
Currently it is not specified, it defaults to infix:cmp. If you  
can suggest a non-confusing way to specify both a transformation  
closure and a comparison method, please go ahead.



how does it know to do string vs numeric sorting?
infix:cmp does numeric comparison if both operands are numbers,  
and string comparison otherwise.


Cmp (like eqv) depends on the particular type, so to sort a  
certain way, you should need only to coerce the values to the right  
type:


@stuff.sort { .Num } # numerically
@stuff.sort { ~ .name.uc }   # stringwise
@stuff.sort { Foo(%x{$_}) }  # foo-wise


I don't know what cmp returns for two values of different types.   
(Failure?)



-David



Re: What does a Pair numify to?

2008-12-15 Thread David Green

On 2008-Dec-15, at 4:18 pm, Jon Lang wrote:
If you've got a list of Pairs, you use a sorting algorithm that's  
designed for sorting Pairs (which probably sorts by key first, then  
uses the values to break ties).


Agreed.

If you've got a list that has a mixture of Pairs and non-Pairs, I  
think that the sorting algorithm should complain: it's clearly a  
case of being asked to compare apples and oranges.


If there's no cmp(Pair, Other::Thing) defined, then it would fall back  
to string-comparison, which seems fair to me.  But complaining isn't  
unreasonable either, since it's easy to coerce stuff to strings if  
that's what you want.


I guess you could force complaining with: infixcmp:(Any, Any) =  
{ die Apples and oranges! }


When are you going to be asked to stringify or numify a Pair?   
Actual use-cases, please.  Personally, I can't think of any.


say $pair;

I can't really think of a great example where you'd want to numify a  
pair, but I would expect printing one to produce something like a =  
23 (especially since that's what a one-element hash would print,  
right?).



-David



Equality of values and types (was Re: how to write literals of some Perl 6 types?)

2008-12-05 Thread David Green

On 2008-Dec-4, at 4:41 pm, Leon Timmermans wrote:
On Thu, Dec 4, 2008 at 6:34 PM, TSa [EMAIL PROTECTED]  
wrote:

And how about 'Num 1.0 === Complex(1,0) === Int 1'?


IMHO the spec on === is quite clear: two values are never  
equivalent unless they are of exactly the same type.


I guess the question is what kind of similarity is the most useful?   
On the one hand, we have values that happen to have the same  
*representation* but different *meaning* (e.g. Weekday::Sun and  
Star::Sun); on the other hand, we have values with a different  
representation but the same meaning (e.g. Int 29 and int8 29).   
Usually the reason for comparing both value and type is to check for  
the same meaning, rather than accidentally equal representations.


So let's imagine a syn operator that checks for the same value and  
the same family:

1 syn 1.0 syn Complex(1,0)
Date '2008-1-2' syn Datetime '2008-1-2 0:00:00'

We can't simply rely on == because my Date and Datetime objects can be  
coerced to numeric values, but they don't mean the same thing as a  
plain Num or Int.  Presumably classes need to indicate their family  
resemblances somehow.


Now, which is more useful?  Is it worth having === and syn?



-David



Re: why infix:div:(Int, Int -- Rat)

2008-12-05 Thread David Green

On 2008-Dec-4, at 3:08 pm, Mark J. Reed wrote:
Using div instead of / should make it pretty clear that you're  
disposing of the remainder.


I misremembered div vs. idiv, but how standard is it?  I know div  
commonly means int division, but not always.  On the one hand, some  
things you just have to learn; on the other, lots of P6 operators have  
word-names as well as symbols, and div is the obvious way to spell  
/ (what else would you call it?).


A way to get both [quotient and reminder] in one fell swoop would be  
nice


Agreed; though having two different operators seems a bit unperlish.   
Int-div could return two values, but that seems prone to accidentally  
interpolating unwanted remainders into lists or things like that.   
Would it make sense to include the remainder as a trait on the  
quotient?  Or return some other special compound type that numifies to  
the quotient.



-David



Re: Support for ensuring invariants from one loop iteration to the next?

2008-12-05 Thread David Green

On 2008-Dec-4, at 9:09 am, Aristotle Pagaltzis wrote:
And while it does seems like a closure trait, that seems somewhat  
problematic in that the order of evaluation is weird when compared  
to other closure traits, which I suppose is what led you to declare  
the “coy” solution as the most natural.



I tried to break down the reasons for wanting to write such loops  
different ways:


1) Simple code -- the coy solution, with the condition checked in  
the middle of the loop, is the cleanest in that if we put the  
condition anywhere else, we still also need to mark where in the  
middle it should be checked.


2) Clear code -- putting the condition up front (or maybe at the end)  
makes it stand out and more clearly identifies the purpose of the  
loop.  Of course, you still need something in the middle as well as up  
front, so you could simply put a comment up front to explain what's  
going on.


3) Self-documenting code -- this is different from the previous point  
(introspection rather than [non-self] documentation...  like my other  
comment about counting iterations -- you can always add $i++; #to  
check for second loop, but then the meaning is accidental rather than  
implicit).
I think this gets at the heart of the problem: not merely making code  
do the right thing, but making it look the right way, making it use  
a natural idiom.  So something like:


repeat using $block
{
something();

check-condition;
# means: last unless $block;

something_else();
}

But I don't really like the need to add the check-condition command.
Maybe something like:

repeat using LABEL
{
something();

LABEL: last unless $block;

something_else();
}


But that still seems too sloppy.  What we need is something a bit like  
the continue block, except that it gets executed before the loop- 
condition is checked the first time.  So what if we split the loop- 
body into two parts?


repeat { something(); }
while ( condition(); )
{ something_else(); }


Now the condition is in the middle and is syntactically separate.   
(It's still not up front, but if the first block is really long, you  
can always... add a comment!)



-David



Re: Support for ensuring invariants from one loop iteration to the next?

2008-12-05 Thread David Green

On 2008-Dec-5, at 7:43 am, David Green wrote:
Now the condition is in the middle and is syntactically separate.   
(It's still not up front, but if the first block is really long, you  
can always... add a comment!)


Well, you don't need a comment -- why not allow the condition to come  
first?


repeat while ( condition(); )
{ something(); },
{ something_else(); }

You need the comma there because the final semicolon is optional, and  
we don't want Perl to think it's an ordinary loop followed by an  
independent block. Probably better is to name the introductory block,  
and then programmers as well as compilers know that something unusual  
is going on:


repeat while (condition)
preamble { something }
{ something_else }



-David



Re: why infix:div:(Int, Int -- Rat)

2008-12-04 Thread David Green

On 2008-Dec-4, at 9:42 am, TSa wrote:

I remember the state of affairs being that [div] returns an Int


Something more explicit like idiv was suggested for integral  
division.  Personally, I'm happy not to have anything special provided  
for it, on the grounds that having to say, e.g. floor($i/$j), forces  
you to be blatantly clear that you're disposing of the remainder and  
how.



-David



Re: how to write literals of some Perl 6 types?

2008-12-03 Thread David Green

On 2008-Dec-3, at 10:18 am, TSa wrote:

Darren Duncan wrote:
Strong typing in Perl means that Perl is conveniently and reliably  
keeping track of this user-intended interpretation of the data, so  
it is easy for any piece of code to act on it in a reasonable way.   
Strong typing lets user code be clean and understandable as it  
doesn't have to do a lot of manual book keeping or error checking  
that Perl can do for it, such as detecting the error of passing a  
character string to a numeric multiplication operator.


First I have a question to the example of the behavior of a string  
in a multiplication. Perl 6 automatically attempts a numerification.  
But does that result in a failure for 'foo' or does that return 0?  
That is, '3' * 3 == 9 is well formed and 'foo' * 3 is malformed,  
right?


That's what I would expect.  A reasonable default would be for  
lossless conversions to happen automatically and lossy ones to throw  
an error.



[...Are Enums === Ints?]
This multi is only allowed if A and B are types distinct from Int  
which to me implies that enums have a WHAT that is not Int. Opinions?


Using int8 vs Int is presumably a performance issue, but int8 29 and  
Int 29 *mean* the same thing, so they should be ===.  An Enum  
doesn't mean the same thing as a plain Int, so it shouldn't.


(As you point out, you can always use something like Weekday::Sun eq  
Star::Sun or Weekday::Sun == 0 if you want string or numeric  
equality.)


A further question is which operators are automatically generated  
for enums. Does

  my Int $a = A::One;
  $a++;
increment from A::One to A::Two or to the Int 2? What shall happen  
when A::Three is incremented? Failure or switch to Int? What happens  
with non-continuous enums? My vote would be to not generate any  
operators


Since ++ works on strings without making them numbers, I think it  
should increment from A::One to A::Two.  But if that's ambiguous, we  
could drop the ++ and stick with .=succ for non-numeric objects instead.




-David



Re: how to write literals of some Perl 6 types?

2008-12-02 Thread David Green

On 2008-Dec-2, at 12:33 pm, Geoffrey Broadwell wrote:

On Tue, 2008-12-02 at 08:50 +0100, Carl Mäsak wrote:

Darren ():

How does one write anonymous value literals of those types?

Why is the latter method [conversion] insufficient for your needs?

Efficiency reasons, among others.


Surely the optimizer will perform conversions of constants at compile  
time.  In fact, numbers and strings have to be converted anyway (from  
a series of characters in the code to a binary int, or whatever).  It  
matters only to the programmer, insofar as we'd like special types to  
get a special syntax -- I'd like that too, but there's a limit to how  
much syntax can be unique or special-looking.  Numbers have a special  
syntax in most languages because they use special characters (Arabic  
numerals), and strings use special quoting characters.  (I think  
Visual Basic uses #1/2/3004# for date-literals.)  Cf.  
Lingua::Romana::Perligata for how Perl might look without special  
symbols.


I can't think of anything significantly better than Set (1,2,3) and  
so on; we could use Unicode symbols, but I don't think that makes it  
any easier or clearer (except for symbols that are already established  
with the required meaning, and the only ones that come to mind are  
braces to indicate sets -- and of course Perl already uses braces for  
something else).



-David



Re: Signatures and matching (was Re: XPath grammars (Was: Re: globs and trees in Perl6))

2008-10-25 Thread David Green

On 2008-Oct-22, at 10:03 am, TSa wrote:

David Green wrote:
One thing I would like signatures to be able to do, though, is  
assign parameters by type.  Much like a rule can look for  
identifiable objects like a block or ident, it would be very  
useful to look for parameters by their type or class rather than by  
name (or position).


Note that types have a fundamentally different task in a signature  
than name and position have. The latter are for binding arguments to  
parameters. The types however are for selection of dispatch target.


Names do that too; I think both names and types should be available  
for both binding and dispatching, depending on what's more natural in  
a given context.  Sometimes we think in terms of names (I'm going to  
Fred's place), sometimes in terms of types (I'm going to the grocery  
store).  (And some types are names (Dad)!)


In single dispatch it is very important if your dispatch is handled  
in the Nail or Hammer class. In multi dispatch one can still  
distinguish action:(Hammer,Nail) from action:(Nail,Hammer). There  
is the following syntax to define two sigs for the same body


   multi method action (Hammer $hammer, Nail $nail)
  |(Nail $nail, Hammer $hammer)


Sneaky, I hadn't thought of doing it that way.  Of course, a mere five  
objects give you an unwieldy 120 possibilities, so some syntactic  
relief is called for.  Perhaps something like an  to indicate that  
the parameters are not sequential:


   sub foo ($posn0, $posn1, Bar $type1  Baz $type2  Bat $type3, : 
$named1, :$named2)




-David



Signatures and matching (was Re: XPath grammars (Was: Re: globs and trees in Perl6))

2008-10-21 Thread David Green

On 2008-Oct-2, at 6:15 pm, Timothy S. Nelson wrote:
The guys on IRC convinced me that the way to go might be something  
like a grammar, but that does trees and tree transformations  
instead of a text input stream.  See the IRC log for details :).

[...]
TimToady note to treematching folks: it is envisaged that  
signatures in a

rule will match nodes in a tree


There does seem to be a clever idea waiting to happen here, although I  
expect signatures will be somewhat simpler since they are intended for  
a more specific purpose.


One thing I would like signatures to be able to do, though, is assign  
parameters by type.  Much like a rule can look for identifiable  
objects like a block or ident, it would be very useful to look for  
parameters by their type or class rather than by name (or position).


For example, if I ask you to hand me a hammer and a nail, I don't need  
you to hand them to me in a specific order, or with labels attached  
like a Dick Tracy comic, in order to know which is which.  That's  
obvious, because, well, one is a hammer and one is a nail.  If I'm  
writing OO-code, then Perl also knows what's a Tool::Hammer and what's  
a Fastener::Nail -- if I know that my $tool is a hammer, and Perl  
knows, then I shouldn't have to spell it out.


The :$foo shortcut for :foo($foo) addresses the same problem, but in  
terms of naming; it is reasonable that a Foo object would be named  
$foo in both the caller and the sub, but not necessary.  Being able  
to use class info that's already there would make it easy to grab  
params when I know the type of object I'm looking for, but not what  
it's called.



-David



Re: Why no is ro? (Re: Subroutine parameter with trait and default.)

2008-09-24 Thread David Green

On 2008-Sep-23, at 5:27 pm, Michael G Schwern wrote:

David Green wrote:
Happily, brevity often aids clarity.  The rest of the time, it  
should be up to one's editor; any editor worth its salt ought to  
easily auto-complete ro into readonly.


Eeep!  The your IDE should write your verbose code for you  
argument!  For that one, I brine and roast an adorable hamster.


Fair enough.  As long as you remember to share with the rest of us!!

That's just another way of saying that your language is too verbose  
for a human to write it without hanging themselves.  See also Java.


But the problem with Java isn't just that it's too verbose to write;  
it's that it's too verbose to read, too.  Why shouldn't your editor  
help with verbosity?  The amount of typing shouldn't be a main concern  
in language design, because your editor can mostly compensate for  
that; there are other, better reasons to decide how verbose something  
should be.


Anyhow, I see where you're going, and I understand the desire for no  
abbvs.  But man, ro is pretty damn easy to remember. [1]  This is  
even sillier when you hold it up against all the magic symbols we're  
supposed to remember.  [EMAIL PROTECTED], :namevalue, |$arg, $arg!, $arg?, : 
$arg.


As a bear of limited recall, I sometimes feel a bit overwhelmed by all  
the stuff there is to remember.  I'm certainly not against all  
abbreviations.  I have a deeply ingrained instinct to name my  
variables x, y, and z, and to name files... x, y, and z.  My shell  
profile is full of one-letter aliases (I don't have time to waste  
typing 2-char command names!).  However experience has taught me the  
value of more robust names for anything but one-liners.


I bet we actually don't disagree much; I'm not really against ro --  
I'm just not against readonly because of its length.  If I were  
writing casually, I'd use rw and ro; formally, I'd use read only  
and read/write (or even readable and writable).  At an in-between  
level, which is where I believe we should be aiming, I think I'd put  
rw and read-only.  I'm not entirely sure why.  Maybe  
psychologically, ro looks like it could be a word, whereas the  
unpronounceable rw has to be an abbreviation?  Or maybe it's just  
because I see rw every day in ls output, but ro not so much.  At  
any rate, if I wanted to argue in favour of ro, I think symmetry  
(which you already mentioned) is the strongest argument.


You're only a beginner once, and if everything is done right for a  
short time.

The rest of your career, you're experienced.


Ooh, now that I completely agree with!  Software that thinks user- 
friendly means dumbed-down drives me nuts.



-David



Re: Why no is ro? (Re: Subroutine parameter with trait and default.)

2008-09-23 Thread David Green

On 2008-Sep-23, at 2:32 pm, Michael G Schwern wrote:
My other thought is that since parameters are read-only by default  
it's not
thought you'd have to write it much so clarity wins out over  
brevity, the flip
side of Huffamn encoding.  But that doesn't work out so good for  
normal

variable declarations.


I'd call it straight Huffman encoding, because clarity is what we  
should be optimising for.  (You read code more than you write it...  
unless you never make any mistakes!)  Happily, brevity often aids  
clarity.  The rest of the time, it should be up to one's editor; any  
editor worth its salt ought to easily auto-complete ro into  
readonly.



-David



Re: Split with negative limits, and other weirdnesses

2008-09-23 Thread David Green

On 2008-Sep-23, at 8:38 am, TSa wrote:

Moritz Lenz wrote:
In Perl 5 a negative limit means unlimited, which we don't have  
to do

because we have the Whatever star.


I like the notion of negative numbers as the other end of infinity.


I think positive values and zero make sense.  But I don't want to give  
funny meanings to negatives; it would be better to replace the int  
limit with a range instead.  (Maybe it would be OK to accept a single  
Int as short for 1..$i, or *-$i as short for *-$i..*.)


Then again, we could get rid of the limit arg altogether, return  
everything, and take a slice of the result -- assuming it can be lazy  
enough to calculate only what ends up getting sliced out.




-David



Re: Multiple Return Values - details fleshed out

2008-08-12 Thread David Green
On 2008-Aug-9, John M. Dlugosz wrote http://www.dlugosz.com/Perl6/web/return.html 
 to clarify and extrapolate from what is written in the Synopses:


Third, list assignment will handle assignment to a literal pair by  
accessing the names of the items inside the Capture. So list  
assignment behaves a lot like binding, but doesn’t do everything  
that parameter passing can do.

[...]
The example seen early on of (:$year,:$mon,:$mday) =  
localtime(time); can be made to work by returning both positional  
and named values. The return signature would need to have twice as  
many items, and the return statement would need to supply each one  
twice.



Couldn't these all work the same way as parameter passing does?  Even  
at the cost of a bit more complexity, it would be simpler overall to  
have only one set of rules to learn.




-David




Re: assignable mutators (S06/Lvalue subroutines)

2008-06-06 Thread David Green

On 2008-Jun-2, at 3:30 pm, Jon Lang wrote:

 sub foo($value?) is rw($value) { ... }

Or something to that general effect.  The parameter in question must  
be optional and cannot have a default value, so that a test of  
whether or not the parameter is actually there can be used to  
determine whether or not to operate like FETCH or like STORE.


I like is rw($value).  There does need to be a way to tell whether a  
value was passed to it, even if that value was undef.  Ah, it just  
occurred to me that rather than checking the $value, you should be  
able to check want~~:($ is rw).



Does this [with no slurpy scalar to pick up the rvalue]:
  sub foo () { ...; $proxy }
give us anything that you couldn't get from:
  sub foo ($rval is rvalue) { ...; $proxy = $rval }

(I'm assuming that both of these subs are rw.)


Yes.  infix:= isn't the only operator that assigns values to rw  
objects: so do the likes of infix:+= and prefix:++.  As well,  
any function that accepts a rw parameter will presumably end up  
writing to it somewhere in its code; otherwise, why declare the  
parameter as rw?


I would expect all of those to work the same way in either case.  That  
is, anywhere the sub is used as an lvalue, it could pass the rvalue as  
a special arg, not just when using =.


Note, BTW, the difference between passing a proxy object as a  
parameter and passing a mutating sub as a parameter: in the former  
case, you call the lvalue sub once in order to generate the proxy  
object, and then you pass the proxy object as a parameter; in the  
latter case, you don't call the mutating sub: you essentially pass a  
coderef to it, and then call it each time the function in question  
attempts to read from or write to it.


OK; but I think that can be handled by a mutating sub -- assuming the  
issue is that the proxy-sub sub foo is rw { blah; $proxy } runs  
blah once and returns the proxy that can be assigned to multiple  
times, whereas a mutating sub would run blah every time you use it.   
But:


sub foo is rw($rval) { unless want~~:($ is rw) { blah }; $unproxy= 
$rval; }


In other words, the mutating-sub-way can do everything the proxy-way  
can (and more), as long as we can tell when being used in lvalue- 
context.


Incidentally, now that Perl is all OO-y, do we need tying/proxying  
like

that, or can we just override the = method on a class instead?
It's possible that in perl6, 'STORE' could be spelled 'infix:=';  
but then how would 'FETCH' be spelled?  And doing so would require  
that your storage routine return a value, even if you never intend  
to use it.  No; I prefer 'STORE' and 'FETCH' as the basic building  
blocks of anything that's capable of working like a rw item.


I agree with that; I'm just pondering whether we need the concept of  
tying any more, or whether FETCH and STORE can be thought of as  
standard methods for any object.  In P5, not everything was an object,  
but everything is in P6 (or can be considered one, if you like  
objects), so it would be simpler to think in terms of one unified  
concept instead of two.


Of course, since subs are objects too, maybe all you need for an  
lvalue-sub is to override the FETCH and STORE methods it already has.   
But then the is rw stuff would simply be syntactic sugar to make  
doing so prettier.



-David



Re: ordinal access to autosorted hashes

2008-06-02 Thread David Green

On 2008-Jun-1, at 11:20 am, Jon Lang wrote:

David Green wrote:
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?


No, that's my understanding too, with the observation that it doesn't  
matter whether there's any sorting going on (so the order might be  
arbitrary -- as in your next point).


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.


Aha -- I guess you're thinking in terms of autosorting that can be  
turned on to return the values ordered by  and .  But .iterator can  
do whatever it wants, which in the default case is presumably to walk  
a hash-table (technically not an arbitrary order, although it might as  
well be as far as a normal user is concerned).  Or you could  
make .iterator return values sorted by alphabetical string- 
representation (which would work for complex numbers), or you could  
make it work by using  and  (which wouldn't work with complexes).


Which doesn't contradict anything you've said of course -- but I'm OK  
with arbitrary orders.  If %h[0] is arbitrary, that's fine.


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.


Do you see that as a psychological aid?  That is, if the order is  
arbitrary, %h[0] makes sense technically, but may be misleading to a  
programmer who reads too much into it, and starts thinking that the  
order is meaningful.


My feeling is that it's fine for all hashes to support []-indexing.   
But if the order isn't important, then you probably wouldn't need to  
use [] in the first place (you'd use for %h:v, etc.)... so maybe it  
should be limited. Hm.



-David


P.S. Everywhere I said  and  I really meant .before and .after.  =P



Re: assignable mutators (S06/Lvalue subroutines)

2008-06-02 Thread David Green

On 2008-Jun-1, at 1:50 pm, Jon Lang wrote:

David Green wrote:
[...] assignment should work like passing args when used on a  
function.  Then you can easily do whatever you want with it.

[...]
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.


The only objection I have to making it a positional parameter is that  
then you can't have other optional positionals before it.  (Also,  
doesn't the '*$value' notation conflict with a possible head of the  
slurpy array?)


I'd rather make it named so it doesn't interfere with other args.  Or  
have it separate from named/positional args altogether; if something  
has a meaning of assignment, then it should always look like foo =  
42 and not like foo(42). (The latter is just an ugly workaround for  
languages with incompetent syntax -- we don't want Perl code to look  
like that because Perl isn't like that.)


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.


Does this [with no slurpy scalar to pick up the rvalue]:

sub foo () { ...; $proxy }

give us anything that you couldn't get from:

sub foo ($rval is rvalue) { ...; $proxy = $rval }



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


Incidentally, now that Perl is all OO-y, do we need tying/proxying  
like that, or can we just override the = method on a class instead?   
Is there something different about it, or is it just an alternative  
(pre-OO) way of looking at the same thing?



-David



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



Re: nested 'our' subs - senseless?

2008-05-06 Thread David Green

On 2008-May-6, at 6:07 am, TSa wrote:

Just to ensure that I get the our behavior right, consider

   sub foo
   {
  our $inner = 3;
   }
   sub bar
   {
  our $inner = 4; # redeclaration error?
   }
   say $inner;

Does this print 3 even when foo was never called?


No, it throws an error about $inner not being declared properly --  
just as in P5 you'd get 'Variable $inner is not imported. Global  
symbol $inner requires explicit package name'.


There's no redeclaration error in bar() because it's declaring the  
name for the first time (in bar's scope, that is), and then  
(re)assigning a value to $inner, which is fine.  If foo said our Int  
$inner and then bar said our Str $inner, that should be an error  
though.



sub foo
{
our $inner = 3;
}
sub bar
{
our $inner = 4;  # fine, assigns or re-assigns $inner
}

say $inner;  # error, name $inner not recognised here

our $inner;  # now the name is available in this scope
say $inner;  # OK, $inner is undef

foo; say $inner; # prints 3

bar; say $inner; # prints 4


IOW, is the assignment in foo a real one that only happens when foo  
is invoked or is it a pseudo-assignment that initializes the  
variables as if the whole statement where outside of foo?


The assignment happens only when foo() is invoked.  However, the  
variable $*Main::inner is declared at compile-time.  Similarly, an  
our sub inner inside foo() would declare the name, but you couldn't  
call inner() until after running foo() --or bar()-- since you can't  
call an undefined sub.




The consequence of a sub not doing Package is that there are
no separate foo::inner and bar::inner classes as in

   class foo
   {
   our class inner { has $.x = 3 }
   }
   class bar
   {
   our class inner { has $.x = 4 }
   }
   say inner.new.x; # error: no inner in scope

My personal idea is to unify class and sub by allowing sub to do  
Package.


I don't understand what a sub doing Package is supposed to do.  I  
think you get the same thing from that last example whether foo and  
bar are classes or whether they're subs: either way, bar will raise a  
redefinition error, and say inner.new.x will throw a no 'inner' in  
scope error.



-David




  1   2   >