[racket-dev] P4P: A Syntax Proposal

From: Shriram Krishnamurthi (sk at cs.brown.edu)
Date: Fri Jul 30 08:30:36 EDT 2010

> deffun: d/dx(f) =
>   defvar: delta = 0.001
>   fun: (x) in
>      ((f((x + delta)) - f(x)) / delta)

Just to be pedantic, I've changed the "in" to "in:", because I want to
have a consistent rule for all key*words*.

> Which can be understood easier than the prefix version but avoids all
> the negatives of a complete infix notation.

What you're doing is essentially recapping an age-old Lisp tradition
of defining infix macros (my guess is the first one was probably
written a few weeks after s-expressions got adopted as the programming
notation).  I don't have a problem with that.  I don't want to use
"in:" as the name for an infix construct, but maybe just "i:"
(especially if people are going to use it often, keeping it short will
help).  But I also don't want to spend time on that right now because
I don't think it's where the big payoff is.

> deffun: d/dx(f) =
>   defvar: delta = 0.001
>   fun: (x) in
>      in:(in:( f( in:(x + delta) ) - f(x)) / delta) ; not as pretty...

No, once you're in infix, you can stay there:

deffun: d/dx(f) =
  defvar: delta = 0.001
  fun: (x) in:
    i:((f(x+delta) - f(x)) / delta)

As I said in another message, I think I made a mistake by using
arithmetic examples, because they represent the worst-case for this
syntax.  Real code will have much less arithmetic.

> Since your target use if for students, I could be convinced that infix
> doesn't belong.  ¡  But both students and experienced (non-LISP)
> programmers will complain about the prefix math. (And prefix comparison
> operators.)

My experience teaching Scheme beginners is that Lisp-style prefix for
arithmetic is NOT a problem; they get the hang of it quickly.  It's
when things start to nest and parens start to add on that they start
to get frustrated.  (COND is a special pet peeve.)

> BTW, any binary operation that expresses a relationship between first
> and second operands could be clarified by writing it in infix.

Except conventionally, I hear no clamor for being able to say

  (+ . map . l)

or even

  (10 . expt . 2)

The bottom line, though, is that I don't have a problem with having a
parenthesized infix term offset by a keyword.

> Also, if P4P is dependent on keywords like if: elif: etc. then macros
> are crippled unless they can also make use of key words.

I'm afraid I totally don't understand what you're saying.

> Other examples:
>   filter( lst ) with:(elem) { odd?(elem) }
> -->
>   (filer lst #:with (lambda (elem) (odd? elem)))

filter: <e> with: <id> <e w/ id bound>
(filter <e> (lambda (<id>) <e w/ id bound>))

I'm failing to see what is "cripping" here that #:with did not carry
over into Racket.  The idea is to create a surface syntax that
entirely hides the Racket layer underneath, so who cares whether the
Racket layer uses intermediate keywords or not?

Given that I am totally, completely, utterly missing your point, I'm
sure you must have one.  Try again?

> The switch example shows one more instance where someone will want to
> define a structure that you haven't thought of.   I believe you said cond
> will just have to be a bunch of if/elif.   But someone will still want to
> implement cond.   If you can't handle creating new structures in your
> syntax then P4P will only be useful to students.

Please see the section on syntax extensions in the manifesto.  I
thought I'd already addressed this.

>  It won't help pull
> parenthesis-haters into the Racket camp (unless you implement all the
> structures they could wish for in your parser, since
> non-schemers/lispers aren't used to creating new syntaxes with macros).

Naturally, P4P will have to offer a term for each of the syntactic
constructs in Racket.  Functions come for free.  So they would have
the whole language available to them.  So what's the problem?


Posted on the dev mailing list.