On Thu, Oct 30, 2008 at 05:41:11PM +0100, Moritz Lenz wrote:
: Xiao Yafeng wrote:
: > Off the top of one's head, since there is no particular difference between
: > an operator and a function, can I see a function as a operator:
: > 
: > (1, 2, 3, 4) >>elems<<(2, 3, 4, 5)          #(2, 2, 2, 2)
: > (1, 2, 3, 4) >>shift<<(2, 3, 4, 5)          #(2, 3, 4, 5)
: But remember that operators come with an associativity:
: $a / $b / $c == ($a / $b) / $c # left associative
: $a ** $b ** $c == $a ** ($b ** $c) # right associative
: When you make a function into an operator, you need a good syntax for
: defining the associativity of the new pseudo-operator.
: Also note that shift(1, 2) doesn't work, because it gets a list, not an
: array, and lists are immutable.

Note also that by conflating unary with binary operators you make
ambiguities.  By the above definition, >>+<< might be expected to
return 2,2,2...*,  whereas the existing >>+<< returns the pairwise

: > Moreover, can I see a subroutine as a operator:
: > 
: > (1, 2, 3, 4) >>{$a>$b??$a!!$b}<<(2, 3, 4, 5)        #(2, 3, 4, 5)
: Every operator is accessible  as a function (or a macro) already, for
: example the operator in 2 + 3 is known as &infix:<+>.

And note that >>{ ... }<< cannot be parsed as a single token
without infinitely large token tables.  We place some fairly severe
restrictions on what can occur within a metatoken for this reason:
no embedded spaces, no recursive metaoperators, etc.  So putting a
closure in the middle would have to be parsed as a >>{ token followed
by some code followed by a }<< token.  Alternately, we'd have to split
out metaoperators as separate tokens, and that is likely to violate the
principle of Least Astonishment in some cases, since it would mean we
could not have both an infix:<X> and infix_circumfix_meta_operator:<X X>.
As it currently stands, by relying on LTM (longest-token matching)
we can express all of:

    @a X @b
    @a X*X @b

and we know that

    [ X ...

must be the start of an array composer, where X is a function name.

The only way I could see to relax this would be to require whitespace
around *all* infix operators, which seems like a plan that would inspire
a truly massive quantity of righteous grumbling.  And it still wouldn't
let you write:

    X{ $^a * $^b }X

as a single infix since that has whitespace in it.  You'd again have
to define X{ and }X to be parsed as a special infix operator, just
as ??!! is handled in STD currently.  Similar considerations apply
for reduce operators that contain whitespace.  At some point you just
give up on composable token syntax and make people call reduce() or
cross() or hyper().  And basically, while an arbitrarily complicated
closure can be considered an individual term, it cannot be considered
an individual token.  Token composition must be restricted to whatever
can be recognized by regular languages, by my current understanding
of LTM, and of how much complexity normal users will put up with.

: The ternary is a rather ugly case, I guess it's called &infix:<??
: !!>($condition, $true, $false), and it's short-circuiting, so it must be
: a macro rather than normal function.

And it would have to be implemented specially in any case.  The STD
grammar parses the true case as part of the infix operator, so
the operator officially has only a condition and a false argument!

But it's possible there could be a built-in function:

    if($condition, {$true}, {$false})

The lazy short-circuit nature would be explicit there via the closure
args.  I suppose one could specially implement a statement_control:<if>
macro though, as in the ??!! case.

Similar considerations would apply for functional/macro forms of && and ||.


Reply via email to