It seems like they have attempted to write scheme using JavaScript syntax to avoid having to make any significant changes to the non-code sections of the book. Here is an excerpt, it's not good: function deriv(exp, variable) { return is_number(exp) ? 0 : is_variable(exp) ? is_same_variable(exp, variable) ? 1 : 0 : is_sum(exp) ? make_sum(deriv(addend(exp), variable), deriv(augend(exp), variable)) : is_product(exp) ? m…
The tragedy of JS if blocks being statements not expressions is made explicit here
SICP in JavaScript
31–40 of 126 posts
Re: SICP in JavaScript
#32It seems like they have attempted to write scheme using JavaScript syntax to avoid having to make any significant changes to the non-code sections of the book. Here is an excerpt, it's not good: function deriv(exp, variable) { return is_number(exp) ? 0 : is_variable(exp) ? is_same_variable(exp, variable) ? 1 : 0 : is_sum(exp) ? make_sum(deriv(addend(exp), variable), deriv(augend(exp), variable)) : is_product(exp) ? m…
One thing I have learnt very well from rewriting a legacy PHP code written by amateur teams is: never ever nest ternary operations. maybe it's only me, but it's really hard to reason about this.
Re: SICP in JavaScript
#33Earlier quoted context omitted.
I think the Scheme version of SICP will live on outside of academia and CS undergrad studies. I'm using SICP for self-learning and I had the choice of Scheme, JS, or Python. I still chose Scheme. This is because I figured Scheme would offer something those other languages didn't since Scheme is the original language of the book and Scheme is just "different" than other languages. It forces you to think differently ab…
What's deterring me from pulling the trigger on the Scheme version is the price. CAD$87 seems a bit steep for a paperback edition that's almost 30 years old. The JavaScript version is CAD$20 cheaper.
Even having them ship it to you will probably be cheaper than that CAD price. It's unfortunate the price has shot up so much, I guess I'll be taking very good care of my hardback edition.
https://mitp-content-server.mit.edu/books/content/sectbyfn/b...
Re: SICP in JavaScript
#34Earlier quoted context omitted.
I implemented the Monkey programming language as described in the book Writing An Interpreter In Go. Over time I extended it to support different things, and one of the additions I made was to add support for the ternary operator. In my implementation nested ternary operators were a parse error.
I've been thinking about diving into that book next. Would you recommend? My alternative is Crafting Interpreters by Robert Nystrom.
That said Nystrom's book has adorable drawings, and feels more "passionate".
I've read both, but I only followed the go-book because I was learning Golang at the time. No regrets.
Re: SICP in JavaScript
#35It seems like they have attempted to write scheme using JavaScript syntax to avoid having to make any significant changes to the non-code sections of the book. Here is an excerpt, it's not good: function deriv(exp, variable) { return is_number(exp) ? 0 : is_variable(exp) ? is_same_variable(exp, variable) ? 1 : 0 : is_sum(exp) ? make_sum(deriv(addend(exp), variable), deriv(augend(exp), variable)) : is_product(exp) ? m…
One thing I have learnt very well from rewriting a legacy PHP code written by amateur teams is: never ever nest ternary operations. maybe it's only me, but it's really hard to reason about this.
Re: SICP in JavaScript
#36It seems like they have attempted to write scheme using JavaScript syntax to avoid having to make any significant changes to the non-code sections of the book. Here is an excerpt, it's not good: function deriv(exp, variable) { return is_number(exp) ? 0 : is_variable(exp) ? is_same_variable(exp, variable) ? 1 : 0 : is_sum(exp) ? make_sum(deriv(addend(exp), variable), deriv(augend(exp), variable)) : is_product(exp) ? m…
One thing I have learnt very well from rewriting a legacy PHP code written by amateur teams is: never ever nest ternary operations. maybe it's only me, but it's really hard to reason about this.
The reasoning is because ternary operations eliminate programming singularities.
Example:
var x;
if (someExpression) {
x = True;
}
//var x is undefined
Example 2: var x;
x = someExpression ? true : false;
// use of ternary expression prevents var x from ever being undefined.
The ternary expression forces you to handle the alternative case while the if expression can leave a singularity. A hole where x remains undefined.Some people say ternary expressions are less readable. But Readability depends on your "opinion." There are no hard logical facts about this. So it's a weak-ish argument.
It is actual fact (ie not an opinion) that ternary expressions are categorically more Safe then if-statements. Therefore, they are factually better in terms of hard logical metrics.
This is the reasoning behind nested ternary statements. It's also one of the strange cases in programming where superficial qualitative attributes of "readability" trumps hard and logical benefits. The overwhelming majority of the population will in fact find many nested ternary operations highly unreadable and this "opinion" overrides the logical benefit.
Usually though, to maintain safety and readability I just alias boolean statements with variable names. The complexity of a conditional expression can be reduced by modularizing parts of it under a symbolic name, you don't necessarily have to reduce complexity by forcing the conditional into the more readable bracketed spatial structures favored by if-statements.
Example:
isXgreaterThanY = x > y;
isWlessThan2 = w
Yes technically the ternary expressions are still nested in a way here, but when reading this code you don't have to dive in deep past the symbolic name.Imagine if you have a boolean condition that relies on multitudes of these sub expressions. By defining the final statement as a composition of Named ternary expressions you eliminate the possibility of a hole;... a singularity where one alternative wasn't considered. In my opinion this is the best way to define your logic.
If-statements, imo, should be reserved for functions that are impure (void return type).. code that mutates things and touches IO which is something you as a programmer should keep as minimal and segregated away from the rest of your pure logic as possible.
Example:
if true:
sendDataToIO(data)
//the alternative of not sending data to IO is not a singularity. It is also required... a ternary expression makes less sense here.
Last but not least: The ternary expression is also a bit weak because it only deals with two possible branches: True/False. The safest and most readable primitive to deal with multiple branches of logic is exhaustive pattern matching. Both Rust and Haskell have a form of this. In rust, it is the match keyword.Re: SICP in JavaScript
#37Earlier quoted context omitted.
Unfortunately there is no if-expression in JS so sometimes it's awkward _not_ to use ternaries in multi-line statements - for instance, when writing in an expression only context like a string interpolation or JSX. It's also just annoying to not be able to assign conditionally without using it, instead of a more clear and readable if/else. It's one of the more annoying nits of the Algol legacy. Oh, but fully agreed,…
a function _if(cond, a, b) would probably have been better.
It's not the biggest thing in the world, and I don't want to distract from the rest of the book, but this is a situation where writing a one or two line helper function:
const _ = (cond, a, b) => cond ? a : b;
would have made the code much more readable without much downside that I can see -- at least to my subjective opinion. Maybe I'm missing something.Edit: comment below correctly points out that if it's important for you to avoid immediate evaluation, you'll need to wrap your conditionals in functions.
Re: SICP in JavaScript
#38Earlier quoted context omitted.
Unfortunately there is no if-expression in JS so sometimes it's awkward _not_ to use ternaries in multi-line statements - for instance, when writing in an expression only context like a string interpolation or JSX. It's also just annoying to not be able to assign conditionally without using it, instead of a more clear and readable if/else. It's one of the more annoying nits of the Algol legacy. Oh, but fully agreed,…
a function _if(cond, a, b) would probably have been better.
Re: SICP in JavaScript
#39I might be wrong, but I feel like writing SCIP on JS is like "Sustainable Energy using Oil." Not quite the right analogy... JS isn't as bad as Oil. But you get the idea... Kinda... don't make sense?
Re: SICP in JavaScript
#40Earlier quoted context omitted.
a function _if(cond, a, b) would probably have been better.
Beat me to it :) It's not the biggest thing in the world, and I don't want to distract from the rest of the book, but this is a situation where writing a one or two line helper function: const _ = (cond, a, b) => cond ? a : b; would have made the code much more readable without much downside that I can see -- at least to my subjective opinion. Maybe I'm missing something. Edit: comment below correctly points out that…
_(cond, () => a, () => b)
And _ becomes: const _ = (cond, a, b) => cond? a(): b();
And it does matter in this case when looking at the last condition which signals an error (does not return an error value if I understand it correctly). In which case your _ would raise an error even when not appropriate.