Is a lisp with only functional parentheses possible?

Pondering the philosophy behind the language
newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Is a lisp with only functional parentheses possible?

Post by newdep »

Im poisend at the moment by Functional programming and an overload on parentheses.
I urged myself to build a small parser that removes the very first parentheses
from newlisp in the hope to create/execute visability into the code.
That results indeed in clearer code and is executable but also a disabled language.

When long enough removing parentheses from lisp you will endup killing lisp.
...parenthese per parenthese...

The question is -> "Is a lisp with only functional parentheses possible?"

- "What is a functional parenthese?"
- "Can a lisp exist with only functional parentheses?"
- "Will a lisp be more practical/attractive in use this way?"

Having less parentheses doesnt say you cant have another grouping mechanism.

And, having anonymous functions in the language doesnt make it a lisp!


PS: If i only could move these questions through a functional programming language and see the result..
-- (define? (Cornflakes))

Ryon
Posts: 248
Joined: Thu Sep 26, 2002 12:57 am

Post by Ryon »

One of the beauties of Forth is its use of the data stack. Not only are parentheses unnecessary, but the operands are securely hidden as well. The listing is factored down to a short series of well-named actions.

I remember some experiments with a stack lisp, but don't recall where one would find them. Possibly in the journal Forth Dimensions.

Elica
Posts: 57
Joined: Wed Feb 13, 2008 6:41 pm

Re: Is a lisp with only functional parentheses possible?

Post by Elica »

newdep wrote:When long enough removing parentheses from lisp you will endup killing lisp.
If you remove parentheses carefully you will not kill Lisp, but will end up with Logo.

A Lisp with reduced number of parentheses may appear simpler to novice users, but will definitely be harder to implement (from developer's point of view). For example, the last two Logo dialects which I implemented both had a hidden conversion from Logo to Lisp-like prefix-only full-paranthesised notation which is then used by the compiler/interpreter.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

I'm a big fan of parentheses, as you know...! They provide some major advantages:

- you can easily see the visual structure of your program, and the parentheses provide useful 'handles' for manipulating your source code. Assuming your editor is helping you, it must be easier to select, delete, move, copy, or otherwise manipulate significant portions of your code than it is with some other languages. Presumably you can easily step up and down through the program hierarchy, and easily manipulate the structure with your chosen editor? And also, you should be able to adjust the formatting and colouring so that the parentheses aren't too obtrusive.

- you can format your code the way you want to, since the interpreter cares only for the visible structure elements (parentheses and comments). This is great, because you, the coder, have the first choice about which white-space elements to use, and where; in many non-lisp languages, you usually have to allow the interpreter the first choice of white space, and fit in where you can.

- obviously, it's easier to manipulate the source code as data when it's so clearly delineated. (Although I still want Lutz to incorporate even better source code parsing, so I don't have to rely on my efforts.)

See also http://fare.livejournal.com/77842.html?thread=106770 for an interesting and forthrightly expressed viewpoint.

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

Ryon.. ;-) I do like FORTH indeed.. Have you ever tried Lutz' his
Forthscript ? http://www.newlisp.org/Projects/Gokumanual.html

Elica..Yes true I did pass by Logo when tracking back lisp, actualky when
I look at the parentheses stripped code in newlisp it looks like Logo indeed..:)

Cormullion..I do need parentheses .I love them. Every language I hit while
programming I start with typing "(" ..even C goes in (void main()) format..
So im already poisend with parentheses too much to neglect them..


Perhpas its intresting to know how I came to the question, or not :). I checked on
some other languages I did not spent any time on latelty (last 10 years ;-)
Just to see what the advantages are compaired to newlisp. Well My conclusion
is that newlisp can do a lot. And I was wondering, why i.e. Python became so popular,
as its far from my ideal language or even Perl or Ruby. The answer is actualy
everywhere I read about 'none' mass languages and its simple,
the bulk goes where the bulk is. That doesnt say anything about the power of
the language at all. But because there is a Bulk of users they create bulks of code.
Nothing efficient nothing fancy just bulk. Which in return makes a language
intresting for....yes..the bulk.

Anyway..Personaly I need lamdba's thats something i know for sure. I
also need nested functions, unlimited and type free & case-insensitive
programming. But I also do want clear code. Actualy thats all inside
Scheme Lisp and ofcourse newlisp. And it all depends on your programming
skills to make that visual attractive enough for the eye.


So Is it that Python and Ruby are so popular because, beside the bulk, have
a more 'Imperative' (uhum...) layout? Is this what catches the C programmer
or the masses? I cant emagine that Lisp or Haskell arnt attractive enough
for the bulk..just doesnt fit into my brain..

So I though..I newlisp would have less parentheses it would perhpas not
resemble Lisp too much and one could call it newScript or something to
get the Bulk into newLisp. Because why would you want Type settings
in the first place? I dont know. I can only emagin its because of the
split between scripter and compiler. People who want speed know where
to Find the C language. But if you want efficiency where do you look?
Yes..where the Mass is..the bulk user community.

So in the end I can only try and extent my newLispScript parser
and see what the result is when its done. A more attractive/effective
newLisp or a disabled Newlisp. I do question though if a disabled newlisp
is less attractive..(having less parenthesic effects thats is..)!

Its 34 Degress on the attic and time for a beer.. Actualy I dont even need
a beer ..it all did already hit my head without it...
-- (define? (Cornflakes))

Cyril
Posts: 183
Joined: Tue Oct 30, 2007 6:27 pm
Location: Moscow, Russia
Contact:

Re: Is a lisp with only functional parentheses possible?

Post by Cyril »

newdep wrote:When long enough removing parentheses from lisp you will endup killing lisp.
...parenthese per parenthese...
Hm... Then my favorite lisp-killing device is:

Code: Select all

; This is in fact im my small library of handy tools

(define-macro (make-pass)
  (doargs (arg)
    (letex ((Old arg)
            (New (sym (append (string arg) "&"))))
      (define-macro (New)
        (Old (eval (args)))))))

; library function call

(make-pass catch not print)

; and usage

(catch& while (read-line)
  (setq line (current-line))
  (if (not& empty? line)
    (print& format "%s\n" line)
    (throw 'empty)))

Maybe catch& while is not very good example (I've copied this from a very old code), but not& empty? and print& format are of everyday usage. I just consider them as names of compound concepts.
With newLISP you can grow your lists from the right side!

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Post by TedWalther »

So when will get get reader-macros in newLISP? I'm itching to embed a custom language within newlisp, and then embed newlisp within that, and then the new langauge within that, and then and then and then...

I'm thinking of a list of "hooks" you could push onto a list, and the reader would call those functions if a match is found. Those functions of course would be able to "push back" onto the stream, and would either return a lisp object or would throw an exception saying "evaluate with the next reader on the list", with the default reader being the last one read, first reader matches.

Unlike common lisp, our reader macros could make use of (regex) for dispatching the custom reader on the source code stream. In short, I think Lutz could quickly and simply beat the pants off common lisp reader macros, incorporating them with a very small performance hit.

Ted

Jeremy Dunn
Posts: 95
Joined: Wed Oct 13, 2004 8:02 pm
Location: Bellingham WA

Post by Jeremy Dunn »

Here are a couple of ideas you might try to reduce parentheses:

1. Give function names a special form such as all caps so that your translator can easily find them and have the function names double up as the left parenthesis.

2. Let the square brackets [ and ] act as a replacement for double parentheses. For instance, [ is the same as ((. This would enable clearing up long strings of parentheses. This is something that could be useful in any LISP.

Keep us informed of what you come up with!

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Post by TedWalther »

With reader macros we could try all of these things.

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

Even if I don't like so many parenthsis, I must admit that, if you eliminate them, you can get some seriuos problems.
Rebol is a functional programming language, with several common points with newLisp. One of the biggesst problems of that language (my opinion) is there are no parenthesis, and it is very difficult to visually check/write code. In fact, without parenthesis, you cannot see where a function (or a block) terminates, and where another function (block) starts, unless you perfectly know the functions and its parameters.

See the following example:

Code: Select all

view f: layout for n 0 19 1 [r: (random 19) + n // 20 append [across] load rejoin [ "a"n": check on [a"r"/data: a"r"/data xor on show f]" ]] 
This is a small game in Rebol. As you can see, without a good Rebol programming knowledge, it is very difficult to visually understand the code.
--

Ryon
Posts: 248
Joined: Thu Sep 26, 2002 12:57 am

Post by Ryon »

Itispos
sibletounreadablyformatjus
taboutanything.Sowhat?

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

:-) You are right, in fact it is difficult to find the right point between usability, efficiency, performance, etc...
--

Ryon
Posts: 248
Joined: Thu Sep 26, 2002 12:57 am

Post by Ryon »

I'm not sure the program's usability, efficiency, or performance would be affected by the formatting style, Alessandro, but my efficiency and performance sure would be!

I don't know a thing about Rebol, but I'll bet I could follow about 90% of that listing if it were formatted a bit more plainly. And I have to admit that this is something I cannot do with Lisp. It pretty much all looks the same to me. :-(

Elica
Posts: 57
Joined: Wed Feb 13, 2008 6:41 pm

Post by Elica »

There is one easy recursive solution, but I'm afraid you will not like it, although you may enjoy it. Here it goes:

To solve the problem with parentheses, we can replace them by square brackets. However, this will introduce a new problem - a problem with the square brackets. To solve it, we can replace brackets with parentheses, which will reraise the initial problem. Fortunately, we already know how to solve it.

So, everything is OK - the initial problem is reduced to a sequence of problems, each of which can be solved trivially.

m35
Posts: 171
Joined: Wed Feb 14, 2007 12:54 pm
Location: Carifornia

Post by m35 »

Elica, I would reward you with an Internet for your comment if I could.


I just did a bit of searching and ran across Sweet-expressions. I would be fascinated to see the newLISP's API wieldable with syntax used in more imperative languages.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

This example is proposed in the sweet-expression scenario (http://www.dwheeler.com/readable/version02.html):

Code: Select all

NewLisp

NewLisp is "Lisp-like, general purpose scripting language", with an implementation released under the GPL.
Original Lisp

Here is a sample from their Code patterns document:
    (dolist (file-name (3 (main-args))) 
        (set 'file (open file-name "read"))
        (println "file ---> " file-name)
        (while (read-line file)
            (if (find (main-args 2) (current-line) 0)
            (write-line)))
        (close file))

This is the original formatting. It's a little misleading; the write-line is actually inside the "if", not a sibling of it. Yet another example of how formatting can mislead a reader, when humans use it but computers don't.

Infix is not Default (Version 0.2)

Same thing, with sweet-expressions:

    dolist (file-name (3 (main-args))) 
        set 'file open(file-name "read")
        println "file ---> " file-name
        while read-line(file)
            if find(main-args(2) current-line() 0)
              write-line()
        close file
Presumably someone can write something that does the necessary transformations...

I like his work, and his approach. But he didn't convince me that Lisp syntax is intrinsicially harder to read, given the same amount of familiarity with it that he allows programmers to have with other languages. (Ie years of training in mathematics, Basic and C-style function calling, etc.)
The fact that so many people are compelled to find a “fix” to Lisp syntax indicates to me that there is a problem...

Here’s the problem: for most software developers, programs written solely using s-expressions are hard to read, and they will only voluntarily use programming languages that allow, at least optionally, a more common notation. This is particularly true for the usual infix operations (+, <, and so on). People who use Lisp-based languages all the time eventually learn, but not everyone wants to use them all the time, and even developers who are comfortable with programs in s-expression notation need to share their work with others.
Lisp's syntax looks genuinely hostile to most “normal programmers”.
He's mainly arguing, I think, that programmers in C-style languages would prefer to have Lisp-like features available using their preferred syntax forms. That's great, and you should always use a language you feel comfortable with.

Personally I still find the lisp style clearer, and think this:

Code: Select all

find(main-args(2) current-line() 0)
is not as good as this:

Code: Select all

(find (main-args 2) (current-line) 0)
But I suppose I'm completely brainwashed by now... :)

linli
Posts: 8
Joined: Tue Sep 01, 2009 3:13 pm

Some thoughts on lisp's syntax

Post by linli »

It seems that quite a lot of people(including me) do not like the parentheses of lisp, because it is unnatural, hard to read or whatever else, but currently do we have a better replacement for it? Have a look at the syntax of C-family languages or PL/SQL, they are all trying to be natural, in the end, they have to use different syntactical rules for different things.Personally, I found this sucks! It is too complicated. In addition, if you make any tiny mistake, the complier or interpreter will not accept your code at all! This is why I believe that any kind of "natural" syntaxes suck for programming languages.
Natural languages are good for communications between human beings because we are intelligent, we can correct small mistakes, but computers can not do it and natural languages are so complicated that it is very very easy to make mistakes, programming languages that try to be natural just increase unnecessary complexity. So unless some one finds some other parenthesis-less syntax that still preserve the same simplicity of lisp's syntax, we should not touch it.

m i c h a e l
Posts: 394
Joined: Wed Apr 26, 2006 3:37 am
Location: Oregon, USA
Contact:

Post by m i c h a e l »

Attempts to remove the parentheses from Lisp, both big (like Dylan in the ’90s) and small (such as Sweet-expressions today) have assumed the problem was with the parenthesis itself, instead of the prejudice of non-Lisp programmers against it. Like all differences we encounter for the first time, they can seem strange or even alien. With exposure and interaction, however, we begin to see beyond the differences to behold the essence of something. Most experienced Lisp programmers say the same thing: they no longer see the parentheses. But even this seems to suggest they’re better left unnoticed.

I love the humble parenthesis. The simple beauty of it belies its power. Those who would be ashamed of parentheses have yet to understand them.

m i c h a e l

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Changes to the traditional parenthesis syntax in LISP may not be compatible with the program equals data paradigm. E.g.:

Code: Select all

(set 'lst '( (foo x y) (bar q p) ) )
should this be translated into:

Code: Select all

(set 'lst '( foo(x y) bar(q p) ) )
or not? Imagine something like this:

Code: Select all

(dolist (e lst) (println (eval e)))
is following the first line. This would fail on the sweet-expression translation. I suppose one would not transform quoted expressions. But how many more examples could be constructed needing more complex rules to guide the transformation process?

Like Scheme, newLISP has one namespace and the operator part of a list expression is evaluated. 'foo' and 'bar' may or may not be user-defined or built-in functions. It may not be possible to find out until runtime.

Although Sweet Expressions could be introduced into newLISP they would then either exclude certain programmatic manipulations of program expressions as data or create ambiguities which can only be resolved introducing more complex transformation rules.

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Post by TedWalther »

Lutz wrote:Changes to the traditional parenthesis syntax in LISP may not be compatible with the program equals data paradigm. E.g.:

Code: Select all

(set 'lst '( (foo x y) (bar q p) ) )
should this be translated into:

Code: Select all

(set 'lst '( foo(x y) bar(q p) ) )
or not? Imagine something like this:

Code: Select all

(dolist (e lst) (println (eval e)))
is following the first line. This would fail on the sweet-expression translation. I suppose one would not transform quoted expressions. But how many more examples could be constructed needing more complex rules to guide the transformation process?

Like Scheme, newLISP has one namespace and the operator part of a list expression is evaluated. 'foo' and 'bar' may or may not be user-defined or built-in functions. It may not be possible to find out until runtime.

Although Sweet Expressions could be introduced into newLISP they would then either exclude certain programmatic manipulations of program expressions as data or create ambiguities which can only be resolved introducing more complex transformation rules.
Or, if we get reader macros, sweet expressions will be transformed to standard newlisp, at which point all standard manipulations will apply. The onus of cleverness will be on the function creator.

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

I think that 'less' parentheses only make newlisp more complex regarding quick reading and understanding..I do like though the thought of 'simplyfing'code by the use of "reader macro's".. That could make the language indeed intresting...

Code: Select all

(push 'd [ a b c ] -1 ) -> (a b c d )

or

(set 'lst '( (foo x y) (bar q p) ) )

--> (set 'lst [[ foo x y ][ bar q p ]] )

-----> (set 'lst _ foo x y _ bar q p _ )

or

(begin.......) ->  [.........]

'(............) -> [..........]

(setq X...) ->  [ X .... ]

(define (X) (...) ) ->  [ (X) (...) ]

...still thinking...
-- (define? (Cornflakes))

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Post by TedWalther »

newdep wrote:I think that 'less' parentheses only make newlisp more complex regarding quick reading and understanding..I do like though the thought of 'simplyfing'code by the use of "reader macro's".. That could make the language indeed intresting...
With reader macros we could embed languages within languages within languages.

Imagine the following code:
(add-reader-macro 'c-lang)
(add-reader-macro 'sql-lang)
(add-reader-macro 'html-lang)

(println "hi")

(C
printf("foo%d",1);
i++;
)

(sql
SELECT * FROM ,(amb "table1" "table2")
)

(html
<h1>foo</h1>
,(generate-some-tables))
)
With read macros, someone could implement the , and ,@ quasi-quote operators from Common Lisp. If they really wanted them. Lutz has made a good case they aren't necessary. But with reader macros they could be expanded from their short form into good newlisp style anyway. Even ' could be implemented as a reader macro, and in most LISP's, is.

In the examples above, I assumed that each minilanguage included a comma escape to let you insert the output of a newlisp expression. This allows for endless recursive embedding of languages, C within newlisp within SQL within newlisp within python within newlisp... And all without any of the usual headaches we get when doing escaping. I've been doing php/html/javascript/sql in my dayjob, and I can honestly say the interactions between the four formats causes a lot of headaches. If only they were all written in newlisp with reader macros, they could be mingled and nested within each other safely, to any depth desired, without all sorts of wierd escaping rules.

newdep
Posts: 2038
Joined: Mon Feb 23, 2004 7:40 pm
Location: Netherlands

Post by newdep »

...I realy do like the sound of this and Im currious on How far this could
be taken inside coding.. this would be nice...
-- (define? (Cornflakes))

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Post by Kazimir Majorinc »

I think reader macros make writing code (programming) more friendly, but writing code that processes code (metaprogramming) more difficult.

I do not think that "one who does not want to use reader macros shouldn't use them" is enough. What would happen if someone writes useful library that uses reader macros? Programmers will start to use it. Theoretically, we can remember both new syntax and how it translates into normal Lisp, but in reality, our minds are finite, especially for those who program Newlisp on and off - so we'd start using Lisp as any other language, without understanding how to process code.

This practice would, in turn, influence future development of the language. Although Lutz makes decisions, these are made on the base of the perceived problems and discussions by other programmers.

I could admit that finally, it is not known whether metaprogramming is good idea and that I only believe it is good idea. The failure of Lisp dialects to establish itself as a mainstream language is not a good sign, but recently it appears that Ruby users practice metaprogramming alot. Anycase, metaprogramming is differentia specifica of Lisp; if it is bad idea, Lisp itself is failure. And if it is good idea, it is comparative advantage of Lisp that should be promoted and not discouraged.

From my point of view, following syntax looks OK:

Code: Select all

(load "c-lang")
(load "sql-lang")
(load "html-lang")

(println "hi")

(C "printf(\"foo%d\",1);
    i++;"
)

(sql (append "SELECT * FROM" (amb "\"table1\""  "\"table2\"")))

(html (append "<h1>foo</h1>"
              (generate-some-tables))
) 
I understand why Ted likes his syntax better. Back while I used PLT Scheme, I used °s-expr instead of (println 's-expr "=" s-expr) equivalent. Good for debugging. Reader macros can be fun. But, Ted can implement his own, private preprocessor - on that way, whole thing is interesting and challenging private experiment, and not a language policy.

Code: Select all

(preprocess 
   (add-reader-macro 'c-lang)
   (add-reader-macro 'sql-lang)
   (add-reader-macro 'html-lang)

   (println "hi")

   (C printf("foo%d",1);
      i++;)) 
(I'll publish this post at my blog)

TedWalther
Posts: 608
Joined: Mon Feb 05, 2007 1:04 am
Location: Abbotsford, BC
Contact:

Post by TedWalther »

Kazimir, how would I implement preprocess function without reimplementing all of the newlisp language? To have that type of recursion, the ability to slip back and forth between different languages, requires the ability to read in a newlisp expression, as with read-expr... but to do it recursively, as with a nested list that contains a mini-language at some level, the macro hooks have to be in the reader.

reader macros can be done efficiently and the concept is fairly simple; you pass the stream object to the reader macro, then the reader macro will tell you if it matched or not, and will optionally return a value, and will leave the stream in some modified state, generally just leaving the pointer past the end of the expression that was read in. If the reader macro succeeded, then there is no need for further evaluation. If no reader macro succeeds, then the default implementation, which parses standard newlisp, is used. But in every case, the reader macro returns valid newlisp expressions.

Again, how would one write the preprocessor function you speak of, without having to reimplement the entire newlisp syntax parser in newlisp? It will be a lot easier to slightly modify the reader to incorporate reader macros.

Ted
Kazimir Majorinc wrote:I think reader macros make writing code (programming) more friendly, but writing code that processes code (metaprogramming) more difficult.

I do not think that "one who does not want to use reader macros shouldn't use them" is enough. What would happen if someone writes useful library that uses reader macros? Programmers will start to use it. Theoretically, we can remember both new syntax and how it translates into normal Lisp, but in reality, our minds are finite, especially for those who program Newlisp on and off - so we'd start using Lisp as any other language, without understanding how to process code.

This practice would, in turn, influence future development of the language. Although Lutz makes decisions, these are made on the base of the perceived problems and discussions by other programmers.

I could admit that finally, it is not known whether metaprogramming is good idea and that I only believe it is good idea. The failure of Lisp dialects to establish itself as a mainstream language is not a good sign, but recently it appears that Ruby users practice metaprogramming alot. Anycase, metaprogramming is differentia specifica of Lisp; if it is bad idea, Lisp itself is failure. And if it is good idea, it is comparative advantage of Lisp that should be promoted and not discouraged.

From my point of view, following syntax looks OK:

Code: Select all

(load "c-lang")
(load "sql-lang")
(load "html-lang")

(println "hi")

(C "printf("foo%d",1);
    i++;"
)

(sql (append "SELECT * FROM" (amb ""table1""  ""table2"")))

(html (append "<h1>foo</h1>"
              (generate-some-tables))
) 
I understand why Ted likes his syntax better. Back while I used PLT Scheme, I used °s-expr instead of (println 's-expr "=" s-expr) equivalent. Good for debugging. Reader macros can be fun. But, Ted can implement his own, private preprocessor - on that way, whole thing is interesting and challenging private experiment, and not a language policy.

Code: Select all

(preprocess 
   (add-reader-macro 'c-lang)
   (add-reader-macro 'sql-lang)
   (add-reader-macro 'html-lang)

   (println "hi")

   (C printf("foo%d",1);
      i++;)) 
(I'll publish this post at my blog)

Locked