The code is convoluted, in my opinion, because it tries to hue too closely to the Scheme code in the original giving some unnatural looking JS code as a result. For example:
function member(item, x) {
return is_null(x)
? null
: item === head(x)
? x
: member(item, tail(x));
}
There are examples which have even more but that was the first one I came across clicking the TOC randomly. In Scheme it would be expressed something like this: (define (member? item set)
(cond ((null? set) #f)
((equal? item (car set)) #t)
(else (member item (cdr set)))))
While the parens cause some brains to segfault, the structure of this (how each condition ties to each result) is clearer than that JS mess. function member(item, x) {
return /* if */ is_null(x)
? /* then */ null
: /* elif */ item === head(x)
? /* then */ x
: /* else */ member(item, tail(x));
} (define (member? item set)
(cond ((null? set) #f)
((equal? item (car set)) #t)
(else (member? item (cdr set)))))
For bonus points, line up the key variable in the clauses, and it's easier to see visually that the `cond` is about that one variable: (define (member? item set)
(cond ((null? set) #f)
((equal? (car set) item) #t)
(else (member? item (cdr set)))))
Which accidentally also lines up with one of the procedure's arguments, though I didn't intend that one, but you could double down on that: (define (member? item set)
(cond ((null? set) #f)
((equal? item (car set)) #t)
(else (member? item (cdr set)))))
This isn't some deep thing; just a little example of how sometimes whitespace, other than just indenting at the beginning of the line, helps to exposure some of the structure visually.And in fact I _think_ some engines do have TCO (bun? javascriptcore?), but I could be wrong
So TCO is part of the language standard but not universally implemented. You are correct about the ones that support it.
When I say Scheme is expression based, I am alluding to the fact that constructs such as `if`, `cond`, `case` etc. are all expressions. Scheme also has several binding constructs (let, letrec, etc) that allows in an expression context to bind the result of a computation in a subexpression. These are all expressions.
The expression version of `if` is in JavaScript called ternary if. A direct translation from Scheme to JavaScript therefore uses ternary if.
But why make a direct translation?
Well, later in the book one writes an interpreter for Scheme. This interpreter shows how the expression based language constructs are implemented. It is therefore necessary that the reader is very familiar with these constructs.
Maybe reading this will help:
https://cseducators.stackexchange.com/questions/7478/which-b...
How to design programs (mentioned in the article).
If you mean 'SICP but in a language that's more popular nowadays', there's SICP in JavaScript.
If you mean a newer book which teaches CS in Scheme, I don't really know. HtDP uses Racket, which is a spin-off of Scheme, but outside of that I'm not really aware of any books which could be called 'modern'. There's Concrete Abstractions, which I would call 'SICP-lite' as it's a fair bit lighter on the maths, so that would be my first go-to if the maths are a bit intimidating.
Peter Van Roy, Concepts, Techniques, and Models of Computer Programming, 2004
It uses the language developed in this book (Oz).
The book constructs many of the current programming paradigms, starting from almost nothing, with an emphasis on software design.
See the paradigms poster built http://www.info.ucl.ac.be/people/PVR/paradigmsDIAGRAMeng201....
I would mention Knuth, but many problems in his books are still yealding PhDs. Way above my grade.
There is a lot of problems I would like to look at hints.
Kudos to your achievement.
SICP is a graduate level text? That was literally the first CS book I had to buy as an undergrad.