Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Perl has a lot of syntax, and Lisp has almost none. Which one is better just depends on your opinion about syntax itself.


Lisp also has a lot of syntax, but it is ON TOP of s-expressions.


Hold Common Lisp next to Perl 5, and you tell me which one has "a lot" of syntax.

I realize that Lisp has some syntax, and of course the fact that everything fits into S-exps is important, but I would not say that it has "a lot" of syntax compared to the vast majority of active languages.


Let's just look at the syntax of Common Lisp's LOOP construct:

    loop [name-clause] {variable-clause}* {main-clause}* => result*

    name-clause::= named name 
    variable-clause::= with-clause | initial-final | for-as-clause 
    with-clause::= with var1 [type-spec] [= form1] {and var2 [type-spec] [= form2]}* 
    main-clause::= unconditional | accumulation | conditional | termination-test | initial-final 
    initial-final::= initially compound-form+ | finally compound-form+ 
    unconditional::= {do | doing} compound-form+ | return {form | it} 
    accumulation::= list-accumulation | numeric-accumulation 
    list-accumulation::= {collect | collecting | append | appending | nconc | nconcing} {form | it}  
                         [into simple-var] 
    numeric-accumulation::= {count | counting | sum | summing | } 
                             maximize | maximizing | minimize | minimizing {form | it} 
                            [into simple-var] [type-spec] 
    conditional::= {if | when | unless} form selectable-clause {and selectable-clause}*  
                   [else selectable-clause {and selectable-clause}*]  
                   [end] 
    selectable-clause::= unconditional | accumulation | conditional 
    termination-test::= while form | until form | repeat form | always form | never form | thereis form 
    for-as-clause::= {for | as} for-as-subclause {and for-as-subclause}* 
    for-as-subclause::= for-as-arithmetic | for-as-in-list | for-as-on-list | for-as-equals-then | 
                        for-as-across | for-as-hash | for-as-package 
    for-as-arithmetic::= var [type-spec] for-as-arithmetic-subclause 
    for-as-arithmetic-subclause::= arithmetic-up | arithmetic-downto | arithmetic-downfrom 
    arithmetic-up::= [[{from | upfrom} form1 |   {to | upto | below} form2 |   by form3]]+ 
    arithmetic-downto::= [[{{from form1}}1  |   {{{downto | above} form2}}1  |   by form3]] 
    arithmetic-downfrom::= [[{{downfrom form1}}1  |   {to | downto | above} form2 |   by form3]] 
    for-as-in-list::= var [type-spec] in form1 [by step-fun] 
    for-as-on-list::= var [type-spec] on form1 [by step-fun] 
    for-as-equals-then::= var [type-spec] = form1 [then form2] 
    for-as-across::= var [type-spec] across vector 
    for-as-hash::= var [type-spec] being {each | the}  
                   {{hash-key | hash-keys} {in | of} hash-table  
                    [using (hash-value other-var)] |  
                    {hash-value | hash-values} {in | of} hash-table  
                    [using (hash-key other-var)]} 
    for-as-package::= var [type-spec] being {each | the}  
                      {symbol | symbols | 
                       present-symbol | present-symbols | 
                       external-symbol | external-symbols} 
                      [{in | of} package] 
    type-spec::= simple-type-spec | destructured-type-spec 
    simple-type-spec::= fixnum | float | t | nil 
    destructured-type-spec::= of-type d-type-spec 
    d-type-spec::= type-specifier | (d-type-spec . d-type-spec) 
    var::= d-var-spec 
    var1::= d-var-spec 
    var2::= d-var-spec 
    other-var::= d-var-spec 
    d-var-spec::= simple-var | nil | (d-var-spec . d-var-spec)
I don't think there are many active languages with a more complex LOOP construct. Add to that, that some implementations have an extensible LOOP that allows to add even more syntax to it.

The syntax for DEFCLASS:

    defclass class-name ({superclass-name}*) ({slot-specifier}*) [[class-option]]

    => new-class

    slot-specifier::= slot-name | (slot-name [[slot-option]])
    slot-name::= symbol
    slot-option::= {:reader reader-function-name}* | 
                   {:writer writer-function-name}* | 
                   {:accessor reader-function-name}* | 
                   {:allocation allocation-type} | 
                   {:initarg initarg-name}* | 
                   {:initform form} | 
                   {:type type-specifier} | 
                   {:documentation string} 
    function-name::= {symbol | (setf symbol)}
    class-option::= (:default-initargs . initarg-list) | 
                    (:documentation string) | 
                    (:metaclass class-name) 
there is much more of this.


LOOP is a good example of syntax creeping its way into Lisp (defclass, not all that much IMO).

As a counterexample that almost makes LOOP syntax look quaint, consider Perl regexes. That is some syntax right there.


Common Lisp has more than 30 special syntactic constructs: block, catch, eval-when, LET, ..., unwind-protect.

It has probably more than a hundred macros that implement syntax: DEFUN, LOOP, DEFMACRO, WITH-OPEN-FILE, DEFPACKAGE, PPRINT-LOGICAL-BLOCK, HANDLER-CASE, ...

It has various basic syntactic elements like function lambda lists, macro lambda lists, etc.

It has FORMAT string syntax.

I'm not trying to win a contest with PERL and its syntax, but thinking that Common Lisp has almost no syntax is misguided. As I mentioned, in Common Lisp much of the syntax is implemented on top of s-expressions.

Stuff like regexp syntax is implemented in Common Lisp libraries. Like this one: http://weitz.de/cl-ppcre/ .




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: