3 ms·
This is awesome. I have two comments 1. Does this mean we don't need static type-checking? 2. Instead of (lambda (x y) (let ((xs (* x x))
by galaxyLogic 4y ago
This is awesome. I have two comments
1. Does this mean we don't need static type-checking?
2. Instead of
(lambda (x y)
(let ((xs (* x x))
(ys (* y y)))
(sqrt (+ xs ys))))
why don't they (the article) format it like:
(lambda (x y)
(let ( (xs (* x x))
(ys (* y y))
)
(sqrt (+ xs ys))
)
)
The rule could be: Never have more than
TWO consecutive closing ')' on the same line.
If you're trying to prove the benefits of
a syntax, the reader should not need to
spend energy on trying to understand which
closing ')' correspond to which opening '('.
- hedgehog0 4y ago
- xdavidliu 4y agothe overwhelming convention in Lisp (both Scheme and Common Lisp) seems to be to never have a closing paren by itself. I'm not sure why, but I also prefer it that way. Most editors like emacs and modern IDEs also highlight matching parens, so usually this is not really an issue.
- stew-j 4y ago1. Values (objects) in Scheme are tagged, carrying the type with them. And no, a variable, the identifier that names a location which stores a value isn't statically typed. From R6RS: https://docs.racket-lang.org/r6rs/r6rs-std/r6rs-Z-H-4.html#node_sec_1.1 https://docs.racket-lang.org/r6rs/r6rs-std/r6rs-Z-H-4.html#n... > Scheme has latent as opposed to manifest types. Types are associated with objects (also called values) rather than with variables. (Some authors refer to languages with latent types as untyped, weakly typed or dynamically typed languages.) Other languages with latent types are Python, Ruby, Smalltalk, and other dialects of Lisp. Languages with manifest types (sometimes referred to as strongly typed or statically typed languages) include Algol 60, C, C#, Java, Haskell, and ML. The Scheme standards are very concise and readable. 2. Sometimes we Schemers will leave an orphan paren, like if we want to leave a place temporarily for new code. The primary benefit of all on the same line, IMO, is it is more compact vertically and most Lisp programmers rely on paren matching anyway. If you program in Scheme long enough, you can just "see" the level of nesting by the apparent contour of parenthesis. (If you don't understand this, that's probably a good thing.)
- kazinator 4y agoThe article is following the predominant formatting method for Lisp dialects. What you propose is not unheard of, even in professional code bases, but very rare. In the predominant style, nobody worries about which specific closing parenthesis goes with which opening one. The indentation reveals the subordination structure, and the editor takes care of that. Speaking of indentation, you have it wrong: the sqrt should be indented inside the let. (lambda (x y) (let ((xs (* x x)) (ys (* y y))) (sqrt (+ xs ys)))) ^^^^ At the ^^^^ spot, all that matters is that we have four closing parentheses. They are all the same otherwise. Which specific one closes the let is not informative. There are too many parentheses to be focused on them; you have to learn mostly not to see them, except within a line of code where there is no indentation. Someone who has been working with the language for a while just "sees" this: lambda (x y) let (xs (* x x)) (ys (* y y)) sqrt (+ xs ys) Or maybe even this: lambda (x y) let xs (* x x) ys (* y y) sqrt (+ xs ys) (The question of "why not make that the syntax" has been thoroughly explored; it exists out there in some forms, along with other proposals for alternative Lisp syntaxes. https://srfi.schemers.org/srfi-110/srfi-110.html https://srfi.schemers.org/srfi-110/srfi-110.html )
- galaxyLogic 4y ago> Speaking of indentation, you have it wrong .. That just tells me I got the indentation wrong because it did not clearly indicate the syntactic components of the expression. > Someone who has been working with the language for a while just "sees" this: ... I take your word for that. I have been working with Lisp for years but not recently, and I had trouble figuring out the meaning of the example code. I even got it wrong you say. It's clear for Lisp experts I'm sure but not everybody is a Lisp expert.
- kazinator 4y agoPardon me; I see the indentation is wrong in the original article by Bob Calco. I rely on indentation; if the indentation is bungled, there is a good chance I will misunderstand the code. I'm not going to count parentheses to see that something was falsely de-indented to look like it doesn't belong to the preceding block.
- lispm 4y agoWhen trained to read Lisp, the human reader concentrates on indentation, code shape and the leading symbols. The leading symbols determine the syntax of the expression. LAMBDA = lambda (args) body LET = let (bindings) body binding = (var [value]) | var actually the syntax is quite a bit more complex, since args have a lot of options and both LET & LAMBDA allow type declarations. Each of the symbols also determine a certain indentation style and code shape. There are built-in operators, macro operators and function calls. Especially macros provide an unbound amount of syntactic possibilities. Trying to figure out expressions by looking at parentheses and finding pairs by parenthesis alignment is mostly not used. It's a too complex visual operation.
- galaxyLogic 4y agoIt's not too complex IF you align the parenthesis. The only reason I can see to put multiple closing parenthesis on the same line is to save vertical space. But if you pack too much code in a few lines, readability suffers. To get the semantics of your statements right you do need to know where syntactic units start and end.