Re: Do slurpy parameters auto-flatten arrays?
HaloO, Luke Palmer wrote: On 8/3/05, Aankhen [EMAIL PROTECTED] wrote: On 8/3/05, Piers Cawley [EMAIL PROTECTED] wrote: So how *do* I pass an unflattened array to a function with a slurpy parameter? Good question. I would have thought that one of the major gains from turning arrays and hashes into references in scalar context is the ability to specify an unflattened array or a hash in a sub call without any special syntax... I thought that the obsoletion of special syntax stems from the type system. Piers seems to have the same view. See his example of map in his parallel reply. Well, you can, usually. This is particularly in the flattening context. In most cases, for instance: sub foo ($a, $b) { say $a } my @a = (1,2,3); foo(@a, 3); Passes the array into $a. If nothing flattened by default, then you'd have to say, for example: map {...} [EMAIL PROTECTED]; And even: for [EMAIL PROTECTED] - $x {...} Which I'm not sure people want. Ups, I thought the for special form would work as follows. 0. the syntax: for expression block 1. determine (return) type of expression 2. create an iterator for that type 3. Use the iterator until it runs out (is that when it returns undef?) 4. bind the block owner to successive return values of the iterator and call the block; if the block is pointy bind its environment as well. With the above for @a - $x {...} # use Iterator of Array and for [EMAIL PROTECTED] - $x {...} # use Iterator of List produc the same sequence of values in $x but through different paths in type space. As long as no user defined types are involved, I dought they are distinguishable at all. Here's an idea how a sub becomes its own iterator: sub foo() does Iterator[foo] { random; } for foo() - $x { say } # endless loop of random output How are roles/types composed into Code subtypes? And the way you pass an array in slurpy context as a single reference is to backwhack it. What it comes down to is that either you're backwhacking things a lot or you're flattening things a lot. Perl currently solves it by making the common case the default in each zone of parameters. I would be interested to hear arguments to the contrary, however. OK, I gave my 0.02. -- $TSa.greeting := HaloO; # mind the echo!
Re: If topicalization
On 8/4/05, Luke Palmer [EMAIL PROTECTED] wrote: How can that possibly work? If a bare closure { } is equivalent to - ?$_ is rw { }, then the normal: if foo() {...} Turns into: if foo() - ?$_ is rw { } And every if topicalizes! I'm sure we don't want that. Luke Here's one solution: 1) Bare blocks don't topicalise if you call them without an argument. 2) 'if' doesn't pass the value of the condition to its body, _UNLESS_ the body is incapable of accepting 0 arguments. This means: * The most common case, if foo() { ... }, won't topicalise. * If you /really/ want to access the value of the conditional, you can say one of: if foo() - $_ { ... }# topicalise if foo() - $cond { ... } # don't topicalise and 'if' will give it to you. * The bare-block-to-pointy-sub rewrite rule is preserved, because a bare block's parameter is optional. Is there anything I've failed to take into account? Stuart
Re: zip with ()
HaloO, Luke Palmer wrote: On 8/1/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: In general, (@foo, @bar) returns a new list with the element joined, i.e. @foo.concat(@bar). If you want to create a list with two sublists, you've to use ([EMAIL PROTECTED], [EMAIL PROTECTED]) or ([EMAIL PROTECTED], [EMAIL PROTECTED]). But of course, I could be totally wrong. :) I think that's right. However, it might be a good idea not to auto-enreference such bare lists: I don't like this notion of auto enreference/dereference at all. Either the type system manages to dispatch things correctly or you get an error. For the List versus Array problem this dispatch is IMHO decideable at compile time by strictly typing @ vars as Array and subtypes thereof. The List type to me is a Code subtype and as such travels in vars. I'm only unsure how easily such variables should enter name space, that is how they behave without sigil. sub foo ($x) {...} foo (1,2,3,4,5); # foo gets called with [1,2,3,4,5] Yes, the $x makes foo an Item or even Value taker of arity 1. The call foo (1,2,3,4,5) OTOH calls it with a List. This should result in a type error. But sub foo (x) might then work for a List but not for an Item|Value call foo(1). Since I think that * in a signature is for extending the arity of the sub to infinity I wonder if it is possible to capture the caller's list into a single *$arg? sub foo (*$x) {...} foo (1,2,3,4,5); # type of $x is now Ref of List of Int? But with an additional array the slurpy item gets at most one value. sub foo (*$x, [EMAIL PROTECTED]) {...} foo (1,2,3,4,5); # $x == 1; [EMAIL PROTECTED] == 4 foo @array; # type of $x is now Ref of Array; @a is undef When you could just as easily have said: foo [1,2,3,4,5]; And we'll probably catch a lot of Perl 5 switchers that way. That actually makes a lot of sense to me. The statement: my $x = (1,2,3,4,5); Looks like an error more than anything else. Yep. I opt for type error Can't assign List to Item. By the same token I would disallow my @a = 3; # type error Can't assign Item to Array. It should be my @a = *3; or my @a = (3,); Hmm, wasn't there a nullary *? my @a = *; say [EMAIL PROTECTED]; # prints 0 That's the scalar comma, which has been specified to return a list. But maybe it should be an error. Sorry, I don't understand this. I thought comma just is *the* List constructor per se. Parens required to lift precedence :) Same applies to semi-colon. (1,2,3;4,5,6) is a List of List of Int. The main reason that we've kept a scalar comma is for: loop (my $x = 0, my $y = 0; $x*$y = 16; $x++, $y++) {...} However, I think we can afford to hack around that. Make the first and last arguments to loop take lists and just throw them away. My interpretation of the loop block controler special form is that it gets a 4-tupel (Block,Block,Block,Block). The last one is of course the loop's body. The first is the initializer that is executed in a scope outside the body. The second and third are the condition and the stepper and also scoped outside the body. Now to the comma. It should be parsed as List of Block. In your example the argument type of loop is (List of Block,Block,List of Block,Block). The loop instanciates an Iterator[List of Block] and uses it to execute the Blocks one at a time. The only special case is in the condition which evaluates only the last Block from the List of Block for truth and the others in Void context. Is loop supposed to be a topicalizer? Does it bind the block owner? Does a pointy body block make sense? loop (my $x = 0; $x 10; $x++) - {...} # current count in $_? loop (my $x = 0; $x 10; $x++){...} # $_ unchanged from outside? loop (my $x = 0; $x 10; $x++) { .blubber # what is the invocant? } Can the last Block also be separated with semi-colon? I guess not. How about a Code var? loop my $x = 0; $x 10; $x++; say $x; # works? loop my $x = 0; $x 10; $x++; foo; # works? loop( my $x = 0; $x 10; $x++; foo ) # perhaps as function call? loop my $x = 0; $x 10; $x++; say $x; # still the loop body? Or does it need { say $x }? loop foo; bar; blubb - { say # prints return value of blubb while bar returns true # first iteration prints return value of foo } Can anyone think of any other common uses of the scalar comma? Not me. It's a C relict. -- $TSa.greeting := HaloO; # mind the echo!
Re: Do slurpy parameters auto-flatten arrays?
HaloO, Piers Cawley wrote: By the way, if flattening that way, what's the prototype for zip? We can after all do: zip @ary1, @ary2, @ary3, ... @aryn How about sub zip( List [EMAIL PROTECTED] ) {...} a slurpy List of Array of List. The return value is a not yet iterated Code object that knows how to produce tuples from the outer lists. This implies that zip(@array) basically returns an unstarted iterator on @array. -- $TSa.greeting := HaloO; # mind the echo!
TSa's Perl 6 type lattice version 1.0
HaloO, in case someone might be interested, here is my more or less complete idea of the Perl 6 type lattice as ASCII art. Enjoy. Comments welcome. ::Any ...| ... ___:___/|\:_: | :| : | | static type : Package:| : Void ?Bool = context : | :| :__|__| : Module:|/:.: ___|___:| | | :| Class Grammar :| |___| :| | :| Role : Object Record =::= Frame =::= Dictionary :| : __/ \_ with:| || || | invocant(s) : Code $Item%Hash Frame@Array Tuple :| ||_||___| block owner : topic | | | $/ : $_ | | | :___/ \_ ___| | |: |\ | || | | | | .Method : Sub\ -Block \Ref Value Undef Inf Junction | /|: |\ \ || | / |: | \ \ __||_ | Rule |: | Macro \/ || | | || |:_/|Ref[Code] | :Pair /Match/ ~Str +Num | |: ||| | || Multi : ||| |Int | ..: ||| | / || ||___ ___| Enum || || \/ | || || Entry[::T.does(Hash)] Bit || _|__ |___ _|| || | \/ | =Iterator *List | Pos[::T.does(Str|Array)] | | | | |_ _|___| | | ||\ / | ..Range Pipe Lazy **Eager Ref[Array|Hash] | |__|_|| _| \ / (to | all leafes) \|/ ::All -- $TSa.greeting := HaloO; # mind the echo!
Re: zip with ()
On Mon, Aug 01, 2005 at 01:13:52PM +0200, TSa (Thomas Sandlaß) wrote: : BTW, you didn't mean originally: : : say zip (@odd), (@even); # prints 13572468 or 12345678? That doesn't work, since () in list context does not enforce scalar context. It's exactly equivalent to say zip @odd, @even; which is also wrong, because zip is requires multidimentional slice syntax. Ordinary commas will be taken to separate items of the first slice. To separate slices requires semicolon or pipes. : Does zip now interleave two array refs instead : of flattened arrays? No, but separating the arrays with comma doesn't work either, so Pugs currently has it wrong. The correct syntax will eventually be: zip(@odd; @even) zip @odd == @even The parens are required only at the top statement level. Inside other bracketing structures you can omit the parens: (zip @odd; @even) just as in subscripts the semicolon separates multiple dimensions: @[EMAIL PROTECTED]; @b] Larry
$pair[0]?
Hi, my $pair = (a = 1); say $pair[0]; # a? say $pair[1]; # 1? I've found this in the Pugs testsuite -- is it legal? --Ingo -- Linux, the choice of a GNU | Black holes result when God divides the generation on a dual AMD | universe by zero. Athlon!|
Re: undef.chars?
On 8/4/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: Hi, (found in the Pugs testsuite.) my $undef = undef; say $undef.chars? # 0? undef? die? say chars $undef; # 0? undef? die? I'd opt for undef.chars to be an error (no such method) and chars undef to return 0 (with a warning printed to STDERR^W$*ERR). Well, I think that chars $undef should be exactly equivalent to $undef.chars. In fact, I think it is: chars $undef is just the indirect object form. So perhaps method not found errors fail instead of die. Luke
Re: $pair[0]?
Hi, Luke Palmer wrote: On 8/4/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: my $pair = (a = 1); say $pair[0]; # a? say $pair[1]; # 1? I've found this in the Pugs testsuite -- is it legal? Nope. That's: say $pair.key; say $pair.value; Also: say $paira; # 1 say $pair{anything else}; # undef But we don't implicitly cast references like that. thanks for clarification, that's what I've thought, too :) --Ingo -- Linux, the choice of a GNU | The next statement is not true. generation on a dual AMD | The previous statement is true. Athlon!|
Data constructors / Unidirectional unification
I'm writing a new module that optimizes sets of conditions into decision trees. Initially I allowed the user to specify conditions as strings, and if that condition began with a !, it would be the inverse of the condition without the !. But then I thought, the user will more than likely have condition *objects* if the conditions are anything but trivial. Then you can't just put a ! on the front. The way Haskell and ML do this is by allowing data constructors: symbols that can take arguments and be pattern matched against. I thought that this was a particularly elegant way to solve the problem, so I implemented it in the Symbol::Opaque module. Now I want it for Perl 6. Here's my proposal. Let's generalize the backtick from unit support into data constructor support. The following are equivalent: 4`meters `meters(4) The postfix form is only available for single-argument constructors, but the prefix form can be used with more than one argument: `foo(4, 5) These things don't need to be declared, but you can use a data declaration to give them a type (which does Symbol, the type of all such constructors): data Quux (`foo, `bar, `baz); Now whenever you create a `foo, it is a Quux. These can overlap: data Foo (`baz); data Bar (`baz); A `baz object is now both a Foo and a Bar. These could be easily extended to allow type signatures, to come up with those nice type-checked data structures that we're using for PIL. But I'm not proposing that part yet. Here's what makes them so useful: they can be bound against: sub to_SI (`meters($m)) { `meters($m) } sub to_SI (`feet($f)) { `meters(feet_to_meters($f)) } Here's an excerpt from my module (perl6ized): sub invert ($in) { my `not($x) := $in ?? $x :: `not($in); } Or maybe that's: sub invert ($in) { `not(my $x) := $in ?? $x :: `not($in); } Anyway, the point is that bindings can fail. In boolean context, they return whether they succeed; in void context, they blow up if they fail (probably fail). As multimethods: multi invert (`not($x)) { $x } multi invert ($x) { `not($x) } Which I like the best. Pairs are values: like numbers. `foo =:= `foo. They can just have sub-values.
Re: undef.chars?
Luke Palmer [EMAIL PROTECTED] wrote: On 8/4/05, Ingo Blechschmidt [EMAIL PROTECTED] wrote: my $undef = undef; say $undef.chars? # 0? undef? die? say chars $undef; # 0? undef? die? I'd opt for undef.chars to be an error (no such method) and chars undef to return 0 (with a warning printed to STDERR^W$*ERR). Well, I think that chars $undef should be exactly equivalent to $undef.chars. In fact, I think it is: chars $undef is just the indirect object form. Didn't $Larry rule that method calls on undef return undef, for the same reason array and hash subscripting does? -- Brent 'Dax' Royal-Gordon [EMAIL PROTECTED] Perl and Parrot hacker