Is it possible to have a LISP that doesn’t use strictly prefix (+ x y z) but sometimes (x choose y) infix-style expressions?

It seems doable, doesn’t it?

It seems more readable to me, in some way.

It may be necessary to escape the operator, I guess, where you’re basically writing ((x )choose( y)).

Man, how nice would it be if editors could actually use underlined text, just a single bit flip, ah well. You could just underline the operator of each expression, and put it anywhere you like.

Is (mod 15 3) awkward to say? Why not (15 mod 3), if only you could be clear 15 is not the operator.

Previous work in this area: sweet-expressions

D Wheeler’s sweet-expressions definitely come to mind.

So in this system of D Wheeler’s, which is great by the way,

  • { .. infix stuff .. }, and
  • ( .. prefix stuff .. )
  • indentation implies ( .. ) wrapping

That’s pretty much it.

I only hesitate on the indentation part. Maybe inside a toplevel ( .. ) or { .. } form, but how else would you break long lines?

Wow, (re-)reading on, he says both Common LISP and Scheme claim [ .. ] as a reserved form.

Uh, I think it might be time to use it. I mean, by now..

Clojure took big steps in this area, using different characters (not just parens), but I’m not sure about infix stuff. I do have to admit it’s a bit hard remembering how to read Clojure when you’re just staring at .. <<- (_ % _) .. or something, wondering what the fuck does that do.

Haskell just declares some operators infix, and others prefix (like, function application, right). You can always (..) an infix operator to “get” the prefix version. The difference between the two is hard to put into words. (Are we casting? or what. Are the two equal? They’re clearly not equivalent, literally, so…)

Optional notation

I do like the notion of optional notation, but also don’t mind a canonical fully-expanded form (like CoffeeScript vs ECMAScript v-browsers-current).

I could just introduce some operator like $ and claim that ($ 5 $mod 3) is the infix way to write it. Ba dum tsh, done. That’s not too bad.

If the $ is too bad, I could probably find a sweeter syntax. I mean, xargs uses that weird -I {} .. {} .. syntax. That can’t be hard to beat.

It might be cool if lisps had a $ operator almost like the one in Haskell, one that just immediately divides an expression. ( x $ .. $ y) or (x _ mod _ y) seem like useful escapes, so you can put a function expression/symbol clearly marked as infix. Lisp is one of those things where you don’t really need anything, but you definitely overwhelmingly feel like a little more might be useful. Just a little more.

Outside the box

I do think paren blocks are still one of the most logical and simultaneously awkward things to write.

Our editors just don’t let us put parens as grace notes.

| not at all important that this should
|   be the first character your eye sees
v
(def square (x)
  (* x x))
         ^
         \ also totally useless

I wish the editor would put some parens “outside the box”, so to speak.

...|Editor Window......|...
  (|def square (x)     |
   |  (* x x)          |)
  (|def delta (x y)    |
   |  (if (< x y)      |
   |    (- y x)        |
   |    (- x y)        |))

     or even better,
  (|def delta (x y)    |
  (|  if (< x y)       |
   |    (- y x)        |
   |    (- x y)        |))

and maybe so far even as to
  (|def delta (x y)    |⇥
  (|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)))

with (ideally, not messing up spacing, I put it on the upper line) to indicate the paren here is nested inside the expression above, to match with indentation. This is redundant, sure, but it’s what literally separates the last line from not getting wrapped in the first subtraction as (- y x (- x y)) or something.

The first two lines don’t end with closing parens, which seems to indicate the follows.

Ideally it would color-code (even in greyscale, with patterns (remember those, in Windows 95/98? those backgrounds?)) the parens that don’t open & close on the same line.

Just an idea. Plaintext is great, but so limiting. Unicode is also weird, but might be an answer.

There are likely 2-4 A-Z alphabets packed into Unicode. It’s a pain to write them, of course, but an editor could make them available. Like 4 fonts, each completely different namespaces. Different language spaces entirely, really.

I mean, yeah, you don’t want to go too much in that direction (in John Cleese’s words-ish, too much is simply too much), but what is there to gain?

Here’s an idea on closing parens, a bad one maybe but numbering, as long as these parens stay outside the box it doesn’t really matter what the symbol is.

with numbered open-close parens
  1|def delta (x y)    |⇥
  2|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)21

or with lettering, not numbering
  a|def delta (x y)    |⇥
  b|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)ba


or with greek lettering,
  α|def delta (x y)    |⇥
  β|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)βα

I’d say that looks.. best. For kicks, since it really doesn’t matter

or with cyrllic lettering,
  А|def delta (x y)    |⇥
  Б|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)БА

or with mahjongg lettering,
  🀀|def delta (x y)    |⇥
  🀑|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)🀑🀀

or with dice lettering,
  ⚀|def delta (x y)    |⇥
  ⚁|  if (< x y)       |⇥
  (|    - y x          |)
  (|    - x y          |)⚁⚀

That one messes up the spacing, but you could easily swap them, and it shouldn’t matter.

That’s the benefit of only needing parens, and not 5 kinds of braces.

Though, you could say parens = greek, curly braces = numbering, sure. That may be useful?

or with greek lettering & numbering,
  α|def delta (x y)    |⇥
  β|  if               |⇥
  1|    x < y          |1
  2|    y - x          |2
  3|    x - y          |3βα

If that’s the cost of writing prefix & infix in the same code, well, interesting.

Of course, this is strictly presentational.

The plaintext would still be

(def delta (x y)
  (if
    {x < y}
    {y - x}
    {x - y}))

, it’s just a better/different way of showing/not-showing the parens & braces.

Maybe rolling it back, if we just need 2 states to show, prefix & infix, we can just underline the infix stuff.

I think each global expression could name its subexpressions, but you still might run out of letters & numbers (going hex, base32, base64.., it’s still one digit).

Since nobody cares when they’re all the same anyway, reusing the numbers is the sensible option, it seems. Just cycle through the alphabets, nobody will care.

So this solution basically starts with sweet-expressions and involves a super complicated editor on top, but it looks like python and is LISP. And it’s purely a presentational layer, we all agree the on-disk format is sweet expressions.

Think of it maybe more like an org mode that doesn’t exist.

Read between the lines

Also on the highway of horrible solutions, we have line splitting.

Just double-space all of your code onto the odd lines 1, 3, 5, &c. Then the even lines annotate the lines above, to basically capture a small amount of information.

“Underline” the infix stuff with _. Highlight error’d lines, even. I don’t know.

Rich text is a big jump, but it might just be worth it, for source code. Put it in source control, get track changes type shit, be done with it. Watch the build artifacts (like we did in CoffeeScript) to make sure you know what you wrote is really writing.