S04 -- closure traits clarification
Greetings, In trying to hack closure trait support into pugs, I have some questions about closure traits, variable with will traits and introspection. (Apologies if some of this has been discussed on the list before -- I'm just going off of the synopses, which if definite clarification on some of these issues has been made, should probably be updated to reflect the decisions made.) Firstly, it is suggested in S04 that variables indicated with a will predicate contribute to the corresponding block-level trait. I.e., if we have the following bit of code: if $dbh { my $sth will undo {$dbh.rollback} will keep {$dbh.commit} = FIRST {$dbh.prepare($query)}; UNDO { say DB error!; } KEEP { say We're good!; } } Then the block has in effect 5 total traits, 2 UNDO block, 2 KEEP blocks and 1 FIRST blocks. From what I understand, the blocks for each trait are executed in FIFO order, thus we would rollback before we report the error in this contrived example. Questions: 1) What type of introspection, if any, are we providing to the language level? I.e., are we providing something along the lines of %traits = ?BLOCK.traits where %traits is keyed on trait name (FIRST, LAST, whatever) and in turn is an array of closures? This would mean, for instance that we could say ?BLOCK.traitsFIRST to get the current block's FIRST closures, if any. When parsing the block for traits, coming across a new FIRST block would be akin to saying: push ?BLOCK.traitsFIRST, {...block contents...} Specifically, I'm looking for definition of the syntax, which is only alluded to in the Synopsis. 2) If we accept the introspection at the block-level above, it seems clear that we should also accept the same .traits method on variables. I.e., in the above DBI example, we should get back the closure(s) for undoing by referring to $sth.traitsUNDO. Is a variable-level trait a single entry, or can we have multiple will undo {...} predicates on a single variable? (The utility of such is left as an exercise to the reader.) 3) User-definable traits. Now, this may be a closed domain of sorts, but do we need to allow for the possibility of user-defined traits? (I'm thinking here of variable-level will predicates.) If so, do user-defined traits get normalized to UPPER? It would seem like we would want consistency here, because if will undo {...} and UNDO {...} get stored in the same trait slot, we're obviously transforming one of the identifiers -- should this behavior be specific to our built-in ones, or to all traits? 4) Which of the closure traits are supported as will predicates on variables? Not all of the closure traits make sense on the variable-level -- this information will be useful when trying to parse the will predicates. Thanks, David Christensen
junctions as indicies
I'm looking in S09, and reading about junctions. It seems to me that if we have a junction $j which we use to index into an array or a hash, it should DWIM and return a junction of the corresponding values. @ar=[1..10]; %hash=(a=1,b=4,c=7); $j=1|2|3; $k=a|c; $u = @ar[$j]; # 2|3|4 $v = %hash{$k}; # 1|7 Does this make sense to others? David
junction adverb: :except
Hypothetical here: If we want to calculate a set of values for a junction which map nicely to a range with a few outliers, would it be possibly to have a qualifier :except which allows us to make exceptions to our given range? I.e., (Ignore for the moment the inefficiency of the choice of this particular algorithm.) my $year = 1900; # or whatever my $leap_year = $year % 400 == any(0..400 :by(4) :except(100,200,300)); Here except would be a modifier on the range being generated for any(). I could also see except being used to strip choices from junctions: my $j = 1|2|3|4; my $k=$j :except(2); # 1|3|4 Let me know if I'm totally abusing junctions here... David
Hyper-slices?
Quick thought --- Does the current design of Perl 6's hyper operators allow for hyper-slices? I.e., if I want to model a matrix by using a list of lists, is the following code valid/useful? my @matrix=([1,2,3],[4,5,6],[7,8,9]); my @row = @matrix[0]; # first row my @col = @matrix[0]; #first column my @transposed = @matrix[0..2]; I don't know if this case has been discussed earlier; is extracting an element considered a unary operation? Is there some use for this notation, other than what I just said? I suppose the same could be said for Lists of Hashes: my @records=({name=Tom,age=27},{name=Dick,age=33}); my @names= @records{'name'}; say @names; # Tom Dick Of course, for this to be useful, the lists would have to be homogenous; @array is List of Hashes (excuse the syntax; I'm still getting up to speed with a lot of the P6 specific issues). Again, apologies if this is a closed domain/already has some other method of retrieving the same information. Thanks, David Christensen
Re: Hyper-slices?
I definitely like the hyper stuff how it is; maybe the answer is to just define an infix:[[]] operator which returns the crosswise slice of a nested list of lists. In any case it could be shunted aside to some package and certainly does not need to be in core. David my @transposed = @matrix[0..2]; The thing that makes me wonder about that is whether it builds anonymous arrays inside for you, or whether it just flattens everything out. Obviously in this case it *should* give you arrays. On the other hand, if you did the standard map transform that hypers do: my @transposed = map { $_[0..2] } @matrix Then it's clearly flattening. What I'm currently thinking is that Perl is terrible for matrix stuff. Maybe we should keep it that way, and punt to PDL. But as it stands, we have no hope of appeasing the mathematicians in this area without really redoing hyper stuff. And I think that the hyper stuff is pretty close to right for non-matrix purposes, so it would be hard to redo it without perturbing what we have. Luke
Hyper operator corner case?
Hey folks, I wanted to delurk and address an issue that may need clarification in regards to hyper operators. Quoting S03: If one argument is insufficiently dimensioned, Perl upgrades it: (3,8,2,9,3,8) - 1; # (2,7,1,8,2,7) Now in this example case, it's pretty clear that the scalar 1 gets turned into a list of 1s with the length of the lhs. What about the case of a larger-dimensioned or single-dimensioned array? Example: (1,2,3,4,5) + (1,2) Is this equivalent to: a) (1,2,3,4,5) + (1,2,undef,undef,undef) (undef padding) b) (1,2,3,4,5) + (1,2,1,2,1) (repetition) c) (1,2,3,4,5) + (1,2,2,2,2) (stretching) d) (1,2) + (1,2) (truncation) e) something else, ie, warnings about mismatched dimension, die(), segfault, kill -9 1 (whatever your sadism level is). Additionally, I was wondering if there was a difference between: (3,8,2,9,3,8) - 1 and (3,8,2,9,3,8) - (1) I suppose the answer to that depends on the answer to the above question. If the answer is the a) case as above and undef resolves to 0 numerically, then we run into another issue to consider. In the case of addition and subtraction, 0 is the identity element, and so: (1,2,3,4,5) + (1,2) yields (2,4,3,4,5). But the intuitiveness goes away with multiplication, and completely blows up with division: (1,2,3,4,5) * (1,2) yields (1,4,0,0,0), probably not what we wanted. (1,2,3,4,5) / (1,2) yields (1,1,NaN,NaN,NaN), and probably die()s with division by zero errors. If in the addition and subtraction cases we want to preserve the identity cases for the slots not accounted for, undef is fine because it resolves to 0; to provide the same features for multiplication and division, the identity element would have to be 1. But that would suppose that the potential hyper-operators would know what their appropriate identity elements were (and that such a thing is meaningful to them). Additionally, if there is a difference between the automatic scalar promotion and list promotion, we could run into errors where people would expect an expression to be a scalar which would be promoted in the documented fashion, but would really be promoted in one of a)-e), breaking what they expected: (1..5) + ($a-$b) # list context for the expression? Promotes like what? (1..5) + +($a-$b) # forced scalar context -- promotes like documented. (1..5) + (1) # promotes like what? Thoughts? David Christensen
Re: Hyper Here-Docs? (was: Re: angle quotes for here-docs ?)
Incidentally, just like mathematically (albeit slightly loosely) an element of a set can be thought of as a function from any singleton, would it be possible for Perl 6 to provide a fast (under the syntactical point of view) way to promote a term to a function returning it? What's wrong with the perl 5: sub mysub($x) { return sub { $x }; # the sub{$x} is the construct } ? David