Re: Pondering parameterized operators

2003-09-29 Thread Austin Hastings

--- Luke Palmer [EMAIL PROTECTED] wrote:
 Yeah, that's true.  But note that you can't do that black magic you
 were
 speaking of earlier:
 
 $a [ (cond ?? infix:+ : infix:*) but tighter(infix:*) ] $b
 
 Because we can't choose the precedence of an operator after we parse
 it... unless we're doing bottom up, which we're not.  I do think that
 the infix [] construct would have to have a fixed precedence.
 

Run time or compile time? If the [] is a compile time operation, it
doesn't matter, of course, since everything is done.

If the precedence of [] can vary, or if user-ops can vary their
precedence, the parser will have to have some sort of late
reevaluation mechanism. 

This fits in with the recompile if you change the world thread from
last week, I guess.

It also ties in kind of nicely with the feel of Damian's OOPerl book:
making objects out of unlikely things. In this case, we're making
operators out of them.

  my op1;
  my op2;

  sub foo {
my $x = $^a op1 $^b op2 $^c;
print Foo:  . $x . \n;
  }

  # (Luke: Because these are literal lists, I don't need :=,
right?)
  (op1, op2) := (infix:+, infix:*);
  foo(3,4,5);
  # Prints 23

  (op1, op2) := (op2, op1);
  foo(3,4,5);
  # Prints 17 (27 if the parser doesn't rescan :-)

=Austin



Re: Pondering parameterized operators

2003-09-28 Thread Eirik Berg Hanssen
Austin Hastings [EMAIL PROTECTED] writes:

 [Eirik wrote:]
Let us see ... somewhat speculative and probably short-of-the-mark
  generalization coming up:
 
 
  macro infix:[  ($lhs, $op, $rhs)
  is parsed(/(Perl6.expr) \] (Perl6.expr)/) {
  return {
  $op($lhs, $rhs)
  };
  }
 
(Precedence?  Err ... the left hand side has already been parsed,
  so infix:[ must be of fixed precedence to the left hand side, right?
  Damn, I thought I had it ...)
 
 This is text replacement, not expression evaluation. You do have it from
 where I sit.

  Text replacement?  This is returning a closure, not text.  But even
if this is a case of text replacement, I get the first parameter,
$lhs, from text that has already been parsed.


   # Note: Need a way to parse nested []'s
   macro [ ($whosit) is parsed(/(?:\s[) (expr) \]/) {
 eval $whosit;
   }

  I may not be up-to-date on macros and is parsed, but ITYM:

macro prefix:[ ($whosit) is parsed(/(Perl6.expr) \]/) {
  return eval $whosit;
}

  This should return text, I believe.  But the parser will not be
expecting a term (or prefix:-operator) here ... it is looking for
an infix:-operator or a postfix:-operator, right?

  (And it will eval() at compile time, so my phase-of-the-moon example
will not be evaluated at run time, even if this works.)


 The macro immediately evaluates the expression, so it has to be a deferrable
 reference.
 Then:
 
   macro infix:eqn($n) is equiv (infix:eq) {
 [String::strncmp.assuming(n = 4)]
   }

  (s/4/\$n/, I believe.)

  But the infix:-operators by default get their LHS and RHS parse
trees as parameters, last I heard, so your parameter list is too
short.  Still, you may be on to something ... what about this?

macro infix:eqn ($lhs, $n, $rsh) is equiv(infix:eq)
  is parsed(/ \( (Perl6.expr) \)
 (Perl6.expr but speculatively_equiv(infix:eq))/) {
  return String::strncmp($lhs, ($rhs), ($n));
}

  if Dough eqn(4) Douglas {...}
becomes
  if String::strncmp(Dough, (Douglas), (4)) {...}

  Okay, that may be evil.  But it DWYW, right?


  No such luck with my phase-of-the-moon example, though.  And come to
think of it, finding the right precedence might be tricky, even if
this (or more complicated re-parsing tricks) should happen to work:

macro infix:[  ($lhs, Sub $op, $rhs)
is equiv($op)
is parsed(/(Perl6.expr)
\]
   (Perl6.expr but speculatively_equiv($op))/) {
return ($op).(($lhs), ($rhs));
}

# This might be determinable at compile time:
if $test [$moon.is_waxing ? infix: : infix:=] $target {...}

# This would need explicit but equiv or something like that:
if $test [($lookup{$key} || infix:eq) but equiv(infix:eq)] $target {...}


  So, probably just a bad idea.


Eirik
-- 
All bridge hands are equally likely, but some are more equally likely
than others.
-- Alan Truscott


Re: Pondering parameterized operators

2003-09-28 Thread Simon Cozens
[EMAIL PROTECTED] (Luke Palmer) writes:
 [$lhs, $rhs]æ\220\215.æ\235\237compile;

What's that in old money?

-- 
As the saying goes, if you give a man a fish, he eats for a day. If you
teach him to grep for fish, he'll leave you alone all weekend. If you
encourage him to beg for fish, pretty soon c.l.p.misc will smell like a
three-week-dead trout. -- Tom Phoenix, c.l.p.misc.


Re: Pondering parameterized operators

2003-09-28 Thread Luke Palmer
Simon Cozens writes:
 [EMAIL PROTECTED] (Luke Palmer) writes:
  [$lhs, $rhs]\220\215.\235\237compile;
 
 What's that in old money?

Eep.  I thought I had mutt's utf-8 working, but apparently not.

Does anyone who knows about these things want to mail me instructions,
or something?  That'd be nice for most everyone who reads my posts :-)

Luke

[$lhs, $rhs].compile;


Re: Pondering parameterized operators

2003-09-28 Thread Eirik Berg Hanssen
Luke Palmer [EMAIL PROTECTED] writes:

 Cool stuff.   In my usual pedantic sort of way, I'll go through the
 message and fix everything you said.  For educational purposes only, of
 course :-)

  Thanks :-)

  For further education, some more questions/comments, if I may:


 # Let's say Cis parsed args come before the default infix args
 macro infix:[ ($op, $lhs, $rhs)  
   is parsed( /:w (Perl6.expr) \]/ )

[snip]

 You shouldn't parse the right hand side yourself.  That fixes the issue.

  I was not aware of this option.  A6/E6 gave me the impression that
Cis parsed would override the default parsing of the RHS, not merely
augment it.  Does the parsed-trait somehow interact with the signature
of the macro, to find out whether to extend or replace?

  That is, can I write prefix:-macros that do not take the default RHS
parameters, but only the ones generated by Cis parsed?  Quotelike
operators come to mind:

macro prefix:qtex ($raw)
  is parsed( /(Perl6.delimited_balanced .*?)/ ) { ... }

  Or would that be accomplished by another keyword, indicating what,
in the absence of Cis parsed, would be 0-ary?  term:qtex, perhaps?
I guess that depends upon what kind of consistency you are aiming for.


 Do you Iwant to give me a heart attack? :-/

  Nope.  I will try to restrain myself.

 This would be fine, I think:
 
 sub eqn ($n) { String::strncmp.assuming(n = $n) }

  You mean it would be fine for using with the infix:[ macro, right?
But then you could not get the precedence you want.  You would be
stuck with whatever precedence infix:[ was given.


Eirik
-- 
All bridge hands are equally likely, but some are more equally likely
than others.
-- Alan Truscott


Re: Pondering parameterized operators

2003-09-27 Thread Eirik Berg Hanssen
Luke Palmer [EMAIL PROTECTED] writes:

 Hmm, since we're requiring no whitespace between a variable and it's
 subscript, this should be possible:
 
 if Dough [eqn 4] Douglas {...}

  Lisp!  :-)

  Well, almost.  Now this would be lisp-y:

  if $test [$moon.is_waxing ? infix: : infix:=] $target {...}


  Let us see ... somewhat speculative and probably short-of-the-mark
generalization coming up:


macro infix:[  ($lhs, $op, $rhs)
is parsed(/(Perl6.expr) \] (Perl6.expr)/) {
return {
$op($lhs, $rhs)
};
}

  (Precedence?  Err ... the left hand side has already been parsed,
so infix:[ must be of fixed precedence to the left hand side, right?
Damn, I thought I had it ...)

  Then vector operators, like +, are really just simple
[vectorize infix:+] and similar -- except properly optimized and
presumably with proper precedence.  And, you can write:


if Dough [String::strncmp.assuming(n = 4)] Douglas {...}


  Still long.  Oh well.  infix:[eqn, perhaps?  At least that one will
be of fixed precedence.  Right?


macro infix:[eqn  ($lhs, $n, $rhs)
is equiv(infix:eq)
is parsed(/(Perl6.expr)
\]
   (Perl6.expr but speculatively_equiv(infix:eq))/) {
return {
String::strncmp($lhs, $rhs, n = $n)
};
}



Eirik
-- 
So this is the Sword of Immortality?  Huh?
 What's it doin' in a CRYPT?!
   --- John S. Novak, III, quoting an unnamed player


RE: Pondering parameterized operators

2003-09-27 Thread Austin Hastings


 -Original Message-
 From: Eirik Berg Hanssen [mailto:[EMAIL PROTECTED]
 Sent: Saturday, September 27, 2003 11:35 AM
 To: [EMAIL PROTECTED]
 Subject: Re: Pondering parameterized operators


 Luke Palmer [EMAIL PROTECTED] writes:

  Hmm, since we're requiring no whitespace between a variable and it's
  subscript, this should be possible:
 
  if Dough [eqn 4] Douglas {...}

   Lisp!  :-)

No, just horribly early evaluation.

That'll do, Luke. That'll do.

   if $test [$moon.is_waxing ? infix: : infix:=] $target {...}

This is right, presuming we have a way to give the parser the right data
(function properties).

   Let us see ... somewhat speculative and probably short-of-the-mark
 generalization coming up:


 macro infix:[  ($lhs, $op, $rhs)
 is parsed(/(Perl6.expr) \] (Perl6.expr)/) {
 return {
 $op($lhs, $rhs)
 };
 }

   (Precedence?  Err ... the left hand side has already been parsed,
 so infix:[ must be of fixed precedence to the left hand side, right?
 Damn, I thought I had it ...)

This is text replacement, not expression evaluation. You do have it from
where I sit.

  # Note: Need a way to parse nested []'s
  macro [ ($whosit) is parsed(/(?:\s[) (expr) \]/) {
eval $whosit;
  }

The macro immediately evaluates the expression, so it has to be a deferrable
reference.
Then:

  macro infix:eqn($n) is equiv (infix:eq) {
[String::strncmp.assuming(n = 4)]
  }

so
  if Dough eqn(4) Douglas {...}
becomes
  if Dough [sub String::strncmp.assuming(n = 4)] Douglas {...}
becomes
  if Dough temporary infix-binary inserted by macro Douglas {...}

and it just works. Woo-hoo!

   Then vector operators, like +, are really just simple
 [vectorize infix:+] and similar -- except properly optimized and
 presumably with proper precedence.  And, you can write:

 if Dough [String::strncmp.assuming(n = 4)] Douglas {...}

   Still long.  Oh well.  infix:[eqn, perhaps?  At least that one will
 be of fixed precedence.  Right?

See above. No precedence worries with an unattached macro -- do a text
replacement
or give the parser a correctly attributed tree, and let it worry about it.

=Austin



Re: Pondering parameterized operators

2003-09-27 Thread Luke Palmer
Cool stuff.   In my usual pedantic sort of way, I'll go through the
message and fix everything you said.  For educational purposes only, of
course :-)

Eirik Berg Hanssen writes:
 Luke Palmer [EMAIL PROTECTED] writes:
 
  Hmm, since we're requiring no whitespace between a variable and it's
  subscript, this should be possible:
  
  if Dough [eqn 4] Douglas {...}
 
   Lisp!  :-)
 
   Well, almost.  Now this would be lisp-y:
 
   if $test [$moon.is_waxing ? infix: : infix:=] $target {...}

if $test [$moon.is_waxing ?? infix: :: infix:=] $target {...}

   Let us see ... somewhat speculative and probably short-of-the-mark
 generalization coming up:
 
 
 macro infix:[  ($lhs, $op, $rhs)
 is parsed(/(Perl6.expr) \] (Perl6.expr)/) {
 return {
 $op($lhs, $rhs)
 };
 }

Pretty close.

# Let's say Cis parsed args come before the default infix args
macro infix:[ ($op, $lhs, $rhs)  
  is parsed( /:w (Perl6.expr) \]/ )
{
my ($clhs, $crhs) = [$lhs, $rhs].compile;  #only compile once
return {
$op($clhs.run, $crhs.run);
}
}

This would have the precedence of infix:+ .

   (Precedence?  Err ... the left hand side has already been parsed,
 so infix:[ must be of fixed precedence to the left hand side, right?
 Damn, I thought I had it ...)

You shouldn't parse the right hand side yourself.  That fixes the issue.
Note that this is just how ??:: is going to do things:

macro infix:?? ($iftrue, $cond, $iffalse)
  is parsed( /:w (Perl6.expr) '::'/ )
  is tighter(infix:=)
  is assoc('right')
{
my ($ccond, $ciftrue, $iffalse) = [$iftrue, $cond, $iffalse].compile;
return {
if $ccond.run {
$ciftrue.run;
}
else {
$ciffalse.run;
}
}
}

And there might just be a Cis compiled trait to automatically do that
first line.  If not, it will surely be defined in Macro::Common. :-)

   Then vector operators, like +, are really just simple
 [vectorize infix:+] and similar -- except properly optimized and
 presumably with proper precedence.  

Yeah.  Very cool.

 And, you can write:
 
 
 if Dough [String::strncmp.assuming(n = 4)] Douglas {...}
 
 
   Still long.  Oh well.  infix:[eqn, perhaps?  

Do you Iwant to give me a heart attack? :-/

This would be fine, I think:

sub eqn ($n) { String::strncmp.assuming(n = $n) }

 At least that one will be of fixed precedence.  Right?
 
 
 macro infix:[eqn  ($lhs, $n, $rhs)
 is equiv(infix:eq)
 is parsed(/(Perl6.expr)
 \]
(Perl6.expr but speculatively_equiv(infix:eq))/) {
 return {
 String::strncmp($lhs, $rhs, n = $n)
 };
 }

I can't feel my left arm...

Again, you don't need to parse the right side of the operator yourself,
otherwise it be a postfix: macro.

Luke



Pondering parameterized operators

2003-09-26 Thread Austin Hastings
So I sit here and think for a minute about how nice it will be in P6 to
be able to define 

  operator infix:eqi($str1, $str2) {...}

for doing

  if ($1 eqi last)

and I think about the whole 'C' string library. Which dredges up my old
questions about parameterized operators:

How can I conveniently pass an extra parameter to a historically binary
operator?

At one point, the colon was going to do that, but Larry took it back:

  if (Dough eqn:4 Douglas) # true
  { ...

The options left seem to be:

  package String;
  sub strncmp($a, $b, $n) {...}
  package main;

  sub infix:immed String::strncmp.assuming($n = 4);
  if (Dough immed Douglas) # ?

or:

  class InfixBinary is Code {...}
  # How do I create a type? -- I want to define a return-type-spec
  # that just guarantees context behavior.

  sub eqn($max) returns InfixBinary {
return String::strncmp.assuming($n=$max);
  }

  if (Dough eqn(4) Douglas) ...

Frankly, I like the second one.

=Austin



Re: Pondering parameterized operators

2003-09-26 Thread Dan Sugalski
On Fri, 26 Sep 2003, Austin Hastings wrote:

 How can I conveniently pass an extra parameter to a historically binary
 operator?

If it's one of the 'base' binary operators (addition, subtraction, and 
whatnot) you don't.

Dan



Re: Pondering parameterized operators

2003-09-26 Thread Luke Palmer
Austin Hastings writes:
 How can I conveniently pass an extra parameter to a historically binary
 operator?

I see a few possibilities.  The first, call it like a function:

if infix:eqn(Dough, Douglas, n = 4) {...}

Or, you could use the adverbial modifier Cwhere (well, not officially
yet, but I hope so):

if Dough eqn Douglas where n=4 {...}

But that has some problems, like putting the operator parameters really
far away from the operator, and forcing parentheses on a function call
on the right (lest the Cwhere be associated with the call).

More below.

 At one point, the colon was going to do that, but Larry took it back:
 
   if (Dough eqn:4 Douglas) # true
   { ...
 
 The options left seem to be:
 
   package String;
   sub strncmp($a, $b, $n) {...}
   package main;
 
   sub infix:immed String::strncmp.assuming($n = 4);

You probably mean:

our infix:immed ::= String::strncmp.assuming($n = 4);

   if (Dough immed Douglas) # ?
 
 or:
 
   class InfixBinary is Code {...}
   # How do I create a type? -- I want to define a return-type-spec
   # that just guarantees context behavior.
 
   sub eqn($max) returns InfixBinary {
 return String::strncmp.assuming($n=$max);
   }
 
   if (Dough eqn(4) Douglas) ...
 
 Frankly, I like the second one.

Yeah, I don't think it's a bad idea.  I think returning an infix
operator is not the way to go about it.  Perhaps optional (and named)
parameters on an infix operator could be taken from a parameter list:

sub infix:eqn ($a, $b, ?$n) {
substr($a, 0, $n) eq substr($b, 0, $n)
}

if Dough eqn(4) Douglas {...}

That's not terribly good at making different things look different.
It's pretty common to see parenthesized expressions on either side of an
operator.  

Hmm, since we're requiring no whitespace between a variable and it's
subscript, this should be possible:

if Dough [eqn 4] Douglas {...}

If we're going that far...

sub foo($a, $b) {
print $($a)y$b;
}
Dough [foo] Douglas;  # DoughyDouglas

Not sure I like that too well.

Luke


Re: Pondering parameterized operators

2003-09-26 Thread Dave Whipp
Austin Hastings [EMAIL PROTECTED] wrote
   if (Dough eqn(4) Douglas) ...

I wonder if the . operator is available here:

  if Dough eq.n(4) Douglas { ... }

that makes it intuitive how to define new equality methods. One thing of
concern is that we'd need whitespace rules to disambiguate things. I sense
some wonderful opportunities for obfuscation.


Dave.