Re: Recommended Perl 6 best practices?

2008-12-21 Thread Larry Wall
On Sat, Dec 20, 2008 at 11:45:38PM -0500, Brandon S. Allbery KF8NH wrote:
 On 2008 Dec 20, at 13:39, Carl Mäsak wrote:
 Maybe this counts as a best practice, or maybe it's more of a
 pattern. In a recent piece of code, I found a way to exploit code
 blocks to act like return statements with side effects. The
 resulting code became very clean, so I decided to blog about the way
 it works.


 Hm, couldn't you also do that with a sub that explicitly throws a  
 return exception to the caller Routine?

Which is most easily expressed as:

somesub.leave()

or

caller.leave()

if you want it anonymous.

But 'return' is shorter than that, and lambdas are shorter than
routine definitions, so the only reason for not using return
is if you want to define your helper block outside of the scope
in which return would work.

Larry


Re: Recommended Perl 6 best practices?

2008-12-20 Thread Carl Mäsak
Maybe this counts as a best practice, or maybe it's more of a
pattern. In a recent piece of code, I found a way to exploit code
blocks to act like return statements with side effects. The
resulting code became very clean, so I decided to blog about the way
it works.

 http://use.perl.org/~masak/journal/38123

// Carl


Re: Recommended Perl 6 best practices?

2008-12-20 Thread Brandon S. Allbery KF8NH

On 2008 Dec 20, at 13:39, Carl Mäsak wrote:

Maybe this counts as a best practice, or maybe it's more of a
pattern. In a recent piece of code, I found a way to exploit code
blocks to act like return statements with side effects. The
resulting code became very clean, so I decided to blog about the way
it works.



Hm, couldn't you also do that with a sub that explicitly throws a  
return exception to the caller Routine?


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com
system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon universityKF8NH




Re: Recommended Perl 6 best practices?

2008-10-01 Thread TSa

HaloO,

Martin D Kealey wrote:

Surely it is more important that ($a ne $b) should be equivalent to not( $a
eq $b ) regardless of whether either variable contains a junction?


IIRC, ne is just an abbreviation of !eq where ! in turn as a meta
operator means to pull the negation to the front. Are junctions
overruling that mechanism? I think we should have negation only on
a single boolean not on the operator itself which is strange if used
multiple times. That is, the operator that sees the junction is the
operator the negation was applied to.

IOW, I would expect

   if  $a  ne $b  {...}
   if  $a !eq $b  {...}
   if!($a  eq $b) {...}
   unless  $a  eq $b  {...}

to be fully equivalent forms where the negation is moved further to the
top of the parse tree from step to step.

This raises the question how the negation meta operator relates to
other meta operators e.g. does ([!==] $a,$b,$c) mean !([==] $a,$b,$c).
I have no idea how difficult such negation propagation in parse trees
is.


Regards, TSa.
--

The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Recommended Perl 6 best practices?

2008-10-01 Thread TSa

HaloO,

one nifty thing could be negation propagation in chained
comparisons:  ($a ne $b ne $c) === !($a eq $b || $b eq $c).
This again insures some sanity if any of $a, $b or $c are
junctions. BTW, the boolean connectives , || and ^^ shouldn't
be auto-threaded through junctions.


Regards, TSa.
--

The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


Re: Recommended Perl 6 best practices?

2008-09-30 Thread Patrick R. Michaud
On Tue, Sep 30, 2008 at 02:31:46PM +1000, Jacinta Richardson wrote:
 Carl Mäsak wrote:
  The correct form using junctions would be this:
  
  die Unrecognized directive: TMPL_$directive
 if $directive ne 'VAR'  'LOOP'  'IF';
 
 which makes sense, because this does give us:
 
   $directive ne 'VAR'  $directive ne 'LOOP'  $directive ne 'IF'

Just for pedantic clarity, what C $directive ne 'VAR'  'LOOP'  'IF' 
really gives is

all( $directive ne 'VAR', $directive ne 'LOOP', $directive ne 'IF' )

In other words, the result of the expression is an all() Junction.
In boolean context this would indeed evaluate to false if $directive
has any of the values 'VAR', 'LOOP', or 'IF'.

Pm


Re: Recommended Perl 6 best practices?

2008-09-30 Thread Martin D Kealey

On Tue, 30 Sep 2008, Patrick R. Michaud wrote:
 Just for pedantic clarity, what C $directive ne 'VAR'  'LOOP'  'IF' 
 really gives is

 all( $directive ne 'VAR', $directive ne 'LOOP', $directive ne 'IF' )

 In other words, the result of the expression is an all() Junction. In
 boolean context this would indeed evaluate to false if $directive has any
 of the values 'VAR', 'LOOP', or 'IF'.

Does it have to be this way?

In formal logic, distributing a negation over a disjunction products a
conjunction and vice versa.

Perl has a long tradition of dwimmery, so why are we taking a literal
distribute all symbols the same way approach?

Surely it is more important that ($a ne $b) should be equivalent to not( $a
eq $b ) regardless of whether either variable contains a junction?

As a start, perhaps we should be marking certain operators (not ! none() !=
ne) with whether they represent a logical inversion, so that conjunctions
and disjunctions can be alternated?

-Martin Kealey


Re: Recommended Perl 6 best practices?

2008-09-30 Thread Jacinta Richardson
Carl Mäsak wrote:

 Do not combine 'ne' and '|', like this:
 
 die Unrecognized directive: TMPL_$directive
if $directive ne 'VAR' | 'LOOP' | 'IF';

 One is tempted to assume that this means the same as $directive ne
 'VAR' || $directive ne 'LOOP' || $directive ne 'IF, but it doesn't.
 Instead, it's a negated string comparison against three values, the
 results of which are then OR-ed together. The condition will always be
 true, because there's always at least two values that $directive is
 not string-equal to.

$directive ne 'VAR' || $directive ne 'LOOP' || $directive ne 'IF'

is always true.  For example assuming $directive = cat;

cat ne 'VAR' (true) || cat ne 'LOOP' (true) || cat ne 'IF' (true)

or assuming $directive = VAR;   Then:

VAR ne 'VAR (false) || VAR ne 'LOOP' (true) || VAR ne 'IF' (true)

which is clearly not what you wanted.  This works if you write instead:

$directive ne 'VAR'  $directive ne 'LOOP'  $directive ne 'IF'

VAR ne 'VAR (false)  VAR ne 'LOOP' (true)  VAR ne 'IF' (true)

Result: false.   (if it is not one of these things then)

Of course now I'm confused as to what:   $directive ne 'VAR' | 'LOOP' | 'IF'
does.  If it was equivalent to:

not ($directive eq 'VAR' || $directive eq 'LOOP' || $directive eq 'IF')

then it would be doing the right thing.  So since it isn't doing the right
thing, I can only assume that your statement above is in error and that:

$directive ne 'VAR' | 'LOOP' | 'IF'

IS INDEED the same as:

$directive ne 'VAR' || $directive ne 'LOOP' || $directive ne 'IF'

and that your expectation of the code is wrong.

 The correct form using junctions would be this:
 
 die Unrecognized directive: TMPL_$directive
if $directive ne 'VAR'  'LOOP'  'IF';

which makes sense, because this does give us:

$directive ne 'VAR'  $directive ne 'LOOP'  $directive ne 'IF'

and that is provably correct.

 The more general advice, then, would be not to use junctions together
 with negated equality operators. Instead, use the non-negated equality
 operator, and negate the whole expression.

This is probably a good idea regardless,

J

-- 
   (`-''-/).___..--''`-._  |  Jacinta Richardson |
`6_ 6  )   `-.  ( ).`-.__.`)  |  Perl Training Australia|
(_Y_.)'  ._   )  `._ `. ``-..-'   |  +61 3 9354 6001|
  _..`--'_..-_/  /--'_.' ,'   | [EMAIL PROTECTED] |
 (il),-''  (li),'  ((!.-' |   www.perltraining.com.au   |


Re: Recommended Perl 6 best practices?

2008-09-14 Thread Carl Mäsak
Conrad ():
 Is there something more up-to-date concerning Perl 6 best practices that
 are presently-recommended (by p6l or @Larry) than the following item on the
 Perl 6 wiki?

If you ask me, best practices evolve as a countering force to enough
people using less-than-ideal practices to create maintenance headaches
or suboptimal solutions noticeable enough for someone to put together
a collection of tips and insights.

I use Perl 6 every day. My problem is not that I encounter badly
thought-out Perl 6 code frequently -- it's that we're targeting
incomplete Perl 6 implementations and have to go against what would
ordinarily be seen as best practices in order to circumvent bugs and
missing features in various layers of the Perl 6 implementation stack.
The tricks we evolve to do this are far removed from best practices:
they are closer to the worst advice you could give a Perl 6 beginner.
(Because most of them solve a problem _without_ the help of some
convenient Perl 6 feature.)

That said, I do have one Perl 6-specific best practice. I know
you're looking for a collection, but one's a start. :) Here it is:

Do not combine 'ne' and '|', like this:

die Unrecognized directive: TMPL_$directive
   if $directive ne 'VAR' | 'LOOP' | 'IF';

One is tempted to assume that this means the same as $directive ne
'VAR' || $directive ne 'LOOP' || $directive ne 'IF, but it doesn't.
Instead, it's a negated string comparison against three values, the
results of which are then OR-ed together. The condition will always be
true, because there's always at least two values that $directive is
not string-equal to.

The correct form using junctions would be this:

die Unrecognized directive: TMPL_$directive
   if $directive ne 'VAR'  'LOOP'  'IF';

But my brain refuses to let me believe that this is what I want to
write. (If $directive is not string-equal to 'VAR' and 'LOOP' and
'IF'... well of course it isn't!)

So instead, I'd use eq, and negate the whole expression:

die Unrecognized directive: TMPL_$directive
   if !($directive eq 'VAR' | 'LOOP' | 'IF');

The more general advice, then, would be not to use junctions together
with negated equality operators. Instead, use the non-negated equality
operator, and negate the whole expression.

// Carl


Re: Recommended Perl 6 best practices?

2008-09-14 Thread Patrick R. Michaud
On Sun, Sep 14, 2008 at 04:18:44PM +0200, Carl Mäsak wrote:
 Conrad ():
  Is there something more up-to-date concerning Perl 6 best practices that
  are presently-recommended (by p6l or @Larry) than the following item on the
  Perl 6 wiki?
 [...]
 That said, I do have one Perl 6-specific best practice. I know
 you're looking for a collection, but one's a start. :) Here it is:
 
 Do not combine 'ne' and '|', like this:
 
 die Unrecognized directive: TMPL_$directive
if $directive ne 'VAR' | 'LOOP' | 'IF';
 [...]
 The more general advice, then, would be not to use junctions together
 with negated equality operators. Instead, use the non-negated equality
 operator, and negate the whole expression.

This particular case is explicitly mentioned in S03:2529:

Use of negative operators with syntactically recognizable junctions may
produce a warning on code that works differently in English than in Perl.
Instead of writing
if $a != 1 | 2 | 3 {...}
you need to write
if not $a == 1 | 2 | 3 {...}

However, this is only a syntactic warning, and
if $a != $b {...}
will not complain if $b happens to contain a junction at runtime.

We might be able to craft a similar warning in Rakudo, but I'm
curious to see how/where STD.pm will choose to handle this.
(My guess is it will have something to do with 
infix_prefix_meta_operator:!, although we also have to have a way
to handle it for the infix:!= and infix:ne cases.)

Pm


Re: negated operators and disjunctions (was: Recommended Perl 6 best practices?)

2008-09-14 Thread Eric Wilhelm
# from Carl Mäsak
# on Sunday 14 September 2008 07:18:

die Unrecognized directive: TMPL_$directive
   if $directive ne 'VAR' | 'LOOP' | 'IF';

One is tempted to assume that this means the same as 
$directive ne 'VAR' || $directive ne 'LOOP' || $directive ne 'IF',
but it doesn't. 

Actually, it does mean exactly that.

But you're not really tempted to read it as:

  if this isn't var or else this isn't loop or else this isn't if

(in denial?).  Instead, one is tempted to read it as:

  if this is not: 'var', 'loop', or 'if'

, by which you really mean:

  if this is not 'var' and this is not 'loop' and this is not 'if'
or:
  if not this is any of: 'var', 'loop', or 'if'

which is:
  unless this is any of: 'var', 'loop', or 'if'
or:
  if this is not all of: 'var', 'loop', and 'if'

But perhaps the thing to remember is to not mix negated operators with 
disjunctions?  The 'dis' being a form of negative and all.

I found this in E06:

  if %person{title} ne $known_title { ... }

Well... I guess E06 is unmaintained, but currently has the best 
explanation of junctions I can find, so I offer the attached patch in 
the hope that the logic error does not propagate.

--Eric
-- 
But you can never get 3n from n, ever, and if you think you can, please
email me the stock ticker of your company so I can short it.
--Joel Spolsky
---
http://scratchcomputing.com
---
Index: exe/E06.pod
===
--- exe/E06.pod	(revision 14582)
+++ exe/E06.pod	(working copy)
@@ -857,6 +857,15 @@
 print Unknown title: %person{title}.;
 }
 
+[Update: that was a logic error:  the negated operator carries through
+the disjunction and is always false.
+
+unless %persontitle eq $known_title {
+say Unknown title: %persontitle.;
+}
+
+Hash key quoting has also changed.]
+
 or even CCode references:
 
 my ideal := \tall  \dark  \handsome;


Recommended Perl 6 best practices?

2008-09-13 Thread Conrad Schneiker
Is there something more up-to-date concerning Perl 6 best practices that
are presently-recommended (by p6l or @Larry) than the following item on the
Perl 6 wiki?

 

  http://www.perlfoundation.org/perl6/index.cgi?perl_6_books_and_media

 

Perl 5 Books with Perl 6 Relevance

 

* Perl Best Practices by Damian Conway. Even though this currently
applies to Perl 5, most of the principles also apply to Perl 6. This book is
the semi-officially recommended guideline for people developing core Perl 6
modules and tests.

 

Until the Perl 6 version of Perl Best Practices is (hopefully) available a
year or 2 from now, would it meanwhile be useful to create a Perl 6 wiki
page devoted to this subject, which would be linked to this documentation
page (among others)?

 

  http://www.perlfoundation.org/perl6/index.cgi?documentation

 

Best regards,

Conrad Schneiker

 

 http://www.athenalab.com/ www.AthenaLab.com

 

Official Perl 6 Wiki -  http://www.perlfoundation.org/perl6
http://www.perlfoundation.org/perl6