develooper Front page | perl.perl6.language | Postings from July 2002

what's new continued

Thread Next
July 1, 2002 04:54
what's new continued
Message ID:

me again,

At the moment based on Apo1->4 no ex's "walked" yet.
- There is a questions inside feel free to answer ... [?? ... ??]
- Also links for other reference implementation will be good.
- Also feel free to correct my english :")

What's new ?

Let me first mention this is in no means full list of the new features in Perl6, this is mostly a list pf those features I find most entertainig.
For a detailed description look at all these links :

And to see what the Larry and crew had to take into account look here :

So lets start............

1.) Proprietes ==============================
reference implementation : Attribute::Types, Attribute::Handlers, Attribute::Handlers::Prospective

Every subrotine or variable or method or object can have a "notes" (out of bound data) attached to it and they are called "properties". (Internally properties are hashes --> pHash).
The proprietes can be compile time and run time... (the common case is they to be compile-time)
Samples :

my $x is constant = 5;#this says that $x is constant and its value is 5

my $x is foo = 0;
Now $ is equal to 1, but $x is 0. In fact $ is interpreted as method call i.e. $
If there is no method with name foo() then such method is pretended to exist and it returns the value of property with that name.


will return hash-ref to properties hash i.e. pHash-ref.
So that :

print keys %{$x.prop}

will print "foo" (and probably if SCALAR's have some default props they will be printed too)
U can also just use : 

print keys $x.prop

since the hash ref returned by .prop will be automatically dereferenced by the hash context of "keys".
(In Perl6 we will have much more contexts than that we had under Perl5. Here are part of them :

 Void context
    Scalar context
        Boolean context
        Integer context
        Numeric context
        String context
        Object context
    List context
        Flattening list context (true list context).
        Non-flattening list context (list of scalars/objects)
        Lazy list context (list of closures)
        Hash list context (list of pairs)

And we will have much more powerfull "want" operator so that we can check the context in which the sub are executed.

U can specify more props at once and also skip "is" keyword like this :

my $i is constant note('I use this var for loop counter') maxValue(100)  = 0;

instead of :

my $i is constant is note('I use this var for loop counter') is maxValue(100)  = 0;

then :

print $i.prop{note}

should print "I use this var for loop counter".

2.) Multiway comparison ==============================

Now we can say :

    0 <= $x <= 10 

to check if $x is between 0 and 10 inclusive i.e. 0 <= $x && $x <= 10

3.) Hyper operators ==================================

Cool no more loop-in-loop-in-loop....:"). All operators can be hyper-ed simply prepend them with "^" - upper-cap.
Samples :

@a ^* @b 

multyplies both arrays and will return a list of ( $a[0]*$b[0], $a[1]*$b[1], ... $a[n]*$b[n] ) 
( @a[0]*@b[0], @a[1]*@b[1], ... @a[n]*@b[n] ) if we use Perl6 notation/syntax.

@a ^+ 1

will return a list of all elements of @a increased by one. (@a stays uncanged).

  @a ^&& @b

will produce a list of  (@a[0] && @b[0], @a[1] && @b[1] ...)  
  @a ^|| @b

will produce a list of (@a[0] || @b[0], @a[1] || @b[1] ...)

Here is how in one sweep we can change some text in every element of array :

  @foo ^=~ s/foo/bar/
And how to increase the elements of array with 1 but this time applying the changes to the @a   

  @a ^+= 1

we can even have hyper-assignment :

my ($a, $b) ^= new Foo;

The expression below will not distribute over $a and  $b :
my ($a, $b) = new Foo;

Let's someone of the anti-perl camp tell me that this "upper-cap noise" makes the code hard to read and I will smash him with a hammer in the head :") and leave him to type "from here to tommorow loop after loop after loop after loop" :"). Gees those perl designers with LW in the head are mad-scientists .....

4.) Binding  ==================================

In addition to the standard assignment operator of perl5 "=" we will also have ":=" i.e. bind operator.
<snip - apo3>
If you're familiar with Prolog, you can think of it as a sort of unification operator (though without the implicit backtracking semantics). In human terms, it treats the left side as a set of formal arguments exactly as if they were in the declaration of a function, and binds a set of arguments on the right hand side as though they were being passed to a function. This is what the new := operator does.

Another way of thinking of it is that:

$a := $b

makes $a another name for the variable currently known as $b (i.e. aliasing).
in pseudo-code you should imagine something like this :

sub xxx($a) { ..... your program here ..... };

that is to say that from now on $a is $b. Aliasing is usefull also in the following ways :

$x := $ary[0]{keylevel1}{keylevel2}

Now instead of writing all those keys just use $x{keylevel4}
Perl6 syntax : 
%x := @ary[0]{keylevel1}{keylevel2};
print %x{keylevel3};

More examples :

(@a, @b) := (@b, @a)

this swap the two arrays.

&sub2 := &sub1;

now calling sub2() is the same as calling sub1()

5.) Binary // - defaulting operator.========================================

This is very handy operator, it will save us alot of keystrokes :") f.e :

  $a // $b 

means the same as 

defined($a) ?? $a :: $b

i.e. if $a is defined it will return $a otherwise it will return $b.
One other way to using it is :

  $a //= 5;
i.e. $a will become 5 only if it is already defined.

6.) Parenthesses in some builtins go away if u want ofcourse. ================================
So we again can save keystrokes :") . example :

    if $foo { ... }
    elsif $bar { ... }
    else { ... }

    while $more { ... }

    for 1..10 { ... }
isn't that much more readable and faster to type.    

7.) Quantum superpositions ===============
reference implementation : Qunatum::Superposition

What this phisics have to do with Perl6 ?
To understand it better I had to read some stuff about "parallel-universes" which i found on google :")
The idea is simple think of the words "any", "all" i.e. trought one object we describe many (our universe is the way we are percieving the infinity universes that exists, probably :") )
So the examples then :

 if ($x == any($a, $b, $c) { ...  }
 if any of the variables equals $x then the code will be executed. Probably we will be able to say :
 $x ^== ($a,$b,$c)
 too. The difference as I understand it in that particular case is [?? correct me if i'm wrong ??] :
 case1 - superposition :
 if ($x == $a || $x == $b || $x == $c) { ...  }
case2 - hyperoperator :  
my $result = 0;  
for ($a,$b,$c)  {
   if ($x == $_) { $result =1; last}
See in the superposition the "operation got multiplied in a way" (one view of the universe), but in the hyperoperator case the operands got "spread in a way around the operator". [?? very obscure decription :"), remember i'm explaining this to myself ??]

Next examples :
while ($nextval < all(@thresholds) { ... }
This time all() binds the @threshold with && not with || as it was with any().

$max = any(@value) < all(@values);

Now we have both || and &&...

9.) SWITCH  ================================
You may asked :
- "When" to the "switch" "case" will be "given" a solution ?
( To the "switch" "case" solution will be "given", "when" ? - Yoda-style :") )
- In Perl6 of course.

--> "When"  perl6 is "given" to us. A "switch" will be made.

reference implementation : Switch

Ok, Perl6 now finally have switch-case statment but we use keywords given-when instead. It is very complex (i mean that there is many variations for comparison. look at Apo4 for details) but it work as ppl would expect. Simple example :

given $a {
   when 5 { print "A is 5" }
   when 1 { print "A is 1" }
   default { print "A is neither 1 neither 5" }

The reason swich first appear now is that the Perl switch is much more powerfull than the switch operator in all other languages (you can read the whole comaprison-matrix in Apo4). Lets continue with our examples :

given $a {
  when /xxx/ {print 'the string contains (xxx)"};
  when /\d+/  {print 'Oooo u use numbers' };
  when /f..k/  {print "Don't f..k with me !" }

this speaks of itself, let see more complex one :

given @a {
 when /xxx/ { print 'There is element in the array that contains (xxx)' };
 when 5      { print 'Elemnt 5 from the array is truth i.e. non zero'};
 when %b   { print 'I see there is element with that name /from the list u passed to me/' };
 when (5,6,9) { print 'At least one element of the array is equal to 5, 6 OR 9' };
 when /abc/ { break when 5 };#doesn't check next when's if there is elemnt which contain 'abc' 
 		    #and element 5 is true
                     #[?? does "when 5" compare to @a or to the @a <-> /abc/ comparison result ?
 when mysub(@) { print 'mysub(@a) returned true' };#[!! is mysub(@) correct]
 when mysub() { print 'mysub() returned true' };
 when $a[7] == 12 { print 'u guess it' };

There is alot more ..... we can compare objects, scalars, arrays, hashes, any way u can imagine ...
Now u know why switch statement appears so late (If u do it, do it once and for all).

8.) Blocks are closures and exceptions too =================================

("try" can be skipped 'cause every block in Perl6 is a "try"-block.)

try {
 PRE {} - execute before anything in the block
 CATCH {} - catch any exception i.e. exception handling goes here, only one catch is allowed
 POST {} - execute after everything in the block is executed.
 KEEP {} - executed if the block succeed
 UNDO {} - executed if the block fail
 NEXT {} - like Perl5 "continue". It is called only before attempting the next iteration of the loop. It is not called when the loop is done and about to exit.
 throw ...

[!! There was discussion on perl-language list about additional WORDS, could someone summarize them and their meanings. They were discussed in the relations with the loops if I recall !]

and all they (except CATCH) are in fact proprietes of the block, isnt that cute :"). And so we can do  :

    my $f is keep { close } = open $file;
which is something like this :

try {
 my $f = open $file;
 KEEP { close $f }

[?? the apo4 uses undo instead of keep, 'm I right ??]

CATCH is a switch statement (so all sematics of "given" applys) and comparison is between $! var and $!.isa(..) so that [!!hard to formulate it]:

  when Error::DB {};
  when Error::XX {};

is :

CATCH $! {
  when $!.isa(Error::DB) {};
  when $!.isa(Error::XX) {};
  default die;#!! not sure

(The name of the top exception class will be X, but not Exception as u may expect. The rationale here is that if it is shorter the ppl will be more encouraged to use it)
in Perl 6. A try with no CATCH:

    try { ... }

is equivalent to:

    try { ... CATCH { default { } } }

- try {} is the new spelling of eval {}, eval will be used only to evaluate strings.
- the unified "current exception" is $!

The good thing about all this is that using exceptions will not require so much additional syntax and "additional-thinking" (it is so stright-forward) of how-to-use-it/when-to-use-it as in other languages, a reason many of us didn't used it. (or atleast me :") )

10.) LOOPS =====================================
Ok now we can loop over many arrays at once and in many other cute ways...
First let me mention that 
%hash.kv - returns key,value pairs
@array.kv - returns index,value pairs

for @xyxyxy -> $x, $y { ... }

As u see this will walk over the array two elements at a time.

for @xxx; @yyy; @zzz -> $x; $y; $z { ... }

Here we walk one element at a time on all arrays in parallel.

for @ababab; @cdcdcd -> $a, $b; $c, $d { ... }

And now two elements at a time on both arrays in parallel.

for @a; @b; @c -> $x { ... }

One at a time across all arrays sequentally i.e. @a[0],@a[1],...@b[0], @b[1], ..., @c[0], @c[1], ... .

- If there is semicolon on the right there has to be the same number of semicolons on the left.

The following prints "a0", "b2", "c3", and so on forever (or at least for a very long time):

for 0 .. Inf; "a" .. "z" x 1000 -> $i; $a {
  print "$a$i";

- Do u see we have "Inf" and it will be evaluated lazely.
There will be no $# or such in loops to keep the current-index as many of us wanted (including me), i think the proposed from Larry way is better i.e. :

for @array.kv -> $i, $elem { ... }

for @foo -> $a is rw, $b is rw { ... }

As u see u can define $a and $b to be "rw" so that when u change them you are in fact changing the values of the @foo array, one more thing is that $a and $b are "my" variables. 

- C-style for-loop will become loop(expr1;expr2;expr3) { .... }.
- "continue" become a NEXT and goes inside the block.

To come soon when i have time...
SUBROUTINES ==========================================================
- Implict parameter specification syntax  
- higher-order functions i.e curring 
- Coroutines
 [?? The coroutine op is "yield" isn't it ??]

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About