The current standard for Scheme is referred to as R6RS
R7RS small has been out since 2013. But yeah... "it's complicated".
We did an experiment a few months ago with compiling Gambit to JS and then serving it as an Office extension, using our JS FFI to interface with the Office JS library. Worked out of the box, but definitely some performance cost. Curious about performance on .NET.
BTW if Bob reads this, happy to hear you talk about this at the upcoming Scheme Workshop :) I guess this isn't available on Excel on the web?
Not stellar compared to something like guile and straight up slow as molasses compared to chez. But I don't think that is the goal. It is probably on par with Python for many things.
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 '('.
The 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 )
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.
Pardon 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.
1. 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:
> 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.)
When 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.
It'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.
the 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.
How do you buy it? I just see a lot hype, but no link to purchase it. I am still playing around with Corman Lisp! I'd love to see how I can add Scheme to my Excel sheets, and a REPL to boot!
Thanks that looks really good. I don't use .Net platform, so I am not a potential user, but for Lispers using the .Net platform, this would be nice.
I use Common Lisp a lot in my work and my own research programming, and language interop is always a nuisance. With IronScheme, it looks like interop with all .Net languages is easy.