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



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



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



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  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 3<4" 
will tempt people to read that like "if 3<4".  (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 "3<4" 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 "?$_ == (foo   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 check boolean conditionals).  
Despite that, it still rubs me the wrong way a little bit.  (I guess it's like 
a picture hanging crooked on the wall — it's not actually hurting anything, but 
once you notice it, it's gonna bug you.)

And there are legitimate, if less common, reasons to expect the more consistent 
behaviour: checking for 'when True' as a catch-all near the end of a series of 
'when's is not unreasonable.  And what I said above about using "if" for Bools 
because there are only two possibilities isn't quite true — since this is Perl, 
there are at least four useful values a Bool can have: true, false, undef, or 
Whatever.  It wouldn't be unnatural to reach for 'when' if you need to 
distinguish those.

I did like "whenever" because it seems to fit well psychologically.  (Your 
psyche may vary.)  But now that I've started thinking of the two issues here 
separately (i.e., breaking out of a block vs a shortcut for $_~~), I'm less 
inclined to make a special case just for "when".  It really would be useful to 
have a $_~~-shortcut that worked with "if", or other places.  My first thought 
was separating the -ever somehow, so that you could say "when ever(3<4)" or "if 
ever (3<4)"; but that means most ordinary 'if's would have to be written 'if 
ever...' which is no good. (Except perhaps for Perl poetry.)

Using "if:" or "when:" with the colon to ind

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

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



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 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 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 C 42> and C cases should never be reachable, since both C<42> 
> and C<"viaduct"> 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 :
>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-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: 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  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 :name or 
:name(value); I don't see any particular reason not to allow --name 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



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



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: 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: 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: 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   
wrote:
On Mon, Oct 19, 2009 at 11:47 PM, Jon Lang   
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: 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-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: 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;}
   } #`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-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 ;# import Bar::foo
use Baz :foo;# 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 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: 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  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: r28727 - docs/Perl6/Spec

2009-10-11 Thread David Green

On 2009-Oct-10, at 11:16 am, pugs-comm...@feather.perl6.nl wrote:
+(However, statement control C notices this and passes no  
argument,

+so C<$_> ends up being bound to the outer C<$_> anyway.)


If "if" will specially handle this case, why not do likewise for @_ or  
%_ and avoid this problem:



+sub say-or-print {
+if $SAYIT {
+say @_; # WRONG
+}
+else {
+print @_;   # WRONG
+}
+}


Or am I merely not yet used to situations where you'd want @_ to grab  
args passed in by "if"?



-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: 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: r28597 - docs/Perl6/Spec/S32-setting-library

2009-10-04 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: r28344 - docs/Perl6/Spec

2009-09-22 Thread David Green

On 2009-Sep-21, at 2:57 pm, pugs-comm...@feather.perl6.nl wrote:

So the preceding example reduces to:
+1, 2, 3 ...
+10, 20, 30 ...
+100, 200, 300 ... 1000
+
+These rules may seem complicated, but they're essentially just  
replicating

+what a human does naturally when you say "and so on".


Oh, nice!  In fact (no surprise) I like all the changes.


-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: 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-19, at 5:53 am, Solomon Foster wrote:

On Sat, Sep 19, 2009 at 6:48 AM, Carl Mäsak  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 ),  
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: [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: Synopsis 02: Range objects

2009-08-27 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 C 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 status, is status, 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: (Any, Interval)
say 5 between [1, 10];
say 5 between 1 .. 10;

say 'aaa' ~~ 'aa' .. 'ba';  # false
say 'aaa' between ;  # 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: Filename literals

2009-08-19 Thread David Green

On 2009-Aug-19, at 4:38 pm, Mark J. Reed wrote:

I don't think $file1.name == $file2.name should talk to the FS,
because I think File#name t+r whatever)  should return a plain Str.


I was thinking === rather than eq might be enough distinction, but  
you're right, confusion is too likely.
Maybe $file1.name ~~ $file2.name?  IO::Filesystem::compare- 
paths($file1, $file2) seems a tad wordy.



On 2009-Aug-19, at 7:06 pm, Timothy S. Nelson wrote:
	Having said that, you've made me realise that $file1 == $file2  
might be the perfect operator for comparing inodes, since inodes are  
numbers.


Isn't that a bit FS-specific?  Since inodes are less commonly used, I  
wouldn't mind making their use more explicit: $f1.inode == $f1.inode.   
Or to be less FS-specific, $f1.id == $f2.id?  Where .id could return  
an inode, an FSspec, whatever is suitable to that filesystem.


	I should've mentioned, though, we're currently using the smartmatch  
operator for this, so I'm thinking maybe I'll just stick with that.


Or $f1.id ~~ $f2.id, since whatever identifier the FS uses might not  
be numeric, yes.



-David




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: 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  
, 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  
represen

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 ;  # 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::Root = "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::Root 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: [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 Ingvoldstad  
wrote:
On Wed, Aug 19, 2009 at 1:54 PM, Moritz Lenz via RT > 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: 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 => ", 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: 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 Bingham> wrote:

2009/8/18 Timothy S. Nelson :

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-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: $*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 Green  
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



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 4:59 am, Carlin Bingham wrote:

2009/8/18 Timothy S. Nelson :
   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



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  
en

$*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: 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



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".




Re: Filename literals

2009-08-16 Thread David Green

On 2009-Aug-15, at 9:22 am, Jon Lang wrote:

IOW, your "outside the file" stuff is whatever can be done without
having to open the file, and your "inside the file" is whatever only
makes sense once the file has been opened.  Correct?  If so, could you
give some examples of how such a distinction could be beneficial, or
of how the lack of such a distinction is problematic?


Well, I definitely think there needs to be a class that combines the  
inside and the outside, or the data and the metadata.  Certainly the  
separate parts will exist separately for purposes of implementation,  
but there needs to be a user-friendlier view wrapped around that.  Or  
maybe there are (sort of) three levels, low, medium, and high; that  
is, the basic implementation level (=P6 direct access to OS- and FS-  
system calls); the combined level, where an IO or "File" object  
encompasses IO::FSnode and IO::FSdata, etc.; and a gloss-over-the- 
details level with lots of sugar on top (at the expense of losing  
control over some details).




In fact, having q, Q, or qq involved at all strikes me as wrong,
since those three are specifically for generating strings.


Pathnames still are strings, so that's fine.  In fact, there are  
different things going on here; one is to have a way of conveniently  
quoting strings that contain a lot of backslashes.  Just as Perl lets  
you pick different quotation marks, to make it easier to quote strings  
that have a lot of " or ' characters, so it should have a way to make  
it easy to quote strings with a lot of backslashes.  (The most obvious  
example being Windows paths; but there are other possibilities, such  
as needing to eval some code that already has a lot of backslashes in  
it.)


Now, you can already turn backwhacking on or off via Q's :backslash  
adverb; Q:qq includes :b (and Q:q recognises a few limited escape  
sequences like \\).  So you could say Q[C:\some\path], and you could  
add scalar interpolation to say Q:s[C:\some\path\$filename].  But  
there's no way to have all of: literal backslashes + interpolation +  
escaped sigils.


Perhaps instead of a simple :b toggle, we could have an :escape  
adverb that defaults to :escape<\>? Then you could have  
Q:scalar:escape("^")[C:\path\with\literal^$\$filename].




The ultimate in "path literals" would be to establish a similar
"default delimiter".  [...]
  `path`.size # how big is the file?  Returns number.


There's something that slightly jars me here... I don't like the  
quotation returning an IO object.  (I like the conciseness, but  
there's something a bit off conceptually.)  Let's see, `exec command`  
bugs me too -- it's quoting something and then doing something with  
the quoted string.  (It's not entirely unreasonable as a cryptic  
shorthand in the shell, but I think P6 should have an actual command  
for that (e.g. the proposed run-gather()).)  Similarly, in this  
example, we're quoting a pathname, and then creating an IO object from  
it.


So I don't like the quoting-and-then-using, when done by the quotation  
marks, although having a function (really, macro) that does its own  
quoting seems fine: "io /some/autoquoted/filename".  And /regex/  
doesn't bother me either.  Hm.  Ah, but an instant regex isn't doing  
anything besides creating an object -- it is comparable to q[foo]  
creating a Str.  So `exec me!` bothers me because it isn't just  
returning some kind of "System::Command" object, it's more like  
creating the object and then calling the .run() method on it too.  / 
pattern/ doesn't *do* anything with the regex.


Now, isn't Q:path[/some/file] just creating an IO object?  Unlike / 
foo/, where "foo" just IS the pattern, "/some/file" is *not* an IO  
object, it's just a filename.  So if the special path-quoting returned  
an IO::File::Name object, I would be perfectly happy.  But you can't  
have $filename.size -- a fileNAME doesn't have a size, the file itself  
does.  To get from the filename to the file, you need another step,  
and it's that extra step I don't like being hidden inside quotation  
marks, just as in the `exec` case.


Anyway, that's a subtle but important point, I think.  Fortunately, in  
the end it doesn't have to work out much differently: instead a "path"  
quoter that does IO-stuff, have a "path" function (macro, whatever)  
that does quoting stuff.


$file = new IO::File(FSNode => "/path/to/file");
$file = path "/path/to/file";
$file = io /path/to/file;
$file = file://localhost/path/to/file;


Incidentally, I do think it's worth having an actual File::Name type,  
even though names are really just strings.  For example, not all  
strings are valid filenames if the FS doesn't handle Unicode.   
However, Strings should get transparently cast to IO::Names wherever  
possible, so the typical user would never have to notice the difference.


IO::Name objects also provide a way to concatenate items correctly, as  
per Hinrik's original post regarding a be

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



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;

$output = $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-13, at 10:25 am, Hinrik Örn Sigurðsson wrote:

I've read a couple of posts about
file test operators, where some have suggested making filenames
special, either as a subtype of Str or something else entirely. That
way Str wouldn't have all these file test methods, which is good
because not all strings are valid filenames.


We should start thinking about the fundamental objects for doing IO as  
IO-objects.  They *have* names, but they aren't names, or strings, or  
even filehandles (although they might *have* filehandles encapsulated  
inside to do the actual work).  A filename is merely a way to get at  
the actual object, just as the string "2009/1/1" can be used to get a  
Date object.  A string, or a handle, or an inode, or some unique  
filesystem spec number, or anything else you can get your hands on  
should be fed to a constructor:


my $file = IO("/foo/bar/qux.txt");

Of course, this being P6, we can have some kind of "io" macro that  
parses the single item after it:


my $file1 = io file://some/dir/some%20file; #  
the quick way
my $file2 = IO.new(:protocol :uri);  #  
the verbose way


The "file:" protocol might be assumed by default, but we could even  
make the protocol keywords into IO-constructor macros:


my $x = file:///some/local/path;# an IO object
my $y = http://perl.org/index;  # another one

(It might even be possible to get away without the protocol, if you're  
willing to start all your regexes with an m and steal prefix / for the  
io-builder:)

use io :default;
$x = /home/me/stuff.txt;   # the lazy way  =P

Then filetests and everything can belong to the IO class where they  
belong, as well as eliminating the need for doublets like "eval" and  
"evalfile".


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.



-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: 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-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 ca

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



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: 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 :without" 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



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: 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: 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: deciphering infix:

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: where the operands are of differing types? Do we  
constrain C 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 > 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



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



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



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 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,:tz)


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 ".  (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: 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: 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-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: 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: 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: infix:(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



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:. 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: 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: 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: 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 
{
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: why infix::(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



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::(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: Support for ensuring invariants from one loop iteration to the next?

2008-12-03 Thread David Green

On 2008-Dec-3, at 12:38 pm, Mark J. Reed wrote:
Overall, the goal is to ensure that by the end of the loop the  
program is in the state of having just
called doSomething(), whether the loop runs or not - while also  
ensuring that the program is in that

state at the top of each loop iteration.

... including the first, just to point out the problem.
[...] I think the cleanest solution is the "coy" one.



Me too.  I don't think having the condition in the middle of the block  
is necessarily a bad thing -- that's how the logic is actually  
working, after all.  Fake conditions like "while(1)" are kind of ugly,  
but P6 has "loop", and you can always make it stand out more:


loop
{
  doSomething();

   #CHECK OUR LOOP CONDITION!
   last unless someCondition;

  doSomethingElse();
}


Now for my own loop-related question: FIRST{} can do something on only  
the first iteration through the loop, but there's no NOT-FIRST block  
to do something on the second and subsequent iterations.  Is there an  
elegant way to do something on all but the first loop?



-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  or , 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 :).

[...]
 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  or , 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], :name, |$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: 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: 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: Multiple Return Values - details fleshed out

2008-08-12 Thread David Green
On 2008-Aug-9, John M. Dlugosz wrote  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



  1   2   >