
Readable Lisp S-expressions Project (2013) - singularity2001
https://readable.sourceforge.io/
======
neilv
There've been so many attempts at removing the parentheses from Lisp, to make
it look more like C/C++/Java, or (more recently) Python, or other.

FWIW, there've been many attempts in Scheme (and Racket), including one by the
core Racket developers (Honu [1]), but they've never taken off. New people
decide to use parentheses.

There's a phenomenon with Lisps, in which, speaking loosely, half the people
who first see a Lisp think the parentheses are a problem, and immediately
start to propose "solutions" for "acceptance". But then they try the Lisp with
the parentheses, in an editor with at least simple indenting support, and they
very quickly get used to it, and maybe even value it. (A small percentage of
them will still put each close-paren on its own line, for a substantially
longer period, but it seems even most of them will quickly learn to snuggle
close-parens and possibly to use fancier editor commands for movement and
editing based on expressions rather than lines.)

Programmers seem more malleable than we might think. I'm not as sure about
those mathematicians or scientists who try to minimize their time learning
programming, or who are necessarily working with hairy expressions in LaTeX
and don't want to have to keep translating. For possible use of those people,
there are a number of efforts to permit expressions to be in more familiar
infix order [2], and to support familiar TeX math notation in the Racket-based
typesetting/documentation system [3]. (And if you don't like those, Racket
will let programmers plug in your own reader or `#lang` to make another
attempt at this atop Scheme.)

[1] [https://docs.racket-lang.org/honu/Examples.html](https://docs.racket-
lang.org/honu/Examples.html)

[2] [https://docs.racket-lang.org/guide/hash-
reader.html#(part._r...](https://docs.racket-lang.org/guide/hash-
reader.html#\(part._readtable\))

[3] [https://docs.racket-lang.org/scribble-
math/index.html](https://docs.racket-lang.org/scribble-math/index.html)

~~~
breck
> There've been so many attempts at removing the parentheses from Lisp

The best previous attempt IMO was Egil Möller's I-expressions in 2003
([https://srfi.schemers.org/srfi-49/srfi-49.html](https://srfi.schemers.org/srfi-49/srfi-49.html)).
These Sweet-Expressions in the OP I think were a regression on I-Expressions.

My attempt (~2013-present) is called Tree Notation.
[http://treenotation.org/](http://treenotation.org/). This is the first time
that we've got S-Expressions without parentheses _and_ are using that for
tremendous benefit (better concatenation, easy ad hoc parsers, visual
programming and program synthesis being some of the main benefits).

Here are a few sample languages:
[http://treenotation.org/sandbox/build/](http://treenotation.org/sandbox/build/)

> but they've never taken off.

It's going to happen finally with Tree Notation. We're starting to see strong
network effects at last. The missing ingredient was strong tooling/design/and
tools that leverage the lack of parentheses to huge benefit.

~~~
singularity2001
Beautiful.

OP claims to be backwards compatible with Clisp, that's not a goal of yours,
right?

So a list in treenotation would be written:

    
    
       list a
        1
        2
        3
        4
    

? Could become a bit verbose at times, or does treenotation have a mechanism
for tables like

    
    
       data={
         header:['brand','make','price],
         rows:[
                ['mercedes','X1',1000] ,
                ['porsche','Z7',2000],
               ]
      }  
    

are triples always parsed like this: ?

description A package

(description (A package)) vs ((description A) package)

Does treenotation differentiate between strings and data/ints?

~~~
breck
> OP claims to be backwards compatible with Clisp, that's not a goal of yours,
> right?

Correct, not a goal of mine. If someone wanted to create a Tree Language that
compiles to CLisp, they could define it in our Grammar Language
([http://treenotation.org/sandbox/build/](http://treenotation.org/sandbox/build/)
\-- you write your grammar on the left, and source code in your new language
on the right).

> So a list in treenotation would be written:
    
    
       list a
        1
        2
        3
        4
    

The base spec for Tree Notation is very simple.

    
    
        YI = "\n" // New lines separate nodes
        XI = " " // Increasing indent to denote parent/child relationship
        interface TreeNode {
          parent: &TreeNode
          children: TreeNode[]
          line: string
        }
    

In practice, we generally break "line" into "words: string[]". So you can
represent atoms in a list as either words or nodes, depending on how you
design your Tree Language.

> Could become a bit verbose at times, or does treenotation have a mechanism
> for tables like

Sort of. We have a software coming out called TreeBase that is a plain text,
git backed database that stores records in Tree Notation. In there we have
Tree Languages for dealing with SSV/TSV/CSV/etc tables. I'm not 100% happy
with the current implementation--going to be putting pattern matching into our
Tree Grammar Language which might solve it--but I bet within a month or two
we'll have a great solution for that with strong type checking, etc.

> Does treenotation differentiate between strings and data/ints?

The base Tree notation is very simple, as the spec above shows. But we created
a Tree Language, built upon Tree Notation, wherein you write grammars to
create new languages. In those grammar files you can define ints, strings,
arrays, etc. The link above has examples with all of those.

------
bitwize
Lisp, as McCarthy proposed it in 1958, actually had an alternate syntax called
M-expressions that would be perfectly readable to any JavaScript programmer:
(foo a b) became foo[a,b].

It never took off. From the earliest days -- before video terminals were a
thing, let alone video-terminal editors that could match parens and indent
automatically -- people just preferred working with sexprs. I think it has to
do with the fact that while mexprs are easier to read with prior ALGOL
experience, sexprs are easier to transform, and to reason about their
transformation.

I think Lisp is one of those things where, you either get it or you don't, and
once you do get it parens are a non-issue. There's a fundamental leap of
insight that requires enormous activation energy to achieve.

~~~
ddragon
The idea of the m-expressions might be coming back though, two of the popular
newcomers are homoiconic languages (depending on your definition), Elixir as a
functional programming language and Julia as an imperative CLOS inspired
language.

Being not as powerful (able to create any valid syntax due to more complex and
rigid parsing rules) and trivial to manipulate code as data as s-expression is
considered a feature, as it helps preventing the proliferation of language
extensions while still allowing them when their benefits outweighs the costs.
Even the main elixir metaprogramming book starts with saying: "the first rule
of macros: don't use macros", and in Julia you have to attach a @ to call a
macro to make it clear that the normal rules of the language do not apply
ahead. Those languages also focus in providing everything the user needs
without the use of macros, which are for more advanced purposes.

While people who use Lisp eventually see the advantages of s-expressions (or
at least of writing more idiomatic code in those languages), being attractive
to new users coming from the more popular languages is very important (and
like clojure interoperate with java, it might be even easier to make a lisp
that has perfect interoperability with Elixir for example, so both groups can
coexist).

~~~
_delirium
Re: "trivial to manipulate code as data as s-expression is considered a
feature"

Although Julia goes further in other directions, just changing the surface
syntax of s-expressions, like this proposal, doesn't really interfere with
this feature. With alternate syntax, you can still write macros and stick to
the code-as-data idea in pretty much the same way. In Lisps with a
programmable reader (like Common Lisp and some Schemes), you can set up the
reader to recognize something like foo[bar,baz] as an sexp, and once read,
it'll be represented internally exactly as if (foo bar baz) had been read with
the default reader. Then any macros and even code-walking code continue to
work the same as before.

~~~
ddragon
I meant that macros being a little harder to use and the result being a little
more restricted is the feature, a small protection against the Lisp Curse (if
every custom language is just as good as the base language, then no one can
agree what the base language should be). Kinda like newer languages kinda
avoid inheritance because while it's powerful, it's kinda easy to misuse
(though Elixir special 'using' macro is a fantastic simple way to share
behavior between modules).

And while programmable reader macros allow Lisp to have any syntax you want,
they go even further in producing heterogeneous environments in which not even
the parsing rules are shared. But you can't just only know the algol/infix way
of programming in Lisp since you'll have to see other people code and
documentation, and when you use these alternate parsers/extensions other
people have to understand the quirks of your unique parser/extension before
understanding your code. Everyone using the exact same language is definitely
a feature, and those languages (and clojure who dropped programmable reader
macros and asks people to use macros more judiciously) have a point in their
belief.

But as a curiosity, Julia also has it's own version of reader macros [1],
which can be used to give it s-expression syntax [2].

[1]
[https://docs.julialang.org/en/v1/manual/metaprogramming/#Non...](https://docs.julialang.org/en/v1/manual/metaprogramming/#Non-
Standard-String-Literals-1)

[2]
[https://github.com/swadey/LispSyntax.jl](https://github.com/swadey/LispSyntax.jl)

~~~
breck
I think you’ll appreciate Tree Notation, which is a dead simple “base
language”, that I think we will get people to agree on.

------
dreamcompiler
There's a line in _The Matrix_ where Neo asks Cypher why he looks at the raw
green code of the Matrix. He replies "You have to...and all I see is blonde,
brunette, redhead" (or something to that effect).

Every time somebody proposes to "fix" Lisp's syntax it reminds me of that
scene. It sounds like a newbie Lisp programmer who hasn't yet experienced the
thrill of seeing beyond the parentheses. And the mind-boggling compositional
utility that comes from leaving them alone.

~~~
singularity2001
The point is: Most of the parentheses are superfluous and removing them (in
the right way) takes nothing away from the mind-boggling compositional
utility.

~~~
dreamcompiler
Parens are anything but superfluous. Substituting whitespace for parens is a
net loss IMO because indentation errors become semantic rather than merely
unaesthetic. And elegant composition is impossible with infix notation unless
-- you add parens again.

~~~
traderjane
Does the Python community struggle with indentation? I thought it was largely
a non-issue.

~~~
thechao
There was a vertical-tab run in ‘13 that really hurt a lot of us; other than
that, the Central Space Bank (at least in the US) has kept things fairly
stable. (This is ignoring the doom-and-gloom quantitative-tab-easing
conspiracy theory nuts.)

------
beders
I've made clojure my main language late last year and while reading lisp code
seemed alien at first, I've now adapted and have no trouble reading
s-expressions. And once you truly understand that `(map inc [1 2 3 4])` is
just a list, things like macros begin to click and you understand the power
that is given to you.

In fact, I'm missing an equivalent to paredit now when I have to go back and
code Java/JavaScript :)

------
yason
Each time as fun.

If you know Lisp you will instinctively convert any syntax back to
S-expressions anyway because that's how things will eventually work anyway and
because you can't think of Lisp macros otherwise. So, the syntax becomes a
burden, and thus you settle for the minimalist, easiest way to denote trees.

Parentheses.

------
elderK
I've read many of the comments.

Lots of talk about removing the parenthesis, using things like Tree-Notation
and such.

Really, all I can say is that you can pry the parens from my cold, dead,
cantankerous hands. :P

Maybe it's because I've been playing with Lisp, in one form or another, on and
off for several years.

But I never found the parens really all that bad.

It's no problem at all as long as you have basic paren matching support in
whatever editor you use.

And if you happen to use an editor that supports the structured manipulation
of S-expressions, well, it's a pretty neat experience.

I think the only time the parens bother me is if I print source code out. But
even then, there are clear conventions on how Lisp source should be laid out
and indented, so you adapt pretty quick, even in the "worst case."

 _shrug_

------
singularity2001
Summary:

Readable is a lisp plugin which allows you to drop superfluous braces and use
function and infix notation:

    
    
      (define (factorial n)
       (if (<= n 1)
        1
        (* n (factorial (- n 1)))))
    

can now be written as

    
    
      define factorial(n)
        if {n <= 1}
          1
          {n * factorial{n - 1}}
    

One more proof that the original lisp is a god like language. And now even
beautiful to look at.

~~~
AlexanderDhoore
"a god like language" Such hyperbole can only be found in the lisp world. You
guys need to take lisp off its pedestal.

~~~
delish
> Such hyperbole can only be found in the lisp world.

Paul Graham may agree with you! Graham found a guy on slashdot with the same
funny notion:

> "I have heard more than one LISP advocate state such subjective comments as,
> "LISP is the most powerful and elegant programming language in the world"
> and expect such comments to be taken as objective truth. I have never heard
> a Java, C++, C, Perl, or Python advocate make the same claim about their own
> language of choice."

> \- A guy on Slashdot. What theory fits this data?

[http://www.paulgraham.com/quotes.html](http://www.paulgraham.com/quotes.html)

~~~
AlexanderDhoore
Any idea what he means with "What theory fits this data" ?

~~~
singularity2001
He is (hyperbolically?) asking for a scientific explanation `why` Lispers are
so convinced of their language (and others not).

------
singularity2001
How do sweet-expressions differentiate between classical (a b(c d)) and its
neoteric reading as (a (b c d)) ?

significant space? (a b(c d)) != (a b (c d)) ?

That would be acceptable (but break backward-compability?)

PS: Thanks for fixing the title but in this case it's much less expressive
than the original.

~~~
dang
The submitted title was "readable lisp with infix and less ((braces))". That
was not the original. The original title is "Readable Lisp S-expressions
Project", so a moderator changed it to that, in accordance with this site
guideline: " _Please use the original title, unless it is misleading or
linkbait._ "

On HN, being the submitter of an article conveys no special rights over the
content, such as how to frame it for readers. If you want to express your
opinion, the place for that is in a comment; then your view is the same level
as other users'. Titles are by far the biggest influence on threads, so this
rule is a big deal.

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

------
gumby
Trying to fix a problem that doesn't exist.

------
goto11
The parentheses in Lisp are like the white-space in Python - something non-
users often get hung-up about when looking at the language, but which turns
out to be a non-issue when using the language for a short while.

A more conventional syntax might look more appealing for non-Lispers, but I
don't think it will make a big difference for adoption. If you want a more
conventional-looking language, there are already plenty to choose from.

------
foobar_
I like begin and end instead of the parens. Allman style ftw!. I've been
thinking of something along the lines of an xml based notation for lisp.

It's a shame lisp doesn't allow a simple text-based preprocessor.

~~~
andyjpb
Something similar to sxml?
[https://en.wikipedia.org/wiki/SXML](https://en.wikipedia.org/wiki/SXML)

XML has attributes which S-exprs don't. This can be solved by convention (as
SXML does) and doesn't really represent a difference in expressibility.

S-exprs have quote and unquote which XML doesn't. This is a fundamental
difference and makes it hard to convert Lisp code that mixes code and data
representations.

