Re: [perl6/specs] 89cc32: Spec Bag.kxxv
On 2014-April-13, at 11:03 pm, Damian Conway wrote: Spec Bag.kxxv It's a clever name...but maybe too clever? I find it unfortunate that a method that only returns keys has a 'v'in its name. Up to now, we've had a more predictable pattern to naming these accessors. It could be called unpack, because that's what one does to bags. Of course, there's already a $str.unpack, which isn't necessarily a problem, but it would more justified if there were a common concept that could be fleshed out. Different things can get unpacked in different ways, but I'm not sure there's enough of an underlying unification to be made. -David
Floating-point equality (was Re: How to make a new operator.)
On 2012-March-23, at 12:01 am, Damian Conway wrote: [...] we ought to allow for the inevitable loss of significant digits within the two preliminary division ops, and therefore compare the results with an suitably larger epsilon. That would not only be computational more justifiable, I suspect it might also produce more least surprise. ;-) I think that comparisons for floating-point values should take some kind of 'significance' adverb and complain if it's missing. Having to be explicit makes for the least surprise of all. π == 22/7 # error π == 22/7 :within(0.002)# true π == 22/7 :within(0.2) # false Probably with something like 'use epsilon :within(0.0002)' as way to declare the fuzziness for a given scope if you have a lot of comparisons. And of course you could use (the equivalent of) 'use epsilon :within(0)' to say, I know what I'm doing, just give me straight what I ask for and I'll take the consequences. Alternatively, maybe have float-comparisons give an error or warning, and introduce an approximation operator: π == ~22/7 :within($epsilon). (Except ~ is already taken!) [I was going to suggest that as a way to handle stopping points in a sequence: 1, 3, 5 ... ~10, but that still wouldn't work without treating the Num::Approx values as a special case, which defeats the purpose. Though with a postfix up from operator, you could say: 1, 3, 5 ... 10^.] -David
Not-so-smart matching (was Re: How to make a new operator.)
On 2012-March-21, at 6:38 pm, Daniel Carrera wrote: The idea of smart-matching a function just doesn't quite fit with my brain. I can memorize the fact that smart-matching 7 and foo means evaluating foo(7) and seeing if the value is true, but I can't say I understand it. Maybe it just needs a better name. Match implies that two (or more) things are being compared against each other, and that's how smart-matching started out, but it's been generalised beyond that. The underlying .ACCEPTS method suggests acceptance... but that's too broad (a function can accept args without returning true). Agreement fits, in the sense of that [food] agrees with me, but I think it suggests equality a bit too strongly. Accordance? Conformance? Validation? That seems a good match (ahem) for the concept: ~~ checks whether some value is valid (or desired?) according to certain criteria. The obvious way to validate some value against a simple string or number is to compare them; or against a pattern, to see if the value matches; but given a function, you check the value by passing it to the function and seeing whether it says yea or nay. I'm not sure validation or validity is the best name, but it conforms better to what smart-matching does. Or conformance Hm. But terminology that sets up the appropriate expectations is a good thing. -David
Re: pattern alternation (was Re: How are ...)
On 2010-08-05, at 8:27 am, Aaron Sherman wrote: On Thu, Aug 5, 2010 at 7:55 AM, Carl Mäsak cma...@gmail.com wrote: I see this particular thinko a lot, though. Maybe some Perl 6 lint tool or another will detect when you have a regex containing ^ at its start, $ at the end, | somewhere in the middle, and no [] to disambiguate. I think conceptually the beginning and the end of a string feels like a bracketing construct (only without symmetrical symbols). At least that seems to be my instinct. Well, it doesn't in / ^foo | ^bar | ^qux /, but in something like /^ foo|bar $/, the context immediately implies a higher precedence for ^ and $. Maybe something like // foo|bar // could work as a bracketing version? You know, this problem would go away, almost entirely, if we had a :f[ull] adverb for regex matching that imposed ^[...]$ around the entire match. I was thinking of that too. I suspect :full would almost always be associated with TOP, in fact. Boy am I tired of typing ^ and $ in TOP ;-) Does it make sense for ^[...]$ to be assumed in TOP by default? (Though not necessary if there's a shortcut like //...//.) -David
Re: How are unrecognized options to built-in pod block types treated?
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
On 2010-08-02, at 2:35 pm, TSa (Thomas Sandlaß) wrote: On Monday, 2. August 2010 20:02:40 Mark J. Reed wrote: [...] it's at least surprising. I'd expect (anything ~~ True) to be synonymous with ?(anything) Note also that ($anything ~~ foo()) just throws away $anything. No; only if foo() returns a Bool. Do check the section on Smart-Matching in S03 and Switch Statements in S04; the specced behaviour isn't just a mistake. There are only two cases where ~~ ignores the LHS: one is a block that takes no args. A block that takes one arg runs foo($_) (and of course if it takes more args, that's an error), but if the block can't take any args, how would you apply $_ anyway? If you want to compare $_ against its result, then you should call the block instead of using the Callable code object directly. Could someone please give a rational for the interspersing technique given $anything { when $one {...} when two() {...} when $three {...} } where two() returning a true value prevents the case $three. That's the other case that ignores $_: not merely returning a true value, but a Bool (whether that Bool is true or false). Trying to match a literal True or False will warn you, so even if you're surprised by it, you won't be caught unaware. If that's what you really want to do, say ?* or !* (which even happens to be shorter than 'True' or 'False'!). The rationale for ignoring the topic with a non-literal Bool is that when 34 will tempt people to read that like if 34. (Human beings don't interpret context rigidly enough for the Principle of Least Surprise to be consistent!) Saying when /foo/ or when bigger-than(4) obviously call for something to compare against, i.e. the topic, but 34 or foo() $bar *look* like complete conditionals. So people will get it wrong occasionally no matter which way it's specced. However, it's arguably more useful to accept conditions in 'when' without comparing the result to $_ because that is surely the more common case. If you really want something like ?$_ == (foobar) then you can say that — since the result of that expression is itself boolean, when ?$_ == (foobar) will do the right thing. (Instead of really doing $_ ~~ (?$_ == (foobar)), which is almost definitely the wrong thing!) On the other hand, if you do want to see whether $_ is true or not, you'll probably be using if. Given/when is particularly useful if you have a long list of comparisons, so you don't need to repeat a possibly-long topic every time, or even to repeat the $_ ~~ each time. But with if you only need to write the big-long($something.whatever) ~~ once anyway, and the only other possibility is simply else. Now, this does mean that the special case for Bool is best suited for use with 'when'. You're unlikely to expect $foo ~~ (34) to ignore the LHS, I think, simply because if that's what you meant, you would just leave off the $foo~~. You can't do that with a 'when', which is what makes it a useful shortcut there. Maybe such a case could raise a warning. Or why not have the special case apply only to when and not to ~~ in general? Anyway, given an example like Aaron's: if !$dishes-status $dishes-status ~~ $trash-status {...} you would use == instead of ~~, and then there's no problem. Or more likely, write !$dishes !$trash or even none($dishes, $trash). A warning here would certainly help catch cases where you want == or === instead of ~~. given $anything { when $one {...} if two() {...} else { when $three {...} } } still smart match $anything with $three? Or is the topic the return value of two() at that point? No, if two() returns false, then the 'else' is executed with the original topic. (Well, unless two() sneakily changed its parent $_, which, being Perl, is possible.) Now it seems Rakudo breaks out of the 'else' block when $three is true, but then continues with the rest of the 'given' block — I think that's a bug, because it ought to break out of the scope that took $_ as a param, i.e. it should break directly out of the 'given'. I would opt for a regularization of the smart match table. First of all the generic scalar rule should coerce the LHS to the type of the RHS and then use === on them. And that's close to what it does, except when the RHS is something indeterminate like a regex or a range or a type. The Any-Any case just does $_ === $X, which instead could arguably cast $_ to the type of $X first. That might be quite useful, especially if there's a way to tell 'when' to use another operator (like plain ===) when you need it. Apart from that, the Bool cases have been optimised for ordinary use in typical given/when blocks (as opposed to staring at the smart-match table and saying, Why isn't it more consistent??). They are more obviously exceptional used directly with ~~, but also less likely to occur (although to some extent this does rely on having a habit of using ? or == to
Re: Smart match isn't on Bool
On 2010-07-30, at 4:57 pm, Aaron Sherman wrote: given False { when True { say True } when False { Say False } default { say Dairy } } I don't think it's unreasonable to expect the output to be False. However, it actually outputs True. Why? Well, because it's in the spec that way. So... why is it in the spec that way? Well, if you want to do a boolean test, you'd probably use if instead; but something that already gives you a Bool, like when time$limit, is likely to be the result you want to test itself rather than comparing it against $_ (which is likely not to be a Bool). So Perl is trying to be helpful by doing something useful instead of making the useful thing much harder at the expense of something that isn't useful anyway. The catch is that I think that comparing against a boolean IS useful. The fact that this question keeps coming up, even on the p6l list, seems to demonstrate that the helpful way isn't completely natural or obvious (at least, not to everyone). On 2010-07-31, at 1:33 am, Moritz Lenz wrote: sub test() { True }; given 0 { when test() { say OH NOEZ } } I don't think it's unreasonable to expect the output to be OH NOEZ. It's not unreasonable, especially if that's what you expect. But it's even more reasonable to expect this to work: given $something { when True { say That's the truth! } when 42 { say Good answer! } when viaduct { say You guessed the secret word! } } In both these examples, the intent is fairly clear from the context. It's easier to forget that Bools behave differently from other types when you only have some variable that could be any type: if $guess ~~ $answer { say Correct! } # hope your question wasn't T/F! Maybe we can't please everyone, but we can at least try not to displease anyone. Perl is awfully clever at keeping your eaten ponies, and there is a way we can have both the helpful syntax and the consistent one: given $who-knows-what { when True { say It's a true thing! } when 42 { say It's numbery! } whenever timeout() { say Who cares what you say, time's up! } whenever $override { say Whatever, switching to automatic override } } This way (or something similar) is just as clear when reading something in context, but also makes it clear(er) when the context doesn't help (like 'when who-knows()') or when you reasonably expect more consistent matching. [Or do I mean whenever??] -David
Re: Smart match isn't on Bool
On 2010-07-31, at 12:47 pm, Patrick R. Michaud wrote: On Sat, Jul 31, 2010 at 10:56:47AM -0600, David Green wrote: given $something { when True { say That's the truth! } when 42 { say Good answer! } when viaduct { say You guessed the secret word! } } I'm not so sure about this. There's an argument to be made that the Cwhen 42 and Cwhen viaduct cases should never be reachable, since both C42 and Cviaduct are considered true values... Oops, no, I don't want it to do a value-and-type-check. I guess in this case the when True could be moved last, but it's still not a great example. Aaron's example with when True as a fallback at the end of a block is better. [re Aaron's example with: if time $limit { say tick } ] The problem with this formulation is that a successful 'when' exits the block, while a successful 'if' does not. This is one of the significant differences between 'if' and 'when'. It's possible to break out with an explicit leave or succeed. Slightly less elegant, but still straightforward and it doesn't require any exceptions. And it makes the different tests look different. Meanwhile, from one of your earlier replies: The problem is that there are at least two interpretations of a true result of expr: when True { ... }# execute when $_ is exactly True when foo() { ... } # execute when foo() returns true Except that the latter 'when' isn't executed when foo() returns true; only when it returns True! Well, maybe by true you meant Bool::True -- after all, that's a comment, not code; or maybe you were even thinking True and the lowercase T was a typo. At any rate, it confused me for several moments. -David
Re: Smart match isn't on Bool
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
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
On 2010-07-31, at 2:00 pm, TSa (Thomas Sandlaß) wrote: On Saturday, 31. July 2010 18:56:47 David Green wrote: given $who-knows-what { when True { say It's a true thing! } # ^--oops, this still shouldn't come first! when 42 { say It's numbery! } whenever timeout() { say Who cares what you say, time's up! } whenever $override { say Whatever, switching to automatic override } } Am I getting your intention to be that when honors the given and whenever just checks truth? Couldn't we use if for this? That would avoid the new keyword. Right; except that whenever still breaks out, unlike if. I like having a new keyword because it makes it perfectly clear that whenever $foo does not mean the same thing as when $foo (though it suggests something related by having when in the name). However, as suggested in my previous message, we could also distinguish them with something like when vs. when:. The colon there isn't quite a new keyword, but it still is something to make the distinction visible. Plus it allows us to extend the same useful behaviour to if vs if:. -David
Unwanted warnings (was Re: Something wrong with str.reverse)
On 2010-06-18, at 10:48 am, Larry Wall wrote: If you make it the default to not warn, then the people who really need the warnings will almost never turn them on. If you make it default to warn, then people will have to turn off the warnings forever. Doesn't the site-policy policy help here? I could turn certain warnings off in my policy file instead of having to turn them off in every new program. Of course, such settings should arguably apply per-project or per-person-who-wrote-the-code; so maybe any file should adopt settings from a .policy.pm in its own dir, if there is one. Actually, no, it should probably use Some::Policy, but there should be a way for a policy module to identify itself as such so Perl knows whether it should override or be overridden by other policy modules. Also, certain warnings could be suppressed if the code is compiled, on the grounds that compiling the code is a way of saying, I'm finished with this, it all works and I don't expect to be changing it any more. Library modules will presumably be compiled, so that would prevent warnings from code you didn't even write. (Although if a module you installed from somewhere else is full of warnings, maybe you do want to know, hm) 0123; # warns 0123; # ok!# suppresses this warning here 0123; # OK!# suppresses this warning from now on Though I'm hesitant to use comment syntax for that. A statement prefix might be more appropriate. We've currently reserved quietly for simple run-time warning suppression, but that's kinda long, and not defined for compile-time warnings yet. Admittedly, it would be rather amusing to have to shout at Perl 6 to make it shut up: my $x = QUIETLY 0123; Call it sh? (for suppression handler, of course) Using comments doesn't feel quite right to me either, but on the other hand, almost anything else seems distracting for something that is supposed to avoid drawing attention. Maybe a statement suffix? -David
Re: series operator issues
On 2010-07-23, at 4:25 am, Moritz Lenz wrote: I'm still not convinced. [that there should be a special index variable] Yes, it would be convient, but I've yet to see a non-contrived example where it's actually necessary, and which can't be implemented trivially with other Perl 6 tools. I see it like the situation with self. Sure, it's not necessary, it's easy to specify it explicitly, and so on, but nevertheless it feels somehow too heavy not to deserve some sugar. My own first instinct was to use map or a loop to produce those a series of squares or factorials or whatever... on the other hand, the series operator does naturally come to mind when you're thinking about a series! The series code is already rather complex (and thus slow), and having to add introspection to find out whether the production code object accepts a named parameter 'i' is not going to help in any way. I do agree that having a special named parameter isn't the way to do it, though. What if there were a special keyword instead? (Again, like the situation with 'self'.) If you used the word index (or counter or n?) in a loop or series or anywhere else suitable, it could be detected at compile-time. It shouldn't be any worse than making your own counter, and might even be better (since Perl needs its own counter for some loops, maybe it could make it available rather than having to define one of your own as well). -David
Re: Command-line args (weekly contribution to P6)
On 2010-05-26, at 8:52 am, Larry Wall wrote: On Wed, May 26, 2010 at 07:22:36AM -0700, jerry gay wrote: : On Wed, May 26, 2010 at 00:53, Moritz Lenz mor...@faui2k3.org wrote: : sub MAIN(:name(:$n)) : then $n has two names, 'name' and 'n', and we could consider all one-letter : parameter names as short names Presumably you could have :n($name) or :name($n), depending on whether you wanted to use the shorter name in your code, and either way, consider one-letter names as short. Also, it's a bit antisocial to get people used to using certain short switches and then cancel them out when they get ambiguous. I feel that may also apply to having -abc be able to mean -a -b -c or -a=bc. The spec doesn't give a rule, but I'd say combining short switches is the handier shortcut, and just require the = to set a value. (And again, if you need to, you can always parse the params yourself.) That does raise a question of what to do about -vvv. Repeating a switch as a kind of incrementing is a venerable tradition, but it doesn't really get us anything more than -v=3. Also, I assume that when repeating a long name, the last use overwrites any previous uses, so to be consistent, -vvv would mean -v -v -v which would mean simply -v. In which case, is it worth giving a warning to that effect, in case the user was expecting it to mean -v=3? Another detail: the spec mentions exact Perl 6 forms like :namevalue or :name(value); I don't see any particular reason not to allow --namevalue or --name(value) as well. (And it's one less arbitrary difference between --name and :name.) Also, setting any value that contains a comma will get it split. If you don't want a list, you'd have to join the pieces back together (or don't use the default parsing), which seems reasonable to me. However, the splitting could also be limited to params that were declared as arrays. Finally, the spec mentions the usual practice of ending named params at the first positional arg. Of course, some commands continue to process named params either way. For programs like Perl itself, e.g. perl --args --for --perl some-script.pl --args --for --script, continuing past the positional arg would not do the right thing. But is this common enough to be the default? You can always use -- to force positional treatment, but not the other way around. -David
eqv and comparing buts
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
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
On 2009-Dec-3, at 8:42 pm, Jon Lang wrote: but _can_ change existing behavior, but doesn't have to. So with becomes the safe version of run-time composition, guaranteeing that whatever you mix in won't disturb existing behavior, and but becomes the unsafe version that you can fall back on when you need to change said behavior. [...] I suppose you could allow for both, with the default being fail on conflict and an adverb being available to force it to quietly resolve the dispute. Yes; I guess but could have an adverb to control its strictness too, come to that. But not requiring but to change behaviour seems reasonable -- I would read it as but make sure that X, where you want to draw attention to X even though it might technically be redundant. -David
But vs. With
I'm wondering whether we can make use of the contrary sense implied by the word but, and have it apply specifically to cases where something is being overridden. In cases where there isn't something to override we could use a different word, such as with. E.g. $x = Tue but Today; replaces the normal or default Str value of Day::Tue with Today. However, $x = Today with Day::Tue; mixes in a new Day method where none existed before. Saying: Tue with Today, or Today but Tue, could warn you that your expectations are back to front. As well, by allowing the meanings to be closer to the English use of but or with, the code can better suggest its intent. Actually, I'm not sure where is the most practical place to draw the line. Lots of things will have default stringifications, say, that may not always merit the contrary force of but. Maybe but should be needed only when a method has already been mixed in anonymously. So: $x = Tue with Today; $y = $x but Tomorrow. -David
Re: But vs. With
Lots of things will have default stringifications, say, that may not always merit the contrary force of but. Maybe but should be needed only when a method has already been mixed in anonymously. Oops, that would wreck the canonical example of 0 but true. Since the Bool(Int) method already exists, but is indeed the appropriate choice to override it. -David
Re: new enumerations
On 2009-Nov-28, at 1:56 pm, pugs-comm...@feather.perl6.nl wrote: +Fri.name# 'Fri' Since enums are like hashes, why not .key instead of .name? (Also might be less confusing should you happen to have an enum where the keys are numbers and the values are names. (Of course, enum Key(hopeful=A, wild=B, gay=C, triumphal=D, boisterous=E, peaceful=F, serious=G) will be confusing no matter what.)) +3 ~~ Day# True, using Day as a subset of Int Should enums be subsets or subtypes? A subset is a shorthand for certain members of a class, but an enum seems like a way to represent a different kind of thing. Weekdays aren't particular ints the way natural numbers are, and it seems useful to be able to tell that $foo is a Day and not a Month or a Colour. 3 == any(Day.mapping.values) would work if you really want to go by values (a bit more verbose, but the actual values are a kind of implementation detail that the user shouldn't be concerned with most of the time anyway). Or defined Day(3). (At first I wrote ?Day(3), but that wouldn't work if there was value that was false. On the other hand, shouldn't enums typically be true? Does it fit the common case better for enums to start at 1 instead of 0, or maybe start at 0 but true?) -David
Re: unusual invocants
On 2009-Oct-20, at 7:55 am, Matthew Walton wrote: On Tue, Oct 20, 2009 at 2:32 PM, Mark J. Reed markjr...@gmail.com wrote: On Mon, Oct 19, 2009 at 11:47 PM, Jon Lang datawea...@gmail.com wrote: Because a method is part of a role, and ought to abide by the same terms by which the role abides. If Logging doesn't do Numeric, it shouldn't have any methods in it that won't work unless it does. 100% agreed. So what the OP wants to do is declare a method that is available on all those invocants - and only those invocatnts - which do all of roles X, Y, and Z. Granted, you can declare a new role XandYandZ that does X, Y, and Z, and define the method there, but that won't work on $foo unless you declare explicitly '$foo does XandYandZ' . The goal is to have the method show up no matter how $foo comes to do all three roles. Right. This is an interesting idea. Currently, it doesn't work because there's no place for such a method to live, so perhaps there could be a way to declare a method space for arbitrary combinations of roles, a sort of meta-role. It's an odd duck, but it does sort of fall out of the multiple-dispatch semantics, which already let you base implementation chioce on arbitrary combinations of roles... Yes, and while the answer could always be don't do that, the concept doesn't seem particularly strange or undesirable. Maybe rather than hide a Numeric method inside a Logging role where people wouldn't expect to find it, we could do it this way: role Numeric Logging { method log {...} } or something alone those lines. Well, if you could put a where clause on your invocant you could do that... method m($invocant where { $_ ~~ X and $_ ~~ Y and $_ ~~ Z }: Int $a, Int $b) { ... } I would expect $foo where {$_ ~~ X} and X $foo simply to be different ways of writing the same thing, but whatever works! -David
Re: lvalue methods
On 2009-Oct-20, at 8:04 am, Jon Lang wrote: The above example is of course trivial. A more serious example might be one based off of a coordinate system: role point { has Num $x, Num $y; method angle() is rw( { $.x = .r * cos($_); $.y = .r * sin($_) } ) { return atn($.y/$.x) } method r() is rw( { $.x = $_ * cos(.angle); $.y = $_ * sin(.angle) } ) { return sqrt($.x * $.x + $.y * $.y ) } } This strikes me as being much more readable than the current approach of explicitly returning a proxy object. I'd even be fine if the above were treated as syntactic sugar for the creation of a proxy object - And/or some sugar for using special STORE methods on a variable, e.g.: has $angle is set { $.x = .r * cos($_); $.y = .r * sin($_) }; (Well, in this example that makes extra storage space for the $angle attribute which we don't actually want, but there are many cases where an easy way to override STORE is really what is useful rather than an lvalue sub.) But one of the problems with lvalue subs that don't simply return a variable (or equivalently, my is set example) is that you can't say things like temp lvalue() unless temp is receiving an actual variable to work on. In the case where angle() (or $.angle) is changing $.x and $.y, should trying to temporize it do temp $.x and temp $.y as well? Should it be impossible? Can Perl tell whether it should be impossible or not? Does it need to be illegal to change other variables inside a STORE? Meanwhile, the flip side to wanting an easy way to do is set is that often when someone reaches for an lvalue sub, all he really wants is a way to pass an arg to the sub that looks like assignment. For example wanting foo($x) = $y to be a prettier way to write foo($x, $y). This could be handled by, say, having a special rvalue keyword in signatures, e.g.: sub foo($x, rvalue $y?) { ... } foo(42); # $y is undef foo(42) = 24;# $y is 24 foo(42, 24); # syntax error This has the advantage of often doing what people want, and the disadvantage of not working with temp, etc. At least Perl could know that temp isn't allowed to work with such subs, though. On the other hand, something that looks like an assignment ought to work like an assignment, including temp Especially since if you want something that looks more assignment-y than passing a regular arg, we already have a way to do that, namely, using the == syntax to feed args into a slurpy parameter. But in your angle example, we really do want an assignment because the net result is to assign stuff. Perhaps method angle is setting ($.x, $.y) ... to indicate that whatever is done to angle should really affect $x and $y, and any other attributes that aren't specified may not be used. -David
Re: Aliasing methods in CPAN roles
On 2009-Oct-18, at 3:44 pm, Jon Lang wrote: David Green wrote: I would expect that role Logging { method log(Numeric $x:) {...} } means the invocant is really of type Numeric Logging, without Logging having to do Numeric. On the other hand, I can see that strictly that might not make sense, so perhaps I really do need to create a compound NumLog type first, so I can have method log(NumLog:)? I think you should need to do this. That's cumbersome, though. I don't want to create some new type, that happens to do Numeric and Logging (in addition to other stuff it might do); I want to affect everything else that does both roles. That is, I don't want my special log() method to work only for other types that explicitly do NumLog; I want it to work for any type that directly does Numeric does Logging. In fact, I can already refer to that combination without needing to create a compound type; for example, in a signature I can say (Numeric Logging $x:). I want my log() method to apply to $x there, even though it's Numeric Logging and not NumLog. I don't like dangling methods outside of any role though, either. What I want to be able to do is say: role Logging { method log(Numeric $x:) {...} } and have it treat the invocant as something that does Logging (naturally, since it's part of the Logging role), and that also does Numeric (as specified in the sig). It's too reasonable a thing to do not to have a reasonable way to express it. Of course, I could do something like this: role Logging { method log { given self { when Numeric {...} when Stringy {...} etc. } } } that is, I can do the dispatching myself. But I shouldn't have to, especially in cases that are more complex than this simple example. (But I'll suggest something new for - in general: what if $x - Numeric with no $n variable were shorthand for $x - Numeric $x is rw, i.e. a shorthand that used the same variable name inside the block as the one being passed in? That would be useful in cases like this where we don't particularly want to rename $x.) It wouldn't always be workable; for instance, @a - Numeric, Stringy { ... } would grab the first two element of @a and would put them into parameters; but there would be no obvious names to assign to those parameters. Yes, and I think it's OK for a shortcut like that to be available only in simple cases. -David
Re: unusual invocants
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
On 2009-Oct-17, at 1:55 am, Jon Lang wrote: This implies that both Logging and Math do Numeric, since the invocant ought to be of a type that the class does. I would expect that role Logging { method log(Numeric $x:) {...} } means the invocant is really of type Numeric Logging, without Logging having to do Numeric. On the other hand, I can see that strictly that might not make sense, so perhaps I really do need to create a compound NumLog type first, so I can have method log(NumLog:)? Or can I create a method outside of any role: role Numeric {...} role Logging {...} method log(Numeric Logging $x:) {...} (of course, that might be implicitly creating an anonymous compound type for me...) I think that what you're actually looking for (for the purpose of illustration) is Logging::log:(Numeric $x:) and Numeric::log: (Numeric $x:). Oh, yes! If $x does Numeric and $x does Logging, then it has a class that has already encountered the potential conflict and resolved it in some way. For example: class Baz does Numeric does Logging { method log(Numeric $x:) {$x.Numeric::log;} method log(Logging $x:) {$x.Logging::log;} } #`Baz postpones the decision until it knows which role it's being asked to play: Numeric or Logging. Baz illustrates my proposal: if $x is a Baz, it will need to check the context to see if it's supposed to be acting like a Numeric or like a Logging, and will act accordingly - or it will complain about ambiguity if it can't figure out which role to play. And the definition for Baz works because Logging does Numeric. I suppose given that I want Logging's method log(Numeric Logging:) rather than its log(Any Logging:), the second method there should really be: method log(Numeric Logging $x:) {$x.Logging::log;} You cannot define a class that does Logging and does Numeric without defining at least one log method, because they conflict; and a class must somehow resolve all such conflicts. OK; although it seems reasonable to have some sugar for the obvious kind of keep them all methods like in this example. In fact, we probably have that already, by declaring a proto log that makes the others all work according to their sigs. And my mistake was thinking that you could have the same sig doing different things, but really the second sig is log(Numeric Logging:). (The only way to have the same sig twice would be something like if Logging defined a special version of log() for Numeric objects, while Numeric defined a special log() for Logging objects -- but semantically that ought to mean the same thing in both cases, so we do want a single method to handle that.) In the Baz case, it addresses the matter by making two options available according to the role being played: Numeric or Logging. All you have to do then is to somehow indicate which role is being played. If you can't tell by the routine's signature, my own preference would be to make it explicit by means of a given block: given Logging $x { .log } # logs like a Logging given Numeric $x { .log } # logs like a Numeric I also thought given sounded good for this, but it would have to work differently from a normal given: if $x doesn't do Logging, then it needs to skip the block. (Also, it looks very close to casting: given Logging($x). Maybe something a bit more visually distinctive would be helpful, something like given $x as Logging, etc.?) But I could see other alternatives: .log given Logging $x; # assumes the inclusion of a given statement modifier. I think given, as either a modifier or a block, is the prettiest syntax. $x - Numeric $n { ... ; $n.log ; ... } What I like about this is using a sig to apply the context, so no new syntax is needed. (But I'll suggest something new for - in general: what if $x - Numeric with no $n variable were shorthand for $x - Numeric $x is rw, i.e. a shorthand that used the same variable name inside the block as the one being passed in? That would be useful in cases like this where we don't particularly want to rename $x.) $x.log:(Logging:); And I like this way because it's the most compact, inline way to indicate it. -David
Re: Aliasing methods in CPAN roles
On 2009-Oct-16, at 12:54 am, Richard Hainsworth wrote: Is there syntactic sugar for aliasing the conflicting method? Eg. something like does XML :db-writexml-db-write; There needs to be something more than sugar: making a new class or role with different methods will break substitutability. However, we could have a feature which aliases a method name in a given scope or context; elsewhere, the original name would still be visible. So you could pass your new XML-plus-SQL object to do-xml-stuff(XML $x) and it would know to treat it as an XML object with the proper .db-write method. (Incidentally, we could use something similar for renaming imported symbols, though in that case it would be only sugar. Currently, we can choose to import something or not, but if a module exports something, it presumably has a good reason; rather than simply not importing the sub/etc., it would be handy to be able to import it under another name. use Bar foo;# import Bar::foo use Baz :fooboo;# import Baz::foo as boo() use Baz foo='boo'; # or spelled this way ) Moreover, suppose that the two modules have roles with the same name, eg., suppose XML-Database-Module and SQL-Database both define a role 'Writable'. How could these one (or both) of these roles be aliased? I suppose the polite thing would be for them to define roles (or anything else) inside their own namespaces: XML-Database- Module::Writable. Meanwhile, on 2009-Oct-14, at 7:58 pm, Jon Lang wrote: Another clarification: there's a subtle but important difference between $dogwood.bark:(Dog:).() and $dogwood.Dog::bark(). The former calls a Dogwood method that has an invocant that does Dog; the latter calls a Dog method. That is: $dogwood.bark:(Dog:).(); # calls Dogwood::bark:(Dog:) $dogwood.Dog::bark();# calls Dog::bark:() Aha, so the bark:(Dog:) syntax identifies the method by its signature as well, thus distinguishing it from the .bark:(Tree:) method. This works fine when the sigs can distinguish the invocants, which is very common. However, I could have ambiguous methods even including the signatures. Suppose I have a Logging role that provides a log() method for printing some info about a variable. In particular, I have method log(Numeric $x:) { ... } because I want to handle Nums specially (say, round them off before printing). Meanwhile, suppose I also have Math::log(Numeric $x:). If $x does Numeric and does Logging, then $x.log won't be able to decide which method to call, unless maybe it's in a sub like foo(Numeric $x) that can know to provide Numeric context to $x. Outside foo, or inside a sub like bar(Any $x), I need some other way to indicate which log method I mean. $x.log:(Numeric:) won't work here, because both roles provide a method with that name and signature. What if all roles' methods got automatic aliases, to a long(er) name, e.g. the .log method could be referred to as such, or as .Logging`log()? That at least would provide a fully-qualified way to refer to methods no matter where they came from originally, and also allow short names to be used where unambiguous. (I guess this parallels what we already have for subs, etc., except methods would be automatically exported into new roles or classes so that we can use short names. I don't know what the actual syntax should be -- I only used ` above for lack of anything better, since the obvious .Logging::log means something else.) -David
Re: Freezing role methods
On 2009-Oct-14, at 8:52 am, Ovid wrote: --- On Wed, 14/10/09, Jon Lang datawea...@gmail.com wrote: The initial possibility that springs to mind would be to use longnames to disambiguate between the two options - specifically, by means of the invocant: ...or something to that effect. You'd still have a disambiguation issue, in that you'd somehow need to specify which hat an object of class C is wearing when you try to call the method. Good, that's what I was looking for the last time this came up. (http://www.nntp.perl.org/group/perl.perl6.language/2009/07/msg32164.html ) Except that if a consumer of C needs foo(), they have to fully qualify the call to foo(). That violates encapsulation. I don't see that as an encapsulation problem. A leaky encapsulation means we have to know how something works, but when I have to distinguish between $dogwood.Dog::bark and $dogwood.Tree::bark, I'm distinguishing between two wholly unrelated actions (that they happen to have some of the same letters in their names is completely coincidental). So I have to know *what* a Dogwood object does; but I still don't have to know how it does it. Or to look at it the other way around: Since we refer to things by name, those names have to be unique everywhere; so let's start out with long, fully-qualified names everywhere: $dog.Dog::bark(), $tree.Tree::bark(), $i.Int::succ, etc. Now everything's fine -- except that our fingers are getting tired from all that typing. We want to use shortcuts to say things like $dog.bark, because there's only one place that $dog can legitimately find a bark() method, and that's in the Dog class, so both we and Perl can easily figure out what is meant. On the other hand, $dogwood.Dog::bark cannot be simplified by leaving out the Dog:: because then it would be ambiguous. But if we look at it as starting with full names everywhere, and seeing what we can leave out (rather that starting with short names and having to add stuff in), I think it's not surprising. In other cases, there may be no way to implicitly disambiguate. In those cases, there would need to be an explicit way to decide which hat the object is wearing. I really don't think that deferring the decision works. The freezing technique described in the paper allows the consumer, C, to statically bind the method foo() in the methods in the appropriate role which call it. The problem with freezing some methods into private ones is that those methods weren't meant to be private; if my role provides a .bark method, I need to be able to call it. Dynamic binding defers the decision which causes implementation details to leak to consumers of C. This means that if you change your roles, your consumers will potentially need to be rewritten. But if you merely change the implementation of how bark() works (either one), nothing needs to be rewritten. If you want to change from Tree::bark-ing to Dog::bark-ing, then you *should* be rewriting code, because you're completely changing what is going on, no less than if you changed from bark()ing to fetch()ing. -David
Re: Freezing role methods
On 2009-Oct-14, at 2:00 pm, Jon Lang wrote: David Green wrote: On the other hand, $dogwood.Dog::bark cannot be simplified by leaving out the Dog:: because then it would be ambiguous. On the gripping hand, if we have a function train(Dog $d), then we can safely assume that within the lexical scope of train, $d is supposed to be treated as a Dog. So within that lexical scope, it should be safe to leave off the Dog::. Yes; and then my question from last time is whether the sig (Dog $d) soft-casts the arg such that the non-doggy bits of $d still remain, e.g. if inside train() we call a function chop(Tree $t), chop() will unambiguously see the Tree-half of the original Dogwood object. Or will it be hard-cast such that the non-doggy bits are simply lost? (And if so, does an ordinary cast Foo($d) do the same thing, or is one hard and one soft, etc.?) The soft way -- being able to cast $dogwood as a Dog and treat it unambiguously so, then to do the same thing treating it as a Tree object -- is the most flexible. Split-personality Dogs may be rare, but I can imagine wanting to call common utility roles (e.g. Logging) from any point down a calling chain. However, I expect that my Dog $d = $dogwood would strip out everything else, on the grounds that you explicitly requested a pure Dog object. Otherwise you could have said my $d = Dog($dogwood) or maybe my $dogwood.^WHAT $d = $dogwood instead. -David
Re: Parsing data
On 2009-Oct-7, at 5:18 pm, Aaron Sherman wrote: This should be powerful enough to match any arbitrarily nested set of iterable objects. I think it will be particularly useful against parse trees (and similar structures such as XML/HTML DOMs) and scanner productions, though users will probably find nearly infinite uses for it, much like original regular expressions. I agree that being able to parse data structure would be *extremely* useful. (I think I posted a suggestion like that at one time, though I didn't propose any syntax.) There is already a way to parse data -- Signatures, but not with the full power that grammars can apply to text. Data-grammars could do everything that Signatures do, and more, though it's still worth having special syntax designed to fit the special and ubiquitous case of sub signatures. Trying to expand signature-syntax to cover everything grammars can do would probably end up too ugly; nevertheless, if we had full grammars to build on, I'm sure the Sig- syntax could be extended quite a lot before it got too cumbersome. It would also open the way for people to build custom sig-parsers (with their own special syntax or not). It also might be worth inventing a whole new syntax design for parsing and manipulating data structures, but your suggested extensions seem pretty good to me. -David
Re: Overloading Roles
On 2009-Oct-5, at 3:41 pm, Jon Lang wrote: Concerning that last one: would it be reasonable to have a Discrete role that provides a .succ method, and then overload the Range role? I think a type needs to be Discrete and Ordered for successors to make sense (e.g. consider a discrete unordered type like Complex ints). I'm still thinking a Discrete type is the same as a Set; so perhaps Discrete Ordered means Positional? But that doesn't feel right -- although any ordered set can be represented as an array, that seems to confuse the idea of order that is intended. (And perhaps Discrete should be a different type from Set even if they do work out the same, simply to better document one's intent.) -David
Re: r28597 - docs/Perl6/Spec/S32-setting-library
On 2009-Oct-4, at 2:07 pm, Moritz Lenz wrote: Michael Zedeler wrote: It doesn't, because succ should always give the next, smallest possible element given some ordering relation. Where's that definition from? The dictionary. =) It would be confusing to have a successor method for something that isn't orderable and discrete. An ordered continuous type like Real could have .inc and .dec; it just happens that in the common case of Ints, .succ and .inc mean the same thing. Complex could have an .inc method, but I don't think there's any especially obvious choice (because .inc probably wants an ordered type). Would it add 1? or 1+i? Better to spell it out explicitly. Well, Real implies ordering (at least to me ;-), I don't think we have a class or role for countability. A Discrete role would be useful, but is Set good enough for that? -David
Re: [perl #69194] rakudo 2009-08 and when with lists
On 2009-Sep-20, at 12:48 am, Larry Wall wrote: Yes, I think it's fair to say that either list context OR a :by turns a Range into a RangeIterator that matches like a list. Hence, this ought to match: (1,3,5) ~~ (1..5 :2by) OK; but I still have to ask why it returns a RangeIterator instead of a SeriesIterator or any other plain Iterator. Is there some reason to make :by work on Ranges that way instead of being, say, an adverb on ...? I can see that it's obvious and useful to get a list by filling in the values between two endpoints, but that also applies to a pair, or a list of two items. Having :by effectively work like a list at least reduces the confusion in the case of numbers, but we're still left with a puzzle when it comes to strings: Is b ~~ a..az false because it's not the case that a b az, or is it true because expanding the list produces a, b, c, ... ax, ay, az? The former according to spec; but the latter according to someone who expects a parallel with ints. (Apparently Rakudo expects that too, at least for the moment.) Of course, in this case :by doesn't help because there is only one way to increment strings. If we give up the Range/RangeIterator duality, we still have the two different concepts, but I think people will be less tempted to try making them line up together mentally. (Different things should look different.) I don't see that we would lose any functionality (make the :by features work with ...; or keep .. and ... as two ways to make series, and use infix:to for Ranges; or anything else that distinguishes ranges from iterators). What's the big advantage in keeping it the way it is? -David
Re: [perl #69194] rakudo 2009-08 and when with lists
On 2009-Sep-18, at 8:44 am, Moritz Lenz wrote: Aaron Sherman wrote: 2,3 constructs a list. 2..3 also constructs a list, unless it's in a given/when condition in which case it's just a range. No. 2..3 is always a range. It's just list context that turns it into a list. That seems confusing. It sounds like the split personality of Ranges strikes again. I still think it makes more sense to have one Series-only type and one Range- only type, rather than one Series type and one Range-plus-Series type. -David
Re: [perl #69194] rakudo 2009-08 and when with lists
On 2009-Sep-19, at 5:53 am, Solomon Foster wrote: On Sat, Sep 19, 2009 at 6:48 AM, Carl Mäsak cma...@gmail.com wrote: David (), It sounds like the split personality of Ranges strikes again. I still think it makes more sense to have one Series-only type and one Range- only type, rather than one Series type and one Range-plus-Series type. If for no other reason than to contribute a contrasting viewpoint, I'm not sure I see the problem in this case. A range is an object in Perl 6, in a much more palpable way than in Perl 5. This might be what causes the mental mismatch for Perl5-ers. Well, I wonder if the journey from a P5 point of view is the historical reason why we ended up with Range+series .. and Series Otherwise what's the rationale for having Range-:by separate from ...? As far as I can see, the range object already is of your proposed Range-plus-Series type, But that's the problem; I'm proposing there shouldn't be a Range-plus- Series type, because it mixes two different concepts. As a range it works one way (basically representing an ordered pair of endpoints), but if you use :by() it looks like a discrete list... even though really it still is just a Range object. and when I apply list context to the range, I get your proposed Series-only type (which happens to be an ordinary list, but still). I think a Range shouldn't turn into a list, at least not implicitly. Some ranges have an obvious coercion (e.g. a..c becomes a b c), but some don't (e.g. 1..5, which should encompass all nums between 1 and 5, not just the Ints. Unless we distinguish Int(1)..Int(5) from Num(1)..Num(5), which only raises the potential for confusion). The one thing that worries me about this is how :by fits into it all. rakudo: given 1.5 { when 1..2 { say 'between one and two' }; say 'not'; }; rakudo: given 1.5 { when Range.new(from = 1, to = 2, by = 1/3) { makes me very leery. I know :by isn't actually implemented yet, but what should it do here when it is? Exactly: 1.5 is between 1 and 2, but if you're counting by thirds, 1.5 is not in the list(1..2 :by(1/3)). Sure, we can stipulate that this is simply how the rules work, but people are still going to get confused. On the other hand, we can get rid of the list/series/:by part of Ranges without losing any power (move that capability to ... instead), and cut down on the confusion. -David
Re: Synopsis 02: Range objects
On 2009-Aug-27, at 3:11 pm, Mark J. Reed wrote: Given how easy chained relational ops make explicit range checking with endpoints, e.g. $a = $x = $b I'd be perfectly happy with a Range smartmatching only the elements that you get out of the RangeIterator. Yes -- although sometimes that would require separating out the $a and the $b parts, which is why having something to mean between would be handy. On 2009-Aug-27, at 11:08 am, TSa wrote: Note that order is not a prerequisite for a notion of range and range iteration. I think of ranges more like set and set iteration. Except the meaning of the word range and the spec both indicate order: (S03) A star on both sides prevents any type from being inferred other than the COrdered role. Instead, can't the existing series operator take on the series aspects of ..? ... can take a function on the RHS that generates new values, or it can take * to generate an arithmetic or geometric sequence. If only a single value is given as the LHS, it could use .succ, so 1...* or a...* would work like C.. does. I think the reason C... doesn't take a value other than * as the RHS is because of the problem of how to figure out whether the series will ever reach that value or not. But that's easy to figure out in the case of an arithmetic or geometric sequence, so 1, 3, 5 ... 99 should be OK, and 1, 3, 5 ... 100 should probably be an error. Maybe * || 100 as an endpoint could mean go on forever or until hitting this value. Similarly, it's simple to figure out whether .succ applied to strings will reach the endpoint or not. For an arbitrary function, it's not so easy. However, each type could have a you can't get there from here function for figuring out whether an endpoint is part of a series or not; if the endpoint passes that test, then you can use it; if it doesn't, or if there is no such function that can tell you, the only valid endpoint is *. The :by adverb as applied to C... could take a value, which would be added (or handled according to the appropriate type when not dealing with Nums) just like it was with ..; or :by could take a block, which would run that function. So 1 ... {foo} would be short for 1 ... *||Nil :by({foo}). This way all the series stuff is gathered together, and a Range can simply represent a pair of starting and ending points without trying to be a list iterator as well. I expect its main use would be meaning between: $foo ~~ $range. If a Range is not a Series, then there's no confusion as to whether being in the range means being in the series or not. S03: Alternately, we could treat an ellipsis as special when it follows a comma to better support traditional math notation. That seems like an easy mistake to make, so treating it specially would be a good quirk. -David
Re: versioning same-auth forks/branches
On 2009-Aug-26, at 3:54 pm, Darren Duncan wrote: The question I have is what to do when a single same authority wants to release multiple forks or branches of the same module, each presumably targeting a different use case, and the version numbers for each fork/branch are not supposed to be interrelated. We could allow arbitrary components in the name; that would give people as much latitude as they want in making up names and splitting them into pieces that are presumably meaningful to a human. Archives like CPAN could either use the whole name as identification (as long as the full thing is unique), or they could pick particular pieces that they will pay attention to (e.g. name + auth + vers) and ignore the rest. Conventions for other components might evolve over time (e.g. a standard meaning for :branch might become customary); the main use is for documentation and classifying modules so people can search for them, etc.Perl shouldn't care what the name is, long or short, other than having a unique way to identify each module. (We could even have an ID separate from the name, but if the names weren't unique that would be confusing for people too, so I don't see any reason not to keep the long name for that purpose.) Flagging stable vs. dev releases could be done via a designated component in the long name; or it could be a trait on the module (e.g. is statusbeta, is statusdev, etc.). Either way, the info is available so you can instruct Perl not to use any alpha modules, or so on. -David
Re: Synopsis 02: Range objects
On 2009-Aug-24, at 4:17 pm, Daniel Ruoso wrote: Em Seg, 2009-08-24 às 23:50 +0200, Michael Zedeler escreveu: The most elegant solution would be if the data types themselves indicated their capabilities. One thing I think you missed entirely is the fact that the infix:.. operator is a multi sub, so it falls to regular dispatch semantics, But Michael's point was not about what's *possible*, but rather what's *reasonable*. Given that Ranges can act in two ways that lead to inconsistency, it would be less confusing to separate the list-kind from the interval-kind. For certain discrete ordered types, like Int, both ways work out the same, and since Ints are the most common and most obvious use for Ranges, it's easy to overlook the confusion. The case with strings is a good example: it really doesn't make sense that a value not produced by a range nevertheless lies between its endpoints. Why not have a separate Interval type? A Range might get implicitly cast to an Interval by using its endpoints; that leaves us open to the same confusion, although the context would help. # Assuming infix:between (Any, Interval) say 5 between [1, 10]; say 5 between 1 .. 10; say 'aaa' ~~ 'aa' .. 'ba'; # false say 'aaa' between aa ba; # true say 'aaa' between 'aa'..'ba'; # hm... Come to think of it, the word range suggests ordering (like the related word rank), so perhaps Range is the right name for the interval-type, and Series should be the type that produces a series of values that may or may not have an innate ordering. (For example, you could produce a Complex series with: 5+5i .. 10+10i :by(1+1i).) -David
Re: Last IO discussion
On 2009-Aug-19, at 5:00 am, Troels Liebe Bentsen wrote: My idea of working with file names would be that we default to locale or filesystem settings, but give the options of working with paths/file names as binary or a specific encoding. As mentioned in the old thread, encoding is only vaguely related to locale. The problem (or one of them) is that if I create a file today, and then change my locale tomorrow, I end up with a garbled filename. Of course, people don't as a rule change to a different locale every day, but I still think this is a situation where we need to put the onus on the user. That is, either Perl can determine the encoding (e.g. because the filesystem indicates it in some way), or else the user needs to pick one explicitly. If you get a list of files from reading a dir, and don't need to display the names or anything, you might get away with treating them as undistinguished bytes; but as soon as Perl does anything that needs an encoding and one hasn't been specified, it should complain bitterly. It's the same reasoning why I think specifying a timezone should be required: it's not that much work for the user to add use IO::Encoding $volume = utf-8, and at least that way naive users will be alerted to the fact that something's going on. It's up to them how much effort they think is worth devoting to the issue, but at least they will be warned that there's an issue there to grapple with. -David
Re: [perl #64566] @a[1..*] adds trailing undef value
On 2009-Aug-19, at 8:07 am, Jon Lang wrote: On Wed, Aug 19, 2009 at 5:37 AM, Jan Ingvoldstadfrett...@gmail.com wrote: On Wed, Aug 19, 2009 at 1:54 PM, Moritz Lenz via RT perl6-bugs-follo...@perl.org wrote: It doesn't mention how the postcifcumfix:[ ] is supposed to introspect those to find out if the WhateverCode object constructed by 1..* needs to receive self.elems or self.elems-1 as an argument. The * can tell when it's in a range, and set some range-flag on the resulting object, right? Then .[] will test for $whatever.range- flag. Or am I missing the point? Given that it's relatively easy to say 1..^*, I wouldn't mind standardizing this so that '*' always refers to the element just past the last one, at least when dealing with the standard index. I like the DWIMmery, but the more I think about it, for such a little difference, it seems more worthwhile to be consistent than to be DWIMy. So, yes, either * always means last+1, and use 1..^*, or make * mean the last index, and use [*+1] to append. But there is a problem with sparse arrays, isn't there? Sparseness is an implementation detail. Arrays all look the same to the user; sparseness just means perl is smart enough to do @foo[1]=$bar without trying to suck up a zillobyte of RAM. -David
Re: directories of interest, a multiplicity alternative to CWD
On 2009-Aug-19, at 2:08 am, Darren Duncan wrote: %DOI{'mycwd'} = %DOI{'fscwd'}; %DOI{'mycwd'} ~= 'subdir'; # later my $fh = IO.open( 'mycwd/myfile.txt' ); For ease of use, we can still have vars like $*CWD, which might be an alias for a doi with a specific name. I've been thinking of something similar, but you should be able to do this with any directory object. my $dir = $*CWD; # returns an IO object, not merely a string my $dir ~= subdir; # $dir is now an object representing the subdir my $file = io $dir/filename; { temp $*CWD = $dir; ... } So the set of default standard dirs would just be a hash of IO objects: $IO::DOI{home}, $IO::DOI{docs}, etc. Actually, different OS's would provide different sets of standard named dirs, and you should be able to import them: # Assume I'm running on a Mac, so $IO::DOI::MacOSX is automatically loaded use IO::DOI Home Music Downloads; # names that ::MacOSX makes available say $Home; # /Users/david say $Music;# /Users/david/Music say $Downloads;# /Users/david/Junk drawer There will be a few names that should be standard as much as possible across OS's, e.g. Home even though on a Mac the dir is actually called Users. Trash might be another one (which will be undef if the OS doesn't handle it). This doesn't address the security side of things; dir objects might have a flag you can set so that it will warn you (perhaps fatally) if you try to use $dir.parent or $dir/.., etc., but you could always get to an outside dir some other way. I think a more explicit way to set a chroot is better, such as: $IO::Root = $*CWD; $IO::Root = $Home; temp $IO::Root = $IO::DOI{Docs}; Similarly, if a Perl thread does not see any DOI at all, then they effectively are denied access to the filesystem period. Hm, undef $IO::Root? Of course, that still doesn't cover everything your suggestion does, because your way allows for multiple roots. But you also weren't suggesting a specific syntax, and I'm leaning to something like my example above. Perhaps along the lines of: $IO::Root{file} = /; # default root (assumes file://) $IO::Root{http} = http://;; # means any website $IO::Root{ftp} = ftp://;;# etc. Every time you use IO::Some_protocol_name, it would set a default $IO::Root{protocol-name}. But there's nothing special about the names; you can add or change $IO::Root as you wish. $IO::Root{file} = /foo; $IO::Root{more files} = /bar; # Now can access only files that come under /foo or /bar $IO::Root$_.delete for «file more files»; # Now there are no more file:// roots, cannot access any files $IO::Roothttp = http://localhost/~david/;; # Now can access only URLs from my section of the local website Hm, having just written that, it obviously should be the case that $IO::Rootfile should be a hash with all the available file: roots, i.e. $IO::Root is a hash-of-hashes where the keys are {protocol-name} {arbitrary-name}. And the default arbitrary-name might just be default. -David
Re: Filename literals
On 2009-Aug-18, at 7:20 am, Timothy S. Nelson wrote: On Tue, 18 Aug 2009, David Green wrote: Some ways in which different paths can be considered equivalent: Spelling: ... Simplification: ... Resolution: ... Content-wise: ... Ok, my next commit will have canonpath (stolen directly from p5's File::Spec documentation), which will do No physical check on the filesystem, but a logical cleanup of a path, and realpath (idea taken from p5's Cwd documentation), which will resolve symlinks, etc, and provide an absolute path. Oh, and resolvepath, which does both. I'm not quite sure I followed all your discussion above -- have I left something out? I think there's a difference between canonical as in a webpage with link rel=canonical, and cleanup as in Windows turning PROGRA~1 into Program Files. There could also be other types of normalisation depending on the FS, but we probably shouldn't concern ourselves with them, other than having some way to get to such native calls. Anyway, my assumption is that there should be a number of comparison options. Since we do Str, we should get string comparison for free. But I'm expecting other options at other levels, but have no idea how or what at this point. As Leon Timmermans keeps reminding us, that really should be delegated to the OS/FS. I think $file1 =:= $file2 should ask the OS whether it thinks those are the same item or not (it can check paths, it can check inodes, whatever is its official way to compare file-thingies). Similarly, $file1.name === $file2.name should ask the OS whether it thinks those names mean the same thing. And if you want to compare the canonical paths or anything else, just say $file1.name.canonical === $file2.name.canonical, or use 'eq', or whatever you want to do, just do it explicitly. According to my last commit, p{} will return a Path object that just stores the path, but has methods attached for accessing all the metadata. But it doesn't do file opening or things like that (unless you use the :T and :B thingies, which read the first block and try to guess whether it's text or binary -- these are in Perl 5 too). There are two things going on here: the user-friendly syntax for casual use, which we basically agree should be something short and pithy, although we have but begun to shed this bike, I'm sure. $file = io /foo/bar; $file = p{/foo/bar}; $file = Q:p/foo/bar/; $file = File(/foo/bar); However we end up spelling it, we want that to give us unified access to the separate inside parts: IO::Data# contents of file IO::Handle # filehandle for using manually IO::Metadata IO::Path I'm not sure why Path isn't actually just part of IO::Metadata... maybe it's just handy to have it out on its own because pathnames are so prominent. In any case, $file.size would just be shorthand for something like $file.io.metadata{size}. The :T and :B tests probably ought to be part of IO::Data, since they require opening the file to look at it; I'd rather put them there (vs. ::Metadata, which is all outside info) since plain ol' $file abstracts over that detail anyway. You can say $file.r, $file.x, $file.T, $file.B, and not care where those test live under the hood. We might actually want to distinguish IO::Metadata::Stat from IO::Metadata::Xattr or something... but that's probably too FS- specific. I don't think I mind much whether it's IO::Path or IO::Metadata::Path, or whether they both as exist as synonyms I think we want many of the same things, I'm just expressing them slightly differently. Let's keep working on this, and hopefully we end up with something great. Yes. A great mess! Er, wait, no And there's no perfect solution, but it would be useful for Perl to stick as closely as the FS/OS's idea of types as it can. Sometimes that would mean looking up an extension; it might mean using (or emulating) file magic; it might mean querying the FS for a MIME- type or a UTI. After all, the filename extension may not actually match the correct type of the file. My suggestion would be that it's an interesting idea, but should maybe be left to a module, since it's not a small problem. Of course, I'm happy to be overruled by a higher power :). I'd like the feature, I'm just unsure it deserved core status. Well, it's all modules anyway... certainly we'll have to rely on IO::Filesystem::XXX, but I do think this is another area to defer to the OS's own type-determining functions rather than try to do it all internally. What we should have, though, is a standard way to represent the types in Perl so that users know how to deal with them. I think roles are the obvious choice: if the OS tells you that a file is HTML, then $file would do IO::Datatype::HTML, which means in turn it would also do IO::Datatype::Plaintext, and so
Re: Custom object constructors
On 2009-Aug-19, at 4:37 pm, Kevan Benson wrote: I'm aware there's a default constructor that allows named parameters to be set, but I think the usefulness of allowing specific constructors that take defined parameters and initialize the object as needed should not be overlooked. E.g. my DateModule $d .= new('2007-03-12'); My first thought is also coercion: say my DateModule $d = '2007-03-12' and let DateModule::.(Str) worry about making the new object. (Or does that need to be my DateModule $d = DateModule('2007-03-12')? That seems unnecessarily redundant.) -David
Re: r28017 - in docs/Perl6/Spec: . S32-setting-library
On 2009-Aug-18, at 2:29 am, Carlin Bingham wrote: chdir provides functionality that would be quite convoluted to mimic through manually setting $*CWD, such as changing to a relative directory. Maybe setting $*CWD just calls chdir() under the hood? Same implementation, brand new shiny Perl-style interface! -David
$*CWD and chdir()
On 2009-Aug-18, at 3:27 am, Timothy S. Nelson wrote: On Tue, 18 Aug 2009, David Green wrote: Maybe setting $*CWD just calls chdir() under the hood? Same implementation, brand new shiny Perl-style interface! That was my intent, but we had some discussions on IRC about the whys and wherefores, and it will return as soon as I do my next commit (hopefully sometime within the next 4-5 hours). Unless you can think of a good way to do relative paths. In my naiveté, I would do: class IO::CurrentDir; # the type of $*CWD sub STORE($self: IO::Path $new) { chdir($new); $self = getcwd(); } or however that would work in P6. It may have problems, but by definition they're the same problems as chdir() has. What am I missing? On 2009-Aug-18, at 3:12 am, Jan Ingvoldstad wrote: It may seem cool, but I don't like secondary effects like that. They break the principle of least surprise. It doesn't seem that surprising to me, especially after seeing the docs the first time. Are there environments where you can set a variable like $*CWD and it doesn't do something like chdir? (And we can always keep chdir() as well, so old dogs aren't forced to learn new tricks.) On 2009-Aug-18, at 3:52 am, Mark J. Reed wrote: If $*CWD is really a Path object and not a Str, then it should be easy to use mutator methods to change to a relative directory and do other chdir()ish things. Say, concatenation works in terms of path components, for instance: $*CWD ~= $subdir; # chdir($subdir) Yes. Though $*CWD = subdir should also work; subdir is not the same path as /subdir, so it knows whether you're assigning a relative path or not. Or rather, our path-type would know, and implicitly prepend the current dir when it parses/forms the actual pathname, so $CWD would effectively get a fully specified path every time. With a method for getting the parent: given $*CWD { $_ = $_.up ~ $sibling } # chdir(../$sibling) I like that. and so on. My favorite kshism is cd old new which does a search/replace on the current working directory; the bash equivalent cd ${PWD/old/new} which is not quite as handy. $*CWD could make that simple, too. Ditto. -David
Re: Filename literals
On 2009-Aug-17, at 8:36 am, Jon Lang wrote: Timothy S. Nelson wrote: Well, my main thought in this context is that the stuff that can be done to the inside of a file can also be done to other streams -- TCP sockets for example (I know, there are differences, but the two are a lot the same), whereas metadata makes less sense in the context of TCP sockets; But any IO object might have metadata; some different from the metadata you traditionally get with files, and some the same, e.g. $io.size, $io.times{modified}, $io.charset, $io.type. if (path{/path/to/file}.e) { @lines = slurp(path{/path/to/file}); } (I'm using one of David's suggested syntaxes above, but I'm not closely attached to it). I suggested variations along the line of: io /path/to/file. It amounts to much the same thing, but it's important conceptually to distinguish a pathname from the thing it names. (A path doesn't have a modification date, a file does.) Also, special quoting/escaping could apply to other things, not limited to filenames. That said, I don't think it's unreasonable to want to combine both operations for brevity, but the io-constructor should have built-in path parsing, not the other way around. I guess what I'm saying here is that I think we can do the things without people having to worry about the objects being separate unless they care. So, separate objects, but hide it as much as possible. Is that something you're fine with? Yes -- to me that means some class/role that wraps up all the pieces together, but all the separate components are still there underneath. But I'm not too bothered about how it's implemented as long as it's transparent for casual use. my $file = io p[/some/file]; my $contents = $file.data; my $mod-date = $file.times{modified}; my $size = $file.size; Pathnames still are strings, so that's fine. In fact, there are different As for pathnames being strings, you may be right FSVO string. But I'd say that, while they may be strings, they're not Str, but they do Str Agreed, pathnames are almost strings, but worth distinguishing conceptually. There should be a URL type that does Str. Actually, there are other differences, like case-insensitivity and illegal chars. Unfortunately, those depend on the given filesystem. As long as you're dealing with one FS at a time, that's OK; it probably means we have IO::Name::ext3, IO::Name::NTFS, IO::Name::HFS, etc. But what happens when you cross FS-barriers? Does a case- sensitive name match a case-insensitive one? Is filename-equality not commutative or not transitive? If you're looking for a filename foo on Mac/Win, then a file actually called FOO matches; but on Unix it wouldn't. (Actually, Macs can do both IO::Name::HFS::case-insensitive and IO::Name::HFS::case-sensitive. Eek.) I'd like Perl 6's treatment of filenames to be smart enough that smart-matching any of these pairs of alternative spellings would result in a successful match. So while I'll agree that filenames are string-like, I really don't want them to _be_ strings. Well, the *files* are the same, but the pathnames are different. I'm not sure whether some differences in spelling should be ignored by default or not. There are actually several different kinds; S32 has a method realpath, but I think canonical is a better name, because aliases can be just as real as the canonical path, e.g. a web page with multiple addresses. Or hard links rather than soft links -- though in that case, there is no one canonical path. It may not even be possible to easily tell if there is one or not. Some ways in which different paths can be considered equivalent: Spelling: C:\PROGRA~1, case-insensitivity Simplification: foo/../bar/ to bar/ Resolution: of symlinks/shortcuts Content-wise: hard links/multiple addresses Depending on the circumstances, you might want any of those to count as the same file; or none of them. We'll need methods for each sort of transformation, $path.canonical, $path.normalize, $path.simplify, etc. Two high-level IO objects are the same, regardless of path, if $file2 =:= $file2 (which might compare inodes, etc.). There should be a way to set what level of sameness applies in a given lexical scope; perhaps the first two listed above are a reasonable default to start with. There's something that slightly jars me here... I don't like the quotation returning an IO object. But doesn't normal quoting return a Str object? And regex quoting return an object (Regex? Match? Something, anyway). Certainly, but a regex doesn't produce a Signature object, say. I don't object to objects, just to creating objects, then doing something with them, then returning another kind of object, and calling that parsing. If we're parsing the characters, we should end up with an IO::Name. If
Re: $*CWD and chdir()
On 2009-Aug-18, at 4:59 am, Carlin Bingham wrote: 2009/8/18 Timothy S. Nelson wayl...@wayland.id.au: It's not in the revised spec, but I think that, even though we've revived chdir, we should still have it so that changing $*CWD will do a chdir under the hood. While in the spirit of TIMTOWTDI, having a magic variable that behaves differently from other variables when it's being set would be rather odd. But really, it isn't different After all, a current path IS just a string; it's a string that shells helpfully insert for you at certain points to save you some typing. The automatic insertion may be magical, but the string itself is quite ordinary. The metaphor of being in a directory is quite fascinating, really. Directories are not something you can be in -- they're lists that hang on the walls of office buildings, or get printed on the pages of a phone book. They're pointers, dir-ections to where you can find something -- an office, a telephone, or a file on a disk. Literally *on* the disk, not in it (disk platters are flat!). But this image of working in a directory seems to come quite easily and naturally. It wouldn't seem magical if we always wrote like this: ls $PWD/foo/bar PWD = $PWD/foo ls $PWD/bar That would still save a lot of typing, but not having to type the $PWD saves even more. But perhaps the apparent magic is that $*CWD = /foo sets the CWD to /foo, but setting it to foo does not set the CWD to foo, but rather to $OLDCWD/foo. But that's not $*CWD's doing, that's our path-quoting. ~ p[/foo/bar] eq /foo/bar# path literal cast to Str ~ p[foo/bar] eq $CWD/foo/bar Not so strange to anyone familiar with the idea of relative paths, and no more magical than... say, the fact that a literal series of digits gets parsed as though it had an implicit 0d in front of it. (Of course, I suspect that $*CWD should be able to be set to a plain Str, but the Str will be cast to an IO::Path because that's what $*CWD.STORE() will take in its signature.) -David
Default path restrictions
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()
On 2009-Aug-18, at 5:48 am, Jan Ingvoldstad wrote: On Tue, Aug 18, 2009 at 1:02 PM, David Greendavid.gr...@telus.net wrote: It doesn't seem that surprising to me, especially after seeing the docs the first time. Are there environments where you can set a variable like $*CWD and it doesn't do something like chdir? Yes, and that's normal and expected behaviour. Huh. Thank you, I did not know that. It makes sense (in that I understand what's going on now that I see it, and indeed it seems almost obvious), but I certainly couldn't call it expected because I didn't. And I can guarantee I'm not the only one; in fact, I have no qualms about classifying that as a bug. -David
Re: S26 - The Next Generation
On 2009-Aug-18, at 3:29 am, Jan Ingvoldstad wrote: In general, executable documentation is a bad thing. It's been shown to be a bad thing many times over. Well, tons of programs have --help options, which could be considered executable documentation, and it's very useful. Emacs brags about being self-documenting. It's worth it because it's more work the computer can do instead of humans (and often do a lot better). It's annoying when a printed book says the default setting is $foo when it isn't because somebody changed the defaults, or the config file is at $some/$path when it isn't because it was installed using a non-standard layout -- but it's understandable, because there's not much you can do about that. It's a lot more frustrating when you're looking at docs on a programmable computer that actually knows the real settings/paths/etc. and *could* tell you, but doesn't. But it's a lot more than that: although it can help the end-user, it also helps authors. I can weave together my (il)literate POD in the most convoluted way Pod6::Order::Labyrinthine can handle. I can have it pull values out of my code so that's impossible for the docs to get out of date because I forgot to change them. That's still a big help even if my end users look only at a static copy of the docs once they're produced. If we absolutely must have some sort of executable documentation, then if I could, I would insist that it wouldn't be a feature complete language. That is: absolutely no IO in the language, no way of executing code that's foreign to the doc, and so on. Well, perl-doc can't run any POD-executing modules that never get installed. But surely it's possible to forbid IO, no? Disallow any actual IO functions, as well as anything that could be used to sneak them in (eval). I guess you'd want to allow Perl itself to load installed modules (but maybe nothing from the current dir, or outside the official library location). Having perl-doc run in lock-down mode, or run in display-precompiled-static-file-only mode by default might be a good idea, though I'm not convinced it's completely necessary. -David
Re: r90210 - in docs/Perl666/Spec: . S0S-upsetting-library
On 2009-Aug-18, at 7:05 am, Mark J. Reed wrote: On Tue, Aug 18, 2009 at 6:59 AM, Carlin Binghamcar...@theintersect.org wrote: 2009/8/18 Timothy S. Nelson wayl...@wayland.id.au: On Tue, 18 Aug 2009, Mark J. Reed wrote: It's not in the revised spec, but I think that, even though we've revived chdir, we should still have it so that changing $*CWD will do a chdir under the hood. You're quoting the wrong person. That wasn't me. Technically of course, he quoted Tim quoting you without any of the double-quoted material but with the quoted attribution referring to your non-quoted quote. I wish e-mail programs were smart enough to catch when somebody's text has all been snipped out but the dangling attribution hasn't. Hey, what if P6 had built-in mail software that used a Grammar to analyse messages and store the nested levels in a Tree structure -- we could have a special A: quoting mechanism for literal attributions, and maybe some variations like aa: to allow for interpolated names, or a:dates to parse -MM-DD, etc. as automatically inserted date formats. On could be a special macro so you don't even need quotes around an attribution line. Oh, and people use different languages to say On $date, $foo wrote, but that's pretty easy to fix: just include a working version of babelfish.com (it's just a few textareas -- you could probably whip it up in a day using Catalyst). Plus it should disallow / \ ? * $ @ % ☹ unless preceded by (##`=☞, and not run any executable code when you're looking at it. And there's a magic plural-\s (s/://g), but it works only if the attributee is Larry Wall. -David is it bedtime yet? Green
Re: S26 - The Next Generation
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
On 2009-Aug-16, at 2:26 pm, Damian Conway wrote: It's Sunday evening and, as promised, here's the new draft of S26. Yay! (To the contents, that is, not to the posting of it. Well, to the posting too, since otherwise it would have been much harder to read.) Perl that accesses $=POD and/or the .WHY and .WHEREFORE methods My favourite part is that it's actually called WHEREFORE. (Take that, all-other-programming-languages!) Hopefully this is something close to the final draft...and something that every stakeholder and faction in this long discussion can dislike equally. ;-) I like it very much. But don't worry, I'll think of something to quibble about! -David P.S. to format it using perldoc2xhtml, I had to change the =begin item at line 589 to =for item.
Files and IO and all
On 2009-Aug-14, at 4:34 am, David Green wrote: There's a lot of scope for a nice, friendly, high-level IO view; perhaps we need an IO-working group to assemble knowledge about what is and isn't possible with different filesystems and design an interface around it all. It won't be possible to unify every different FS function, but it can keep the basics (like open) as consistent as possible across platforms, and provide idiomatic Perl expressions so everything at least tries to feel perlish. Some things may simply be impossible to manage transparently (like filenames with no identifiable encoding), but even having an organised way to identify the possible problems will be helpful. (A lot of similar issues apply to databases, despite which -- or because of which -- it's so nice to have the DBI project.) All the low-level features have to be there, of course, to open files and seek through them, etc., etc., but Perl is not a low-level language; we have (in P5) the magical , but the easy way to deal with files should always apply (that is, be available anywhere you don't absolutely need to manipulate low-level details). The idea is to treat files as data, because that's what we're really interested in: their contents, not all their surrounding metadata. If you're writing a file-manager, then you need lots of FS-specific detail; in fact, you probably don't care about the contents of files but only their metadata. However, it's more usual to care only about the contents and use a bit of metadata (like the name) merely as a way to get the contents. The high-level interface shouldn't be concerned with file handles or pointers, but simply with files, and not even as concerned with files as with *data*. In other words, the focus should be on a data-structure, not on the file itself. A text file is really just a way to store a string; an XML file is a way to encode and store a structured tree object. my Str $poem = io file://jabberwocky.txt; my Image::JPEG $camel = io file://dromedary.jpg; my XHTML::Doc $x is readonly = io http://foo.org/a%20doc; Then you simply work with your string, or tree, or image-object. An XHTML::Doc object, for instance, would really contain nodes, but it would know how to encode or decode itself as a series of plain-text tags for reading or writing to disk. The old-fashioned way to handle this is to open the file, get a filehandle, read the filehandle into a string, take the string[s] and XHTML::Doc-parse() them. The new way would be to have the parse(Str) method be how XHTML::Doc objects do the IO::input() role, and the IO class takes care of the opening and reading behind the scenes. Anything could mix in the basic IO role so that an object can load or save itself. Different data structures would override the necessary methods to format the data the right way. The type of IO object would determine how metadata works (i.e. whether it's a file or an HTTP stream or a directory, etc.). Objects would handle other functionality in whatever ways make sense for that object. For example, iterating a plain-text file would split it into lines. (This suggests that maybe ordinary Strings could split into lines in @-context? Hm.) A Spreadsheet::OpenOffice object might instead provide a list of worksheets when acting like an array (or hash, with sheet names as the keys). A raw binary file of uninterpreted data would just be a simple Blob object. Assuming that there existed a consistent definition of Table objects that could be coerced one to another, we could do things like: my Table::SQL $input is readonly := io dbi:Pg:employees/active; my Table::Spreadsheet::Excel $output := io file://Active-Emp.xls; $outputSheet #1 = $input;# read from input, write to output say Data from $input.io.name() saved to $output.io.name(); Now of course there are lots of things that such a broad interface isn't prepared to handle, but that's what the lower levels are for. If .io provides access to the intermediate interface, then you can start with course-grained control, and delve into the particulars if or when you need finer control (access to OS- or FS-specific calls). Above that, there is room for a very high-level IO functionality that glosses over a lot of details, because an awful lot of code just doesn't need all the specifics. -David
Re: Filename literals
On 2009-Aug-14, at 5:36 am, Richard Hainsworth wrote: Would it be possible to remove the special purpose of \ from strings within IO constructs? It's P6, anything's possible! I probably wouldn't change [what look like] ordinary quoted strings, but maybe something with a qf//-type construct (or would that be qf\\ ?!). My idea of using a macro was to grab almost anything that wasn't whitespace, and it doesn't have to be parsed like a normal string, so \ could be interpreted as a dir separator. Of course, / has become so standard, that it even works on Windows (kind of); on the other hand, being able to use either (or both) would be convenient for a lot of people. On 2009-Aug-14, at 7:18 am, Leon Timmermans wrote: I don't think that's a good idea. In general, parsing an URI isn't that easy, in particular determining the end is undefined AFAIK. In your example the semicolon should probably be considered part of the URI, even though that's obviously not what you intended. Well, we can encode a URI any way we like -- I was thinking of anything up to the next whitespace or semicolon, maybe allowing for balanced brackets; and internal semicolons, etc. being %-encoded. I guess the argument would be that using an encoding that looks almost- but-not-quite like other popular ways of representing URIs could be confusing, and people would be tempted to paste in addresses from their browser without re-encoding them the P6 way. Maybe it's more practical to permit only URIs with little to no punctuation to be unquoted, and quote anything else? Not that quoting is such a great hardship anyway On 2009-Aug-14, at 7:41 am, Timothy S. Nelson wrote: And in response to David Green and his comment about working with file data vs. metadata, as a systems programmer, I've written a fair number of programs that have worried a fair bit about the metadata in the filesystem; sometimes you want to read data, and sometimes metadata. Of course; and when I referred to low-level and high-level, there isn't really a distinct dividing line between the two. Is getting (or setting) the modification date on a file low-level because it's metadata, or high-level because it's a simple, ordinary task? I don't particularly care about the classification; I just wanted to make the point that P6 should make it possible to gloss over anything that's over-glossable. -David
Re: Embedded comments: two proposed solutions to the comment-whole-lines problem
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?
On 2009-Aug-9, at 6:30 am, Richard Hainsworth wrote: Its just that */star/whatever doesnt convey [to me] the fact that its a sub-set of of Perl6. I like *... it has more personality than lite. (Or even light.) Though since it's a subset, we could always call it Rakudo ⊂! On 2009-Aug-9, at 12:29 pm, Henry Baragar wrote: Ruby anyone? See http://en.wikipedia.org/wiki/Rake_(software). You mean call it Rakudo Ruby because Ruby has only part of the features of P6? We could name interim releases after competing brands as they get left behind: Rakudo Ruby, Rakudo Python, Rakudo P5 (We're already too late for Rakudo PHP, I'm afraid.) On 2009-Aug-9, at 3:57 pm, Tim Bunce wrote: Perhaps it's worth asking what we might call the release after that one. Rakudo not-quite-so-lite? Rakudo ** (aka Rakudo Exponentiation)? Though I think Patrick is optimistic that development will proceed exponentially enough that a single interim release will be enough to hold us over until Christmas. -David
Re: Reusing code: Everything but the kitchen sink
On 2009-Jul-10, at 4:37 pm, Jon Lang wrote: This is one of the distinctions between role composition and class inheritance. With class inheritance, the full tree of inherited classes is publicly accessible; with role composition, the methods of the combined role are the only ones that are made available to the class. OK, that's actually about what I was thinking, despite the peculiar way I expressed it. I meant the full names to refer to methods directly in the composed role, not somewhere else. Of course, there's already a way to refer to methods with the same name -- using the long name that includes the signature. So my example should have used bark(Canine: ...) and bark(Tree: ...); and whichever one actually gets called depends on whether the invocant does Canine or does Tree. so Dogwood::bark ought to consider its context (am I being called to behave like a Canine, a Tree, or something else?) and decide what to do based on that. If Dogwood::bark isn't defined, you should get an implementation conflict error, because the class failed in its duty to provide an implementation. Yes, and Dogwood::bark could handle it by something like: if $self.does(Canine) {...} elsif $self.does(Tree) {...} -- but Perl already knows how to handle multiple dispatch based on type, so I shouldn't have to write it out manually. In fact, this works with Rakudo: you can have both barks if you declare them as multis, and then it will accept them without having to declare a Dogwood::bark. (But of course if you try calling it, you get an Ambiguous dispatch to multi 'bark' error, because a $dogwood object equally satisfies both signatures.) (I tried to see what would happen if you cast the $dogwood object to Canine or to Tree, but either Rakudo doesn't do it yet, or I got it wrong.) Needing to say multi makes sense if you wanted multiple methods of the same name *within* a role (or class or any other namespace), but I don't think it should be necessary across different Roles. Since they already exist in different namespaces, we know they're supposed to mean different things, and it's a simple fact of life that sometimes the same term will get used in different places for completely different meanings. If you have to do the dispatching manually, I guess that's only a slight annoyance as long as it's possible. (Maybe it's better to force the programmer to do it, not because Perl couldn't, but to prevent potential surprises? Hm.) role R { method foo() { say foo } role R1 does R { method bar() { say bar } role R2 does R { method baz() { say baz } class C does R1 does R1 { } The question is whether or not Rakudo is smart enough to realize that R1::foo is the same as R2::foo, or if it complains that R1 and R2 are both trying to supply implementations for foo. The former is the desired behavior. Conversely, in this case the same name means the same thing, so it does seem perl ought to be able to tell that both foo's are really a single foo() here; since they both come from the same role (R), they have to mean the same thing, and C has to know that it does R. In any case, then the question is how to know what role something does, which is really a question about casting and passing args rather than anything to do with Roles per se. I can't tell just from $dogwood.bark which kind of barking is wanted; but I could have Dogwood::bark_like_a_dog() instead, perhaps. However, in sub nighttime (Canine $rover) { $rover.bark if any(burglars()); } I can only call .bark because all I know for sure is that I have something which does Canine; if I pass it a $dogwood object, I see three possibilities: 1) $rover in the sub is just the Dogwood object that was passed in, and calling $rover.bark cannot know what to do. I also can't call $rover.bark_like_a_dog or anything else, because that method exists only for Dogwood objects, and the sub doesn't always receive Dogwoods. So I'm stuck, and I don't see any way around that the way things are. 2) $rover does Canine and only Canine -- the Tree-half of $dogwood that was passed in is invisible inside the sub, and thus $rover.bark calls bark(Canine:) which is what we want. (Of course, it calls Dogwood's bark(Canine:) when passed a Dogwood object -- it's not magically jumping back to the original Canine role.) If nighttime() in turn calls something-else($rover), the something-else sub also gets only a Canine object. 3) $rover acts like a Canine, but the rest of the original $dogwood arg (the Tree parts) are still there; they just aren't used unless somehow explicitly brought out; for example, by casting $rover to a Tree, or by passing it to some other function that is looking for a Tree object. This is how I'd like it to work, because that's the most flexible. Maybe there should be hard casting and soft casting: by hard
Re: RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)
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
On 2009-Jul-7, at 5:28 am, Jonathan Worthington wrote: The spec is right in that you need to write a method in the class that decides what to do. This will look something like: method fuse() { self.Bomb::fuse() } That makes sense for using the combined role on its own, but can we still handle separate roles that get mixed together? That is, after defining that method so I can call $joke.fuse(), can I still call $joke.Bomb::fuse and $joke.Spouse::fuse as well? I'm thinking that it's useful to be able to refer to the fully- qualified names for anything composed into a role or class; often there will be no ambiguity, so the full name won't be necessary. If the names aren't unique, then you can specify them fully, and perhaps add an unqualified fuse() that does one or the other (or both? or neither??) for convenience. That shouldn't be necessary, I think -- it just means you would have to spell out exactly which method you wanted. In the case Ovid also mentioned where two roles have a method of the same name because both methods really are doing the same thing, there ought to be a way to indicate that (though if they both come with implementations, you'd still have to pick one or write your own). Of course, in a perfect world, the common method would come from its own role: if Foo.fuse and Bar.fuse really mean Foo.Bomb::fuse and Bar.Bomb::fuse, then doing Foo and Bar together should automatically give you a single .fuse method (again, at least as far as the interface is concerned). I guess being able to create a role by dropping some bits from an existing role would be useful sometimes, but it seems to lose one of the most useful benefits of roles: as Jon Lang pointed out, R1 :withoutfoo bar would effectively be a new role, one that doesn't do R1. But you want something to do a role in the first place so that it will work anywhere else there is code looking for that role. So supposing: role Canine { method bark { say ruff; } }; role Tree { method bark { say rough } }; class Dogwood does Canine does Tree { ... }; my Dogwood $dw; sub nighttime (Canine $rover) { $rover.bark if any(burglars()); } sub paper (Canine $rex) { $rex.bark if newspaper(:delivered); } sub paper (Tree $nodes) { $nodes.bark == flatten; ... } What happens when I call nighttime($dw)? Obviously, it's meant to call $dw.Canine::bark. Since nighttime() is looking for something that does the Canine role, any method calls in that function can safely be assumed to be short for .Canine::bark (since all we know for sure is that any arg passed in will do Canine, and we can't know it will do anything else). If I want to call paper(), then I would have to cast $dw to either one of the roles, e.g. paper(Tree($dw)), and that would presumably strip off or hide the Canine part of its nature. It doesn't seem unreasonable for any non-Tree attributes to be inaccessible inside paper(Tree), since all it can guarantee is the arg does Tree; but on the other hand, I think it would be OK but would require you to use the fully qualified names for anything non-Tree. If Dogwood defines its own .bark method, I can see it meaning one of two things: either it's yet another bark(), specifically $dw.Dogwood::bark(), that can be used only where we're expecting a Dogwood object. (It might bear no relation to Canine::bark or Tree::bark, although in that case it would probably be a good idea to pick a different name!) Or else, it could mean a consolidation of the two mixed-in .bark's, i.e. $dw.Canine::bark and $dw.Tree::bark would both now be implemented by plain $dw.bark, aka $dw.Dogwood::bark (all three full names would mean the same thing for Dogwood objects). -David
Huffman's Log: svndate r27485
On 2009-Jul-8, at 3:41 pm, pugs-comm...@feather.perl6.nl wrote: =item log + our Num multi method log ( Num $x: Num $base = Num::e ) is export Logarithm of base C$base, default Natural. Calling with C$x == 0 is an error. It occurs to me that log is a pretty short name for a function I rarely use. (In fact, I'm not sure I've ever used it in perl.) On the other hand, I -- and a thousand or so CPAN modules -- are always logging stuff in that other popular computer sense. (All right, that number isn't exactly the result of a rigourous study... I did find 57 modules that mentioned logarithms.) The inertia of tradition weighs heavily here, but perhaps we could call it ln(). (If anyone asks, I'm prepared to say with a straight face that it stands for log (numeric).) And/or log(), but with the :base arg mandatory -- then as long as your status logging doesn't have a :base, you can have both. -David
Re: YAPC::EU and Perl 6 Roles
On 2009-Jul-8, at 1:49 pm, Ovid wrote: That being said, roles also have two competing uses (though they don't conflict as badly). As units of behavior, they provide the functionality your code needs. However, they can also serve as an interface. Maybe there are Interfaces, which are, well, just interfaces, and there are Roles, which are Interfaces plus a partial or full implementation. Like roles and classes, roles and interfaces could be transparently interchanged when suitable. Add some bodies to an Interface and you've got a Role; cast a Role to an Interface and you strip out everything but the declarations. Behavioral: if you are primarily relying on roles to provide behavior (as we do at the BBC), then silently discarding the role's behavior by providing a method of the same name in your class can lead to very confusing bugs. I've lost a lot of time debugging this behavior. role Stuff { suggest method foo { ... } method bar { ... } } class Thing does Stuff { method foo { ... } supersede method bar { ... } } Since foo() is only suggested by this role, you can easily override it; whereas bar() needs to be explicitly superseded. (Or maybe it should be method foo :suggested) The idea being that certain methods are expected to work by accepting what's provided in the role most of the time, so you should rarely have to supersede them; or they're merely suggestions, and therefore you are expected to role^H^H roll your own most of the time. (And if you find yourself getting annoyed that you have to type supersede so much, that's probably a good clue that something went wrong somewhere in the design.) Either that, or just have suitable warnings that can be toggled on or off depending on what sort of policies you need. That was actually my first thought, and I think we should have adjustable warnings for everything anyway, but the more I look at the above example, the more it's growing on me. -David
Re: New CPAN
On 2009-May-30, at 6:56 am, Andrew Whitworth wrote: I'm not saying we *can't* create a general repository for all sorts of nonsense, I'm saying that we *shouldn't*. Holiday photos is just a whimsical example. The problem is that it's hard enough keeping up with what Perl6 is today, let alone what it will be tomorrow. Or what Perl 7 will be, or what some other programming language/system will be that isn't even invented yet. Mark's point is that any arbitrary restrictions put in place now will seem short-sighted in 10 years' time, so we need something flexible. And it's all just 1s and 0s to the computer, so you *could* use it for photographs; that shouldn't matter to the software. If you want to create an infrastructure that is vastly extensible and too clever by half, that's you're prerogative. Sure, it's always possible to go too far. But on the other hand, isn't Perl 6 all about being too clever by half? It's certainly about being vastly extensible, anyway. -David
Re: New CPAN
On 2009-May-30, at 12:06 pm, David Green wrote: ...what Perl6 is today, let alone what it will be tomorrow. Actually, we do kind of know what Perl will look like a decade from now, because P6 is deliberately extensible enough that we may never need a Perl 7. But that simply means that holiday photos are already a possibility: perl -MSteganography::Images pics/2009/ceylon.jpg In fact, you could do that in Perl 5 On 2009-May-30, at 9:32 am, Daniel Ruoso wrote: If you replace holiday pictures by 'YAPC pictures', 'Talk slides', 'Code Snippets', 'Perl related scientific articles' it does look much more closer to a very good use of CPAN. Hm, all we need is the right grammar, and your slides can be their own code! -David
Re: renaming or adding some operators
On 2009-May-29, at 7:53 pm, Darren Duncan wrote: Thirdly, there are I'm sure a number of other aliases that could be added to other ops, such as ≤ and ≥ for = and =, and ≠ for one of the inequality operators, although that last one would probably make more sense if = was the equality test operator, so maybe best to avoid ≠ then. Probably. I would really like to see the obvious symbols defined, though, for two reasons: 1) Being able to use real symbols (e.g. ≤ instead of crude ASCII approximations) will make Perl code look ever so pretty and make all the other kids envious. (Envy is, of course, one the great programmers' virtues, the one that makes us steal all the best bits from other languages!) 2) It will discourage people from abusing operators that already have well-defined standard meanings. For example, if there is no ∑, somebody might be tempted to use it for multiplication; or to use √ for checking something; or + for concatenating strings, etc. However, I think some set ops could also be used with hashes. For example, an alternate way of spelling exists %foo{$bar} is $bar ∈ %foo or %foo ∋ $bar. I think that one's ambiguous as to whether $bar exists as a key or a value. $bar ∈ @foo; $bar ∈ %foo.keys; $bar ∈ %foo.values; ∃ %foo{bar} -David
Re: deciphering infix:cmp
On 2009-Mar-26, at 10:50 pm, Patrick R. Michaud wrote: But what to do with something like C 3 cmp '3' , or any infix:cmp where the operands are of differing types? Do we constrain Ccmp to only work on similarly-typed operands (in which case my sort above would fail), or am I overlooking something obvious? Failing makes sense to me (you can't compare apples to oranges, at least not without explicitly saying you want compare them only as coerced to general Fruit types). The other way I can think of that might be useful practically is to compare first by type, then by value; but that should probably be a different operation. say sort { $^a.WHAT leg $^b.WHAT || $^a cmp $^b }, a, 1, b, 2 , c, 3, d, 4; -David
Re: a junction or not
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
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
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)
On 2009-Feb-23, at 11:30 pm, Carl Mäsak wrote: For what it's worth, I write a lot of Perl 6, and I'm already used to it. OK. Of course, you might be smarter than the average coder, but I agree it's not a huge deal. On 2009-Feb-24, at 9:29 am, Mark J. Reed wrote: On Tue, Feb 24, 2009 at 11:16 AM, Ruud H.G. van Tol rv...@isolution.nl wrote: David Green wrote: my $foo is limited(100..200); $foo = 5; # really does $foo = 100 Where does that MySQ smell come from? Why not undef (or NaN)? How about Failing instead of any of the above? Silently replacing the assigned value seems like a Bad Idea. MySQL does stuff like that silently, which is a problem. But it's OK if you ask for it. In fact, why not all of the above: my Int where {100 = $_ = 200} $foo; $foo = 5;# failure! my Int where {100 = $_ = 200} $foo is silently-set-to(NaN); $foo = 5;# does $foo = NaN my Int where {100 = $_ = 200} $foo is auto-kept-within-limits; $foo = 5;# does $foo = 100 Except with better names... On 2009-Feb-24, at 10:30 am, Larry Wall wrote: Alternately, if you want a purer FP solution: take $foo clamp 100..200; take $bar clamp $midpoint ± $epsilon; That's a much better name! But why take instead of $foo clamp= 100..200? (Maybe the answer is why not?, but I might be missing the point.) -David
Comparing inexact values (was Re: Temporal changes)
On 2009-Feb-23, at 10:09 am, TSa wrote: I also think that time and numbers in general should be treated in a fuzzy way by smart match. My thought is to have == take a :within adverb, at least for imprecise types like Num, that could be used to specify how close values need to come in order to be considered equal. So instead of: if abs($x-$y)$epsilon { ... } you could say: if $x==$y :within($epsilon) { ... } which makes your tests for equality look like tests for equality. I'd even suggest that the :within be mandatory, to guarantee that the coder is aware that $x==$y is probably not DWIM. Of course, there should also be an easy way to set epsilon across a scope, like: use Num :precision(0);# force exact matches in this block -David
min= (from Rakudo Built-ins Can Now Be Written In Perl 6)
On 2009-Feb-23, Jonathan Worthington posted to Rakudo.org: Applied a patch from bacek++ to get min= and max= working ($foo min= 100 will assign 100 to $foo if it's smaller than what is in $foo). Nice -- except I first read that backwards, i.e. even though it follows straight from the definition of [op]=, it made me think of forcing a minimum value, which would actually be max=. I can think of a few ways to deal with this: 1) Get used to it. Maybe document it somewhere to catch fewer people off-guard, but otherwise simply expect people to check their code. 2) Override it by defining an explicit infix:min= operator that does max=, and vice versa. People like me will never notice that something fishy is going on, but it penalizes the folks who are actually paying attention to what min= ought to mean! 3) Avoid the potential for confusion by having another way to set min/ max values, such as: $foo.min = 100; min($foo) = 100;# lvalue function $foo = get-foo() :min(100); # adverb on = I'm not crazy about any of those, but that did suggest what is probably a better way to approach it anyway: setting limits at declaration rather than repeating them every time the variable is assigned to: my $foo is limited(100..200); $foo = 5; # really does $foo = 100 -David
Re: Temporal revisited
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
On 2009-Feb-20, at 11:17 am, Larry Wall wrote: Certainly, we'll be depending on the type system to keep these things straight. I'm not suggesting the user use bare Nums as anything other than naive durations for APIs such as sleep(). If we have some units to make suitable objects, we can say sleep(5`min), etc. That would mean we can always take time-types, and avoid the $t*1000*60*60*24 idiom to boot. [...]I suppose Temporal is as good a module name as any, though Temporal::Instant does seem a bit redundant... Well, it distinguishes it from Coffee::Instant... -David
Re: Temporal and purity (was: Re: IO, Trees, and Time/Date)
On 2009-Feb-19, at 4:39 pm, Martin Kealey wrote: 2. Date isa Instant works sensibly: anywhere that expects an Instant, you can give it a Date. (Assuming we all agree that dates start at midnight, but then we *are* talking specifically Gregorian dates.) I don't like dates just starting at midnight because I've run into too many awkward cases where $time $date doesn't do what you mean because it assumes 0:00:00 when you meant 23:59:59. I'd rather have dates becomes time-ranges. Or perhaps don't make them coercible and require an explicit conversion via $date.morning or $date.evening or something. (Maybe require $time ∩ $date or $time ⊂ $date?) -David
Re: Temporal revisited
On 2009-Feb-19, at 11:26 am, Dave Rolsky wrote: What I want to see in Perl 6 is a set of very minimal roles that can be used to provide a simply object from gmtime() and localtime(). These objects should not handle locales, proper Olson timezones, string parsing, user-defined formatting, or math. Yes; I myself haven't had to worry about leap-seconds before, and may very well never have to. Really basic math is common enough that it seems reasonable to include, though. And we get that by being able to numify times, though I'm not sure about officially making time() return a Num -- isn't that exposing an implementation detail? If I need an epoch value, I'd expect to have to say $time.epoch or $time.epoch(1970) or something. our Time::localtime(:$time,:tzGMT) Why can't we just have time() that takes a :tz adverb and dispense with gmtime() and localtime()? I also think that timezones should be required, so that it's impossible to have a time and not know what TZ it's supposed to be. If there's no simple enough way to do minimal timezones, then allow only GMT (and require using a suitable module to recognise any other TZ). If you really don't care because you know for sure the TZ will never matter, say use timezone GMT. (You may as well not care that all the times are GMT in that case. But if it turns out someday that you do care, you can't say you didn't know.) Or maybe allow any string as a timezone by default. If all your times use the same TZ, that's fine; but as soon as you try to work with two times with different zones, you'll get an error, unless you're using a module that knows how to convert between those zones. (While we're at it, why is time zone still officially two words? Usually I like to side with the dictionary, but I can't figure out how timezone has escaped becoming de facto standard English.) ((I also prefer Instant to DateTime unless we end up using both, as in Darren Duncan's suggestion.)) -David
Re: Support for ensuring invariants from one loop iteration to the next?
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?
On 2008-Dec-6, at 7:37 am, Aristotle Pagaltzis wrote: Funnily enough, I think you’re onto something here that you didn’t even notice: [...] if we had a NOTFIRST (which would run before ENTER just as FIRST does, but on *every* iteration *except* the first), then we could trivially attain the correct semantics and achieve all desired results: repeat { @stuff = grep { !.valid }, @stuff }; NOTFIRST { .do_something( ++$i ) for @stuff; } } while @stuff; The really nice thing about this is that the blocks are nested, so that any variable in scope for the invariant enforcement will also be in scope in the NOTFIRST block without the user ever having to arrange another enclosing scope. Oh, yes! So what if we had LOOP $n {} that executed on the nth iteration? LOOP 0 {} at the beginning would be like FIRST {}, LOOP * {} at the end would be like LAST {}, and LOOP 1..* {} would give us the NOTFIRST block. Presumably you could have multiple LOOP blocks too. (Actually, you couldn't quite do FIRST/LAST using LOOP $n, because FIRST/LAST occur outside ENTER/LEAVE, whereas LOOP would occur inside. But perhaps you could have LOOP blocks inside ENTER/LEAVE blocks?) -David
Re: Support for ensuring invariants from one loop iteration to the next?
On 2008-Dec-16, at 6:21 pm, Timothy S. Nelson wrote: Or, instead of having a new block, just add the iterator indicator to the NEXT block, and get rid of ENTER and LEAVE. That way, you'd have this sequence: - FIRST {} - NEXT 0 {} # Replaces ENTER - NEXT 1..* {} # Does NOTFIRST - NEXT * {} # Replaces LEAVE - LAST {} Would that do it? Not quite -- the idea is that you could put the LOOP block anywhere in the body of the loop, and it would execute at that point. NEXT and friends always occur at the end (or beginning) of their block. Nor would it work to take an existing block like NEXT and allow it to be positioned in the middle of the body, because it wouldn't be possible to duplicate what they already do -- in this example, the NEXT wouldn't get executed when next if something() occurs: loop { next if something(); a; NEXT { ... } b; } On Tue, 16 Dec 2008, Jon Lang wrote: How do you compute '*'? That is, how do you know how many more iterations you have to go before you're done? In some cases, it won't have to be computed, in some cases it won't be computeable (which should be an error). I'd say it'd be fair enough to say that 1..(*-1) should be an error in non-bounded(?) loops (ie. while). That sounds right to me. Does 'for @foo' take a snapshot of @foo, or can you change the bounds by changing @foo while the loop is running? In which case trying to count back from * might be an error for anything except constant bounds. -David
Re: r24325 - docs/Perl6/Spec
On 2008-Dec-14, at 11:21 am, Moritz Lenz wrote: Uri Guttman wrote: how is sort ordering specified? Currently it is not specified, it defaults to infix:cmp. If you can suggest a non-confusing way to specify both a transformation closure and a comparison method, please go ahead. how does it know to do string vs numeric sorting? infix:cmp does numeric comparison if both operands are numbers, and string comparison otherwise. Cmp (like eqv) depends on the particular type, so to sort a certain way, you should need only to coerce the values to the right type: @stuff.sort { .Num } # numerically @stuff.sort { ~ .name.uc } # stringwise @stuff.sort { Foo(%x{$_}) } # foo-wise I don't know what cmp returns for two values of different types. (Failure?) -David
Re: What does a Pair numify to?
On 2008-Dec-15, at 4:18 pm, Jon Lang wrote: If you've got a list of Pairs, you use a sorting algorithm that's designed for sorting Pairs (which probably sorts by key first, then uses the values to break ties). Agreed. If you've got a list that has a mixture of Pairs and non-Pairs, I think that the sorting algorithm should complain: it's clearly a case of being asked to compare apples and oranges. If there's no cmp(Pair, Other::Thing) defined, then it would fall back to string-comparison, which seems fair to me. But complaining isn't unreasonable either, since it's easy to coerce stuff to strings if that's what you want. I guess you could force complaining with: infixcmp:(Any, Any) = { die Apples and oranges! } When are you going to be asked to stringify or numify a Pair? Actual use-cases, please. Personally, I can't think of any. say $pair; I can't really think of a great example where you'd want to numify a pair, but I would expect printing one to produce something like a = 23 (especially since that's what a one-element hash would print, right?). -David
Equality of values and types (was Re: how to write literals of some Perl 6 types?)
On 2008-Dec-4, at 4:41 pm, Leon Timmermans wrote: On Thu, Dec 4, 2008 at 6:34 PM, TSa [EMAIL PROTECTED] wrote: And how about 'Num 1.0 === Complex(1,0) === Int 1'? IMHO the spec on === is quite clear: two values are never equivalent unless they are of exactly the same type. I guess the question is what kind of similarity is the most useful? On the one hand, we have values that happen to have the same *representation* but different *meaning* (e.g. Weekday::Sun and Star::Sun); on the other hand, we have values with a different representation but the same meaning (e.g. Int 29 and int8 29). Usually the reason for comparing both value and type is to check for the same meaning, rather than accidentally equal representations. So let's imagine a syn operator that checks for the same value and the same family: 1 syn 1.0 syn Complex(1,0) Date '2008-1-2' syn Datetime '2008-1-2 0:00:00' We can't simply rely on == because my Date and Datetime objects can be coerced to numeric values, but they don't mean the same thing as a plain Num or Int. Presumably classes need to indicate their family resemblances somehow. Now, which is more useful? Is it worth having === and syn? -David
Re: why infix:div:(Int, Int -- Rat)
On 2008-Dec-4, at 3:08 pm, Mark J. Reed wrote: Using div instead of / should make it pretty clear that you're disposing of the remainder. I misremembered div vs. idiv, but how standard is it? I know div commonly means int division, but not always. On the one hand, some things you just have to learn; on the other, lots of P6 operators have word-names as well as symbols, and div is the obvious way to spell / (what else would you call it?). A way to get both [quotient and reminder] in one fell swoop would be nice Agreed; though having two different operators seems a bit unperlish. Int-div could return two values, but that seems prone to accidentally interpolating unwanted remainders into lists or things like that. Would it make sense to include the remainder as a trait on the quotient? Or return some other special compound type that numifies to the quotient. -David
Re: Support for ensuring invariants from one loop iteration to the next?
On 2008-Dec-4, at 9:09 am, Aristotle Pagaltzis wrote: And while it does seems like a closure trait, that seems somewhat problematic in that the order of evaluation is weird when compared to other closure traits, which I suppose is what led you to declare the “coy” solution as the most natural. I tried to break down the reasons for wanting to write such loops different ways: 1) Simple code -- the coy solution, with the condition checked in the middle of the loop, is the cleanest in that if we put the condition anywhere else, we still also need to mark where in the middle it should be checked. 2) Clear code -- putting the condition up front (or maybe at the end) makes it stand out and more clearly identifies the purpose of the loop. Of course, you still need something in the middle as well as up front, so you could simply put a comment up front to explain what's going on. 3) Self-documenting code -- this is different from the previous point (introspection rather than [non-self] documentation... like my other comment about counting iterations -- you can always add $i++; #to check for second loop, but then the meaning is accidental rather than implicit). I think this gets at the heart of the problem: not merely making code do the right thing, but making it look the right way, making it use a natural idiom. So something like: repeat using $block { something(); check-condition; # means: last unless $block; something_else(); } But I don't really like the need to add the check-condition command. Maybe something like: repeat using LABEL { something(); LABEL: last unless $block; something_else(); } But that still seems too sloppy. What we need is something a bit like the continue block, except that it gets executed before the loop- condition is checked the first time. So what if we split the loop- body into two parts? repeat { something(); } while ( condition(); ) { something_else(); } Now the condition is in the middle and is syntactically separate. (It's still not up front, but if the first block is really long, you can always... add a comment!) -David
Re: Support for ensuring invariants from one loop iteration to the next?
On 2008-Dec-5, at 7:43 am, David Green wrote: Now the condition is in the middle and is syntactically separate. (It's still not up front, but if the first block is really long, you can always... add a comment!) Well, you don't need a comment -- why not allow the condition to come first? repeat while ( condition(); ) { something(); }, { something_else(); } You need the comma there because the final semicolon is optional, and we don't want Perl to think it's an ordinary loop followed by an independent block. Probably better is to name the introductory block, and then programmers as well as compilers know that something unusual is going on: repeat while (condition) preamble { something } { something_else } -David
Re: why infix:div:(Int, Int -- Rat)
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?
On 2008-Dec-3, at 10:18 am, TSa wrote: Darren Duncan wrote: Strong typing in Perl means that Perl is conveniently and reliably keeping track of this user-intended interpretation of the data, so it is easy for any piece of code to act on it in a reasonable way. Strong typing lets user code be clean and understandable as it doesn't have to do a lot of manual book keeping or error checking that Perl can do for it, such as detecting the error of passing a character string to a numeric multiplication operator. First I have a question to the example of the behavior of a string in a multiplication. Perl 6 automatically attempts a numerification. But does that result in a failure for 'foo' or does that return 0? That is, '3' * 3 == 9 is well formed and 'foo' * 3 is malformed, right? That's what I would expect. A reasonable default would be for lossless conversions to happen automatically and lossy ones to throw an error. [...Are Enums === Ints?] This multi is only allowed if A and B are types distinct from Int which to me implies that enums have a WHAT that is not Int. Opinions? Using int8 vs Int is presumably a performance issue, but int8 29 and Int 29 *mean* the same thing, so they should be ===. An Enum doesn't mean the same thing as a plain Int, so it shouldn't. (As you point out, you can always use something like Weekday::Sun eq Star::Sun or Weekday::Sun == 0 if you want string or numeric equality.) A further question is which operators are automatically generated for enums. Does my Int $a = A::One; $a++; increment from A::One to A::Two or to the Int 2? What shall happen when A::Three is incremented? Failure or switch to Int? What happens with non-continuous enums? My vote would be to not generate any operators Since ++ works on strings without making them numbers, I think it should increment from A::One to A::Two. But if that's ambiguous, we could drop the ++ and stick with .=succ for non-numeric objects instead. -David
Re: how to write literals of some Perl 6 types?
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))
On 2008-Oct-22, at 10:03 am, TSa wrote: David Green wrote: One thing I would like signatures to be able to do, though, is assign parameters by type. Much like a rule can look for identifiable objects like a block or ident, it would be very useful to look for parameters by their type or class rather than by name (or position). Note that types have a fundamentally different task in a signature than name and position have. The latter are for binding arguments to parameters. The types however are for selection of dispatch target. Names do that too; I think both names and types should be available for both binding and dispatching, depending on what's more natural in a given context. Sometimes we think in terms of names (I'm going to Fred's place), sometimes in terms of types (I'm going to the grocery store). (And some types are names (Dad)!) In single dispatch it is very important if your dispatch is handled in the Nail or Hammer class. In multi dispatch one can still distinguish action:(Hammer,Nail) from action:(Nail,Hammer). There is the following syntax to define two sigs for the same body multi method action (Hammer $hammer, Nail $nail) |(Nail $nail, Hammer $hammer) Sneaky, I hadn't thought of doing it that way. Of course, a mere five objects give you an unwieldy 120 possibilities, so some syntactic relief is called for. Perhaps something like an to indicate that the parameters are not sequential: sub foo ($posn0, $posn1, Bar $type1 Baz $type2 Bat $type3, : $named1, :$named2) -David
Signatures and matching (was Re: XPath grammars (Was: Re: globs and trees in Perl6))
On 2008-Oct-2, at 6:15 pm, Timothy S. Nelson wrote: The guys on IRC convinced me that the way to go might be something like a grammar, but that does trees and tree transformations instead of a text input stream. See the IRC log for details :). [...] TimToady note to treematching folks: it is envisaged that signatures in a rule will match nodes in a tree There does seem to be a clever idea waiting to happen here, although I expect signatures will be somewhat simpler since they are intended for a more specific purpose. One thing I would like signatures to be able to do, though, is assign parameters by type. Much like a rule can look for identifiable objects like a block or ident, it would be very useful to look for parameters by their type or class rather than by name (or position). For example, if I ask you to hand me a hammer and a nail, I don't need you to hand them to me in a specific order, or with labels attached like a Dick Tracy comic, in order to know which is which. That's obvious, because, well, one is a hammer and one is a nail. If I'm writing OO-code, then Perl also knows what's a Tool::Hammer and what's a Fastener::Nail -- if I know that my $tool is a hammer, and Perl knows, then I shouldn't have to spell it out. The :$foo shortcut for :foo($foo) addresses the same problem, but in terms of naming; it is reasonable that a Foo object would be named $foo in both the caller and the sub, but not necessary. Being able to use class info that's already there would make it easy to grab params when I know the type of object I'm looking for, but not what it's called. -David
Re: Why no is ro? (Re: Subroutine parameter with trait and default.)
On 2008-Sep-23, at 5:27 pm, Michael G Schwern wrote: David Green wrote: Happily, brevity often aids clarity. The rest of the time, it should be up to one's editor; any editor worth its salt ought to easily auto-complete ro into readonly. Eeep! The your IDE should write your verbose code for you argument! For that one, I brine and roast an adorable hamster. Fair enough. As long as you remember to share with the rest of us!! That's just another way of saying that your language is too verbose for a human to write it without hanging themselves. See also Java. But the problem with Java isn't just that it's too verbose to write; it's that it's too verbose to read, too. Why shouldn't your editor help with verbosity? The amount of typing shouldn't be a main concern in language design, because your editor can mostly compensate for that; there are other, better reasons to decide how verbose something should be. Anyhow, I see where you're going, and I understand the desire for no abbvs. But man, ro is pretty damn easy to remember. [1] This is even sillier when you hold it up against all the magic symbols we're supposed to remember. [EMAIL PROTECTED], :namevalue, |$arg, $arg!, $arg?, : $arg. As a bear of limited recall, I sometimes feel a bit overwhelmed by all the stuff there is to remember. I'm certainly not against all abbreviations. I have a deeply ingrained instinct to name my variables x, y, and z, and to name files... x, y, and z. My shell profile is full of one-letter aliases (I don't have time to waste typing 2-char command names!). However experience has taught me the value of more robust names for anything but one-liners. I bet we actually don't disagree much; I'm not really against ro -- I'm just not against readonly because of its length. If I were writing casually, I'd use rw and ro; formally, I'd use read only and read/write (or even readable and writable). At an in-between level, which is where I believe we should be aiming, I think I'd put rw and read-only. I'm not entirely sure why. Maybe psychologically, ro looks like it could be a word, whereas the unpronounceable rw has to be an abbreviation? Or maybe it's just because I see rw every day in ls output, but ro not so much. At any rate, if I wanted to argue in favour of ro, I think symmetry (which you already mentioned) is the strongest argument. You're only a beginner once, and if everything is done right for a short time. The rest of your career, you're experienced. Ooh, now that I completely agree with! Software that thinks user- friendly means dumbed-down drives me nuts. -David
Re: Why no is ro? (Re: Subroutine parameter with trait and default.)
On 2008-Sep-23, at 2:32 pm, Michael G Schwern wrote: My other thought is that since parameters are read-only by default it's not thought you'd have to write it much so clarity wins out over brevity, the flip side of Huffamn encoding. But that doesn't work out so good for normal variable declarations. I'd call it straight Huffman encoding, because clarity is what we should be optimising for. (You read code more than you write it... unless you never make any mistakes!) Happily, brevity often aids clarity. The rest of the time, it should be up to one's editor; any editor worth its salt ought to easily auto-complete ro into readonly. -David
Re: Split with negative limits, and other weirdnesses
On 2008-Sep-23, at 8:38 am, TSa wrote: Moritz Lenz wrote: In Perl 5 a negative limit means unlimited, which we don't have to do because we have the Whatever star. I like the notion of negative numbers as the other end of infinity. I think positive values and zero make sense. But I don't want to give funny meanings to negatives; it would be better to replace the int limit with a range instead. (Maybe it would be OK to accept a single Int as short for 1..$i, or *-$i as short for *-$i..*.) Then again, we could get rid of the limit arg altogether, return everything, and take a slice of the result -- assuming it can be lazy enough to calculate only what ends up getting sliced out. -David
Re: Multiple Return Values - details fleshed out
On 2008-Aug-9, John M. Dlugosz wrote http://www.dlugosz.com/Perl6/web/return.html to clarify and extrapolate from what is written in the Synopses: Third, list assignment will handle assignment to a literal pair by accessing the names of the items inside the Capture. So list assignment behaves a lot like binding, but doesn’t do everything that parameter passing can do. [...] The example seen early on of (:$year,:$mon,:$mday) = localtime(time); can be made to work by returning both positional and named values. The return signature would need to have twice as many items, and the return statement would need to supply each one twice. Couldn't these all work the same way as parameter passing does? Even at the cost of a bit more complexity, it would be simpler overall to have only one set of rules to learn. -David
Re: assignable mutators (S06/Lvalue subroutines)
On 2008-Jun-2, at 3:30 pm, Jon Lang wrote: sub foo($value?) is rw($value) { ... } Or something to that general effect. The parameter in question must be optional and cannot have a default value, so that a test of whether or not the parameter is actually there can be used to determine whether or not to operate like FETCH or like STORE. I like is rw($value). There does need to be a way to tell whether a value was passed to it, even if that value was undef. Ah, it just occurred to me that rather than checking the $value, you should be able to check want~~:($ is rw). Does this [with no slurpy scalar to pick up the rvalue]: sub foo () { ...; $proxy } give us anything that you couldn't get from: sub foo ($rval is rvalue) { ...; $proxy = $rval } (I'm assuming that both of these subs are rw.) Yes. infix:= isn't the only operator that assigns values to rw objects: so do the likes of infix:+= and prefix:++. As well, any function that accepts a rw parameter will presumably end up writing to it somewhere in its code; otherwise, why declare the parameter as rw? I would expect all of those to work the same way in either case. That is, anywhere the sub is used as an lvalue, it could pass the rvalue as a special arg, not just when using =. Note, BTW, the difference between passing a proxy object as a parameter and passing a mutating sub as a parameter: in the former case, you call the lvalue sub once in order to generate the proxy object, and then you pass the proxy object as a parameter; in the latter case, you don't call the mutating sub: you essentially pass a coderef to it, and then call it each time the function in question attempts to read from or write to it. OK; but I think that can be handled by a mutating sub -- assuming the issue is that the proxy-sub sub foo is rw { blah; $proxy } runs blah once and returns the proxy that can be assigned to multiple times, whereas a mutating sub would run blah every time you use it. But: sub foo is rw($rval) { unless want~~:($ is rw) { blah }; $unproxy= $rval; } In other words, the mutating-sub-way can do everything the proxy-way can (and more), as long as we can tell when being used in lvalue- context. Incidentally, now that Perl is all OO-y, do we need tying/proxying like that, or can we just override the = method on a class instead? It's possible that in perl6, 'STORE' could be spelled 'infix:='; but then how would 'FETCH' be spelled? And doing so would require that your storage routine return a value, even if you never intend to use it. No; I prefer 'STORE' and 'FETCH' as the basic building blocks of anything that's capable of working like a rw item. I agree with that; I'm just pondering whether we need the concept of tying any more, or whether FETCH and STORE can be thought of as standard methods for any object. In P5, not everything was an object, but everything is in P6 (or can be considered one, if you like objects), so it would be simpler to think in terms of one unified concept instead of two. Of course, since subs are objects too, maybe all you need for an lvalue-sub is to override the FETCH and STORE methods it already has. But then the is rw stuff would simply be syntactic sugar to make doing so prettier. -David
Re: ordinal access to autosorted hashes
On 2008-Jun-1, at 11:20 am, Jon Lang wrote: David Green wrote: I thought it already did, but apparently it's something that we discussed that didn't actually make it into S09. I agree that .[] should apply to hashes just as .{} can apply to arrays. The hashes don't even need to be sorted -- %h[$n] would basically be a shorter way of saying @(%h.values)[$n], in whatever order .values would give you. I believe that the order that .values (or is that :v?) would give you is determined by .iterator - which, if I'm understanding things correctly, means that any use of :v, or :k, :p, or :kv, for that matter, would autosort the hash (specifically, its keys). Or am I reading too much into autosorting? No, that's my understanding too, with the observation that it doesn't matter whether there's any sorting going on (so the order might be arbitrary -- as in your next point). Bear in mind that keys are not necessarily sortable, let alone autosorted. For instance, consider a hash that stores values keyed by complex numbers: since there's no way to determine .before or .after when comparing two complex numbers, there's no way to sort them - which necessarily means that the order of :v is arbitrary, making %h[0] arbitrary as well. Aha -- I guess you're thinking in terms of autosorting that can be turned on to return the values ordered by and . But .iterator can do whatever it wants, which in the default case is presumably to walk a hash-table (technically not an arbitrary order, although it might as well be as far as a normal user is concerned). Or you could make .iterator return values sorted by alphabetical string- representation (which would work for complex numbers), or you could make it work by using and (which wouldn't work with complexes). Which doesn't contradict anything you've said of course -- but I'm OK with arbitrary orders. If %h[0] is arbitrary, that's fine. This is why I was suggesting that it be limited to autosorted hashes: it's analogous to how @a{'x'} is only accessible if you've actually defined keys (technically, user-defined indices) for @a. Do you see that as a psychological aid? That is, if the order is arbitrary, %h[0] makes sense technically, but may be misleading to a programmer who reads too much into it, and starts thinking that the order is meaningful. My feeling is that it's fine for all hashes to support []-indexing. But if the order isn't important, then you probably wouldn't need to use [] in the first place (you'd use for %h:v, etc.)... so maybe it should be limited. Hm. -David P.S. Everywhere I said and I really meant .before and .after. =P
Re: assignable mutators (S06/Lvalue subroutines)
On 2008-Jun-1, at 1:50 pm, Jon Lang wrote: David Green wrote: [...] assignment should work like passing args when used on a function. Then you can easily do whatever you want with it. [...] If a routine is rw, you may optionally define a single slurpy scalar (e.g., '*$value') in its signature. This scalar counts as the last positional parameter, much like slurpy arrays and hashes must be declared after all of the positional parameters have been declared. You do not need to pass an argument to it; but if you do, you may do so in one of two ways: through the usual arguments syntax, or via assignment syntax. The only objection I have to making it a positional parameter is that then you can't have other optional positionals before it. (Also, doesn't the '*$value' notation conflict with a possible head of the slurpy array?) I'd rather make it named so it doesn't interfere with other args. Or have it separate from named/positional args altogether; if something has a meaning of assignment, then it should always look like foo = 42 and not like foo(42). (The latter is just an ugly workaround for languages with incompetent syntax -- we don't want Perl code to look like that because Perl isn't like that.) If an assignable routine does not have a slurpy scalar in its signature, it operates exactly as currently described in S06: it returns something that is assignable, which in turn is used as the lvalue of the assignment operator. Does this [with no slurpy scalar to pick up the rvalue]: sub foo () { ...; $proxy } give us anything that you couldn't get from: sub foo ($rval is rvalue) { ...; $proxy = $rval } [...] sub foo () is rw { return new Proxy: FETCH = method { return .() }, STORE = method ($val) { .($val) }, postcircumfix:( ) = method ($value?) { yadda } } Incidentally, now that Perl is all OO-y, do we need tying/proxying like that, or can we just override the = method on a class instead? Is there something different about it, or is it just an alternative (pre-OO) way of looking at the same thing? -David
Re: ordinal access to autosorted hashes
On 2008-May-27, at 8:32 pm, Jon Lang wrote: [...] Would it be reasonable to allow hashes to use .[] syntax as something of a shortcut for .iterator in list context, thus allowing autosorted hashes to partake of the same sort of dual cardinal/ordinal lookup capabilities that lists with user-defined array indices have? I thought it already did, but apparently it's something that we discussed that didn't actually make it into S09. I agree that .[] should apply to hashes just as .{} can apply to arrays. The hashes don't even need to be sorted -- %h[$n] would basically be a shorter way of saying @(%h.values)[$n], in whatever order .values would give you. Side issue: S09 doesn't specify whether or not you need to explicitly declare a hash as autosorted. I'm assuming that the parser is supposed to figure that out based on whether or not .iterator is ever used; but it isn't immediately obvious from reading the Autosorted hashes section. As well, there might be times when explicitly declaring a hash as autosorted (or not) might be useful for optimization purposes. Does the parser need to know? All hashes have an .iterator method, but you can override it to force elements to be returned using some particular ordering. Providing a flag for optimisation sounds useful... although since Perl doesn't do any sorting for you, if you want something more optimised than making .iterator re-sort the hash every time it's called, you'd have to replace the innards of the Hash type yourself anyway. But if you did make a Hash::Sorted class, defining an is sorted trait might be a nice way to use it. -David
Huffman encoding (was Re: treatment of isa and inheritance)
On 2008-Apr-30, at 1:29 pm, Brandon S. Allbery KF8NH wrote: On Apr 30, 2008, at 15:14 , Jon Lang wrote: On a side note, I'd like to make a request of the Perl 6 community with regard to coding style: could we please have adverbal names that are, well, adverbs? is :strict Dog brings to my mind the English -ly suffixes everywhere conflicts with Huffman coding, which per @Larry is a primary design concern. Consider the leading colon to be the Perl6 equivalent. Logically, yes, a : on the front of a word is as good an indicator of an adverb as an ly on the end. Psychologically, however, it isn't; for one thing, my mind doesn't pronounce punctuation the same way as letters. Whatever the reason, I've been reading English for decades longer than I have P6 (and by the time I've spent that many decades getting familiar with P6, I'll be even more familiar with English... which is of course one of the reasons why Perl tries to look kinda sorta like English in the first place; it may as well try to look like half-decent English!). But the more general point I wish to make is that extra characters don't necessarily conflict with the goal of Huffman encoding. I assume the idea was that extra 'ly's everywhere take up space that isn't needed -- of course Huffman himself was concerned with minimising bits, but in terms of Perl what we're interested in is efficient understanding, not efficient storage. Now short code is not a bad first approximation to understandable code, since longer reading-time will contribute to longer understanding-time. But that's only a very rough rule of thumb: if something is too short, it will take even more work to figure out what it's saying, and thus any time saved by shortness will be swamped by the much greater effort to figure out what the heck it means. (In this particular example, it seems quite reasonable that the cognitive dissonance from seeing an adjective where one's English- trained brain is expecting an adverb will outweigh the negligible time it takes to scan a couple of extra letters.) That's why Perl6 has abandoned all the punctuation-variables from P5 in favour of their use English equivalents. Real words are longer to read (and write) but easier to understand overall. (Of course, more characters are less efficient to type, but except for throw-away one-liners, code gets written once and read multiple times, so Huffman meta-encoding dictates that we should optimise for reading. And anyway, making code more efficient to write is the job of one's text-editor, not the language. Maybe we should work on auto- completion files for popular editors that will expand things like :str into :strictly, etc.) -David
Re: assignable mutators (S06/Lvalue subroutines)
On 2008-May-27, at 9:40 am, Dave Whipp wrote: TSa wrote: method inch { yield $inch = $.mm * 25.4; self.mm = $inch / 25.4; } Would you regard that as elegant? That looks functionally incorrect to my eyes: if the caller resumes at the time of the yield statement, and immediately assigns a new value to the mm attribute, then there is a race between the two updates to mm. It seems overly complex to me, but perhaps I'm missing good reasons for such an approach. I see lvalue subs mainly as syntactic sugar: foo(42); # arg using normal syntax foo == 42; # arg using feed syntax foo = 42; # arg using assignment syntax Feeds are a way of passing values to a function, but work like assignment when used on a variable; assignment is a way of giving a value to a variable, so it should work like passing args when used on a function. Then you can easily do whatever you want with it. In fact, it could work just like a feed, and pass values to the slurpy params, but I think assignment is special enough to be worth treating separately. Maybe something like: sub foo ($arg1, $arg2, [EMAIL PROTECTED], =$x) {...} foo(6,9) = 42; # the 42 gets passed to $x That example uses a leading = for the assigned param (parallel to the leading * for the slurpy param), but I'm not crazy about it for various reasons (and =$x refers to iteration in other contexts). Perhaps it could be identified as $x is assigned -- but that doesn't look quite right to me either. However it's written, it would be simpler than having to use proxies. -David
Re: nested 'our' subs - senseless?
On 2008-May-6, at 6:07 am, TSa wrote: Just to ensure that I get the our behavior right, consider sub foo { our $inner = 3; } sub bar { our $inner = 4; # redeclaration error? } say $inner; Does this print 3 even when foo was never called? No, it throws an error about $inner not being declared properly -- just as in P5 you'd get 'Variable $inner is not imported. Global symbol $inner requires explicit package name'. There's no redeclaration error in bar() because it's declaring the name for the first time (in bar's scope, that is), and then (re)assigning a value to $inner, which is fine. If foo said our Int $inner and then bar said our Str $inner, that should be an error though. sub foo { our $inner = 3; } sub bar { our $inner = 4; # fine, assigns or re-assigns $inner } say $inner; # error, name $inner not recognised here our $inner; # now the name is available in this scope say $inner; # OK, $inner is undef foo; say $inner; # prints 3 bar; say $inner; # prints 4 IOW, is the assignment in foo a real one that only happens when foo is invoked or is it a pseudo-assignment that initializes the variables as if the whole statement where outside of foo? The assignment happens only when foo() is invoked. However, the variable $*Main::inner is declared at compile-time. Similarly, an our sub inner inside foo() would declare the name, but you couldn't call inner() until after running foo() --or bar()-- since you can't call an undefined sub. The consequence of a sub not doing Package is that there are no separate foo::inner and bar::inner classes as in class foo { our class inner { has $.x = 3 } } class bar { our class inner { has $.x = 4 } } say inner.new.x; # error: no inner in scope My personal idea is to unify class and sub by allowing sub to do Package. I don't understand what a sub doing Package is supposed to do. I think you get the same thing from that last example whether foo and bar are classes or whether they're subs: either way, bar will raise a redefinition error, and say inner.new.x will throw a no 'inner' in scope error. -David