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

"Lisp has no syntax" really means "Lisp has no specific syntax". Any well-parenthesized S-expr is a syntactically valid Lisp program, even if it is nonsensical. Most other languages (including Forth) have keyword and syntax-dependent structuring.


> Any well-parenthesized S-expr is a syntactically valid Lisp program

It isn't. It's just a valid S-expr.

For example

((a b c) (d e f)) is not a valid Common Lisp program.

(let foo bar baz) is also not a valid Common Lisp program.

The syntax for LET is:

   let ({var | (var [init-form])}*) declaration* form*
SBCL:

  ; in: LET A
  ;     (LET A
  ;       B
  ;       C)
  ; 
  ; caught ERROR:
  ;   Malformed LET bindings: A.
  ; 
  ; compilation unit finished
  ;   caught 1 ERROR condition
LET is a built-in operator. It's not a function and not a macro.


> Any well-parenthesized S-expr is a syntactically valid Lisp program, even if it is nonsensical.

Which version of Lisp are you talking about? A very brief web search showed eg https://stackoverflow.com/questions/40210896/syntax-error-in...

For something really simple, try `(define define)` in Scheme.

I'd say Forth has less syntax than Lisp. But that's perhaps a reflection of most Forth implementations using some clever tricks to offload much of what's handled by syntax in other languages.

Eg defining new functions (ie 'words' in Forth terms) is not done via a special syntactic construct in Forth, but via 'immediate words'. The lines are a but blurry, though.


This is not a Lisp syntax error, this is a 'cond' macro syntax error.

The language has no syntax, the constructs within the language can and do impose additional restrictions (not extensions - restrictions) when evaluated. You may not find the distinction useful, but it is there.


Check the Common Lisp specification some time.

Every language construct has a syntax definition: function calls, macro calls, lambda expressions, special operator calls, ..., every macro.


Racket calls it a syntax error. I defer to them on the classification of their errors.


Neither Racket, nor any Scheme implementation calls (define define) a syntax error in general. It is only an error when define is defined to define, as it is in the base environment. If you have an environment where define does not define, (define define) may work.

Welcome to Racket v8.9 [bc].

> (define (define x) (display "Look ma, no error!\n"))

> (define define)

Look ma, no error!


In Common Lisp the identifiers in package Common Lisp are not allowed to be redefined.


It may be semantically invalid in Common Lisp, but it is syntactically valid in Lisp (as seen by observing different dialects).


The term "Lisp" is undefined. Common Lisp is an actual standard for a programming language with a specification. Its core symbols are reserved identifiers.

Anyway, if you would be allowed to reimplement a built-in operator, then from then on you would be using the new operator and you would be limited to its syntax.

Common Lisp OTOH provides namespaces (called "package") and there is a pre-defined namespace "COMMON-LISP" for the core language.


> The term "Lisp" is undefined

This hasn't been a problem in this thread thus far, but to be explicit, this seems like a good definition: https://en.wikipedia.org/wiki/Lisp_%28programming_language%2...

Given that definition, we can see that there are many actual standards for programming languages with specifications under the name "Lisp". Scheme - as was mentioned in this thread, is one such standard, along with Common Lisp.

> Anyway, if you would be allowed to reimplement a built-in operator, then from then on you would be using the new operator and you would be limited to its syntax.

I think you're arguing the merits of doing something like redefining define here, which is not the subject of this comment chain. Of course such behavior is questionable at best. The comment chain is discussing if such a thing would be valid in Lisp - and, in some dialects (such as Scheme) it is.

Scheme also has a feature called "libraries" which makes such behavior more feasible, as you could still have access to the shadowed primitive. Consider:

gosh[r7rs.user]$ (import (prefix (scheme base) base:))

gosh[r7rs.user]$ (define (define x) 5)

define

gosh[r7rs.user]$ (base:define x (+ (define define) (define define)))

x

gosh[r7rs.user]$ x

10


> Scheme - as was mentioned in this thread, is one such standard, along with Common Lisp.

Then see the Scheme standards. They include a syntax definition.

> The comment chain is discussing if such a thing would be valid in Lisp - and, in some dialects (such as Scheme) it is.

Lisp is not a defined language, thus you can assume anything.

My point is: Lisp dialects have syntax. This syntax is usually defined on top of s-expressions. S-expressions also have a syntax, but this syntax usually (there are exceptions) describes only data types (lists, conses, numbers, strings, symbols, arrays, records/structures, bit vectors, pathnames, ...) and not the actual programming language with its operators (functions, macros, special operators) & their way to define and invoke them.

Example: The LET operator in various Lisp dialects there have a specific syntax. This syntax is not the syntax of simple function calls like (operator arg0 ... args).

R7RS small defines this syntax (and also calls it syntax):

  (let ⟨bindings⟩ ⟨body⟩)
  (let ⟨variable⟩ (⟨binding spec⟩*) ⟨tail body⟩)

  ⟨Bindings⟩ has the form ((⟨variable1⟩ ⟨init1⟩) ...)
If you write let forms which don't use this syntax, then they are not valid R7RS Scheme let forms, even though they are valid s-expressions.




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

Search: