Pick a famous computer scientist, and the odds are better than even they've written a paper or two on this topic.
Of course parsers are described by recursive functions, that's because recursive functions usually describe a push-down automata or a DFA, which you know, is needed for a parser.
But describing a parser is not easy, even in lispy languages ... you still need a declarative syntax (like BNF or PEGs) for those rules, you still need a strategy (like LL(*) or LALR(1)), you still need to deal with context-dependent constructs, and you still need an AST that must be optimized.
Text parsing is also not one of Lisp's strengths. Many implementations don't even have proper regexp engines ... but indeed, it's easy to translate any language to LISP as long as you're goal is not to generate something human readable.
Like this one: http://weitz.de/cl-ppcre/
Perl 6 is Lisp with a decent syntax, and minus a lot of assumptions about how lists should be represented :)
ref: http://irclog.perlgeek.de/perl6/2010-01-15#i_1905210
He then goes onto to mention that despite all the trappings of OO, Perl 6 is fundamentally more in the FP camp
I'm no Lisp guru, not even proficient but isn't saying that kind of missing a large point of Lisp in that code is data and data is a list/sexpresion or what ever it's called?
I am unsure if I would call it a feature.
Calling perl syntax "decent", and by implication better than lisp syntax (such as there is) is mind bending.
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.
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.As a counterexample that almost makes LOOP syntax look quaint, consider Perl regexes. That is some syntax right there.
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/ .
Both Lisp and Perl are in the same camp ... I could hardly read an algorithm written in them before learning and actively working with them.
Either way, I'm tired of languages that can only be extended by adding functions. Declarative APIs require much more than that.
s/natural/English/. Some languages can be parsed by computer without problems. For example, simple 15kb C program can parse 100% of technical text in Esperanto, 98% of technical text in Ukrainian (my native language), 84% of technical text in Russian, and so on. Not so simple parser can parse more than 100% of text, i.e. it can fix errors in text.
For me, shell is much closer to my native language than perl or SQL.
PS. AFAIK, there is no natural language in the wild nature. :-/ All human languages are artificial.