Live data from Hacker News

SICP: JavaScript Edition available for pre-order

mitpress.mit.edu

101–110 of 123 posts

Re: SICP: JavaScript Edition available for pre-order

#101
post #58
post #8

First they replace Scheme with Python for their CS classes, and now SICP in JavaScript! Isn't this another portent from Nostradamus about the coming of the end of the world?

It's not the worst thing to happen, but for the love of god, couldn't they have at least chosen an expression oriented language?! Even Ruby for god's sakes would've been better than JS!

If they were to choose another language, StandardML should have been the choice.

It was designed to be easy for students to implement with relatively easy parsing rules. It is fully functional, but allows mutations. It also has an actually sound type system.

Re: SICP: JavaScript Edition available for pre-order

#102

Earlier quoted context omitted.

Yeah, imagine the craziness of making materials like this accessible to users of the most widely used language.

SCIP uses an amount of high-level functions that are frankly ridiculous outside of a very functional language. Hell, maybe even outside of a Lisp-1. That's not to say that Scheme is the best language (probably not in my top 5), but there are better languages than javascript for SCIP, and better programming methods than SCIP for javascript.

Which remotely popular language would be a better choice?

The only ones that leap to mind are the ML languages.

Re: SICP: JavaScript Edition available for pre-order

#103
post #6

One major benefit here is how approachable this is. One could even simply open Dev Tools on their browser and use the console as a REPL. As someone who installed Scheme/Dr Scheme/Dr Racket long ago, it's nice to say, "you can get started right now". I know there'll be a lot of complaint about JS as a language choice but, it's pretty ubiquitous. And, much like Scheme, no one's saying, "you should use this for your nex…

Though I'm sure there are a few Scheme interpreters written in JS or that compile to WebAssembly and so are just about as accessible.

Right, but if we're looking for the quickest path, "right click on this page, and select 'Inspect'" and boom. You're there. Certainly one could go to https://replit.com/ and choose from a host of "better" languages. My approach was trying to avoid someone having to install anything at all. As soon as you say, "ok, you'll need to install NodeJS, then use npm to install this package....", things get dicey. Someone who's serious about learning will fight through it, but someone who's just starting out may be put off.

Re: SICP: JavaScript Edition available for pre-order

#104
post #72

Earlier quoted context omitted.

If you have a browser on a computer you have a js repl.

That's what I had assumed but wanted to double check since "accessible" is ambiguous. However, it's not all that convincing of an argument. Several languages are installed as easy as a browser is. And loading a local file, such as code included with a book, in the developer console quickly goes beyond accessible.

You don't even have to install a browser on any popular OS you can name.

JS REPL and dev tools are also far better than almost anything outside of Common Lisp.

Re: SICP: JavaScript Edition available for pre-order

#105
post #36

Javascript is eating the world. Only WASM can save us now.

JS isn't just popular because of the browser.

It has a TON of syntactit niceties today. Most of the warts are no longer relevant (here's to a future "use strict 2" mode that eliminates the really bad type coercion bits).

It hits a very pragmatic center where you can do OOP, but top-level functions are also possible (looking at you Java).

JS also has good functions. Closures that don't require spelling everything out, first-class functions that can be passed around to other functions, anonymous functions, etc. Outside of currying, it has almost everything you'd want functions to have. That's something sorely missing in languages like Python (lambdas), Ruby (proc/lambda/block mess), PHP (no implicit closures), Java (no first-class functions), etc.

Re: SICP: JavaScript Edition available for pre-order

#106
post #81

Earlier quoted context omitted.

I was doing some Javascript coding today. A false != x test failed for a zero-valued x; had to make it !==. WTF? I never want false and 0 to be other than different objects. Almost every twist and turn in this language is an imbecillic clusterfuck. I had one instance of a if (foo.bar = 0) typo; no warning from the implementation. Why do we want stupid C mistakes in a higher level language, without the C fixes for the…

Once you learn the quirks of JavaScript you get used to it. Also you should not use forEach in JS, take a quick look at this page. https://phoenix35.js.org/good-practices.html

If forEach is not to be used, it should be deprecated and removed from the language in a timely manner.

The objection that it's not functional is invalid; procedural traversal with a callback function, object or closure, is a time-honored pattern in software.

Most of the other problems cited are not with forEach per se but the language in which forEach finds itself.

None of the alternatives presented are more attractive than

  for (let i = 0; i 
If we could just run this through the C preprocessor, we could have

  foreach (i, elem, obj) {

  }
by way of something like:

  #define foreach(ivar, elvar, obj) \
    for (let ivar = 0, elvar; \
         ivar 
Since Javascript is based on C syntax, it should have the preprocessor that the birthplace of C saw it fit for that language not to be without.

Re: SICP: JavaScript Edition available for pre-order

#107

I have a copy of SICP right next to me, and it's one of my favorite computer science books. I'm not sure how I feel about this javascript edition though...

I was doing some Javascript coding today. A false != x test failed for a zero-valued x; had to make it !==. WTF? I never want false and 0 to be other than different objects. Almost every twist and turn in this language is an imbecillic clusterfuck. I had one instance of a if (foo.bar = 0) typo; no warning from the implementation. Why do we want stupid C mistakes in a higher level language, without the C fixes for the…

> Oops! In the following, j isn't lexical:

I don't think I'm correct here. However, be that as it may, in my code, when I moved that second variable before the loop and initialized it there with a let, the behavior somehow changed.

Re: SICP: JavaScript Edition available for pre-order

#108

I have a copy of SICP right next to me, and it's one of my favorite computer science books. I'm not sure how I feel about this javascript edition though...

I was doing some Javascript coding today. A false != x test failed for a zero-valued x; had to make it !==. WTF? I never want false and 0 to be other than different objects. Almost every twist and turn in this language is an imbecillic clusterfuck. I had one instance of a if (foo.bar = 0) typo; no warning from the implementation. Why do we want stupid C mistakes in a higher level language, without the C fixes for the…

Some of this is a lack of familiarity. You wouldn't dream of using C without reading a book first. You wouldn't dream of tackling a Java project without reading on the topic. You wouldn't even dream of trying something as simple as Python without a bunch of reading.

Why do you try to code JS without reading about the language? It's the only language where people consistently try this kind of thing.

> false != x

Referential equality operator is `!==` (which isn't so different from lisp where you have eq, eql, equal, string=, etc). Fun fact: Eich didn't have type coersion in the language at first. It was added at the insistence of developers (something he regrets, but Microsoft forced this to stay in the spec)

> function () { switch (WTF) { } }();

A lot of languages don't make switch statements into expressions. The fact that JS can do this via a function while most other popular languages cannot do it at all is a benefit if anything (there is a proposal to allow these to be expressions). More generally, prefer this

    let foo
    switch (abc) {
      case "blah":
        foo = 123
        break;
    }
> the switch statement has the idiotic break with fallthrough found in C.

It actually gets this from Java. Eich was told to make the language look like Java and he did.

> dict[key] = (dict[key] || 0) + 1;

Your code is potentially bad. `||` uses "falsey" values. If the key is zero, the left-hand side will return false forcing the right-hand side. Use `dict[key] ?? 0` instead as it will only return the right-hand side if the left side is `undefined` or `null`.

If it is a pure dictionary, you are using the wrong construct too. Use `Map` instead

    let dict = new Map()
    dict.set((dict.get(key) ?? 0) + 1)
> this calls for two dictionary key lookups. You want this sort of thing in a single operation.

You get a value rather than a reference. I believe the JIT can optimize this pattern. If you are really fixated on using a reference, store an object with a value instead so you can grab and keep an object reference.

> What is "function scope" and why even have something so idiotic?

In lisp, you'd use `(let ((foo 123)) (print foo))` to set an explicit scope. ES4 proposal had a let block which I think would have been a better idea than the current stuff. Function hoisting generally occurs in other languages one way or another, but is hidden from the user.

> for (let i = 0, j = 0; ....

Yep, this is one more reason why the correct fix was a let block with `let (i=0, j=0) for (; ...)` or 1et for (var i=0, j=0...`

> Appending together Lists has functional semantics, like Lisp:

Array.prototype.concat goes back to at least the ES3 spec as does Array.prototype.push. At the time, arrays were either implemented as hashtables or linked lists. My guess is that adding a single entry to the hashtable only occasionally caused a resize while concatenating N lists was almost guaranteed to do so. I think they decided that it was easier for implementors to just create a new reference.

Since ES5, most new array APIs have favored returning new lists for everything. I think there's a case for making new versions of those older APIs that behave immutably.

> if (foo.bar.indexOf[key] This could happen in any language with a methodNotFound handler. For what it's worth, `if (foo.bar.contains(key)) {code}` would be the better way of writing it. I think Typescript would also catch this (though I'm not 100% as I don't remember ever having made that particular mistake).

> Every damned object is a dictionary with properties you can access as strings with square bracket indexing, and that is always safe: it yields undefined if the property is not found.

Garbage In; Garbage Out. At least it handles that garbage in a safe manner. What more could you ask from a dynamic language?

Re: SICP: JavaScript Edition available for pre-order

#109
post #81

Earlier quoted context omitted.

Once you learn the quirks of JavaScript you get used to it. Also you should not use forEach in JS, take a quick look at this page. https://phoenix35.js.org/good-practices.html

If forEach is not to be used, it should be deprecated and removed from the language in a timely manner. The objection that it's not functional is invalid; procedural traversal with a callback function, object or closure, is a time-honored pattern in software. Most of the other problems cited are not with forEach per se but the language in which forEach finds itself. None of the alternatives presented are more attract…

> If forEach is not to be used

That source is simply incorrect. forEach is perfectly fine to use as long as you realize what is happening. It iterates an array where each thing is a function that returns a promise. Of course the results aren't what they expect.

ES5 array additions suffer from being a little too early (though later stuff wouldn't exist otherwise, so...). They are designed to deal with holey arrays (arrays with indexes missing). This is extremely uncommon today, but was decently common once upon a time. They were also created before the iterator protocol.

The real fix is to design iterator versions that can handle things like async generator functions.

> it should be deprecated and removed from the language in a timely manner.

NOTHING can be removed from the language once added. Doing that would break all the older websites that depend on it (technically, a few minor breaks happened after they tested millions of sites and couldn't find anything that was adversely affected). At best, they can block older features from newer features. For example, using class syntax or a bunch of other ES6 language structures automatically makes your code shift into "use strict" mode.

I hope they introduce a "use strict 2" variant that strips away more of the undesirable features than the current "use strict" does.

> Since Javascript is based on C syntax, it should have the preprocessor that the birthplace of C saw it fit for that language not to be without.

That pre-processor was a source of untold nightmares. Direct injection leads to bugs. If someone is going that route, full-blown macros are the only answer. There is a full-blown macro system Mozilla created a few years ago, but it's not very popular.

https://www.sweetjs.org/

There also exist some C-style pre-processors for babel too, but they should be avoided because lisp's gensym is a critical feature that they and C both lack.

Re: SICP: JavaScript Edition available for pre-order

#110
post #71

Earlier quoted context omitted.

I've really noticed that people rage that Javascript and npm removed so much of a barrier to tech. Try publishing a dependency for Java. Now try doing it for JS. Everyone was able to do highly concurrent workloads. Something that was extremely difficult before Javascript. It just smells of elitism to me. It's a wonderful language that brought the async await system to everyone.

It's C# that created and popularized async/await, not JS (and it having an already open source implementation at the time, it was available to everyone for free).

JS introduced promises to the world around 2005 (they were in an unused experimental language a few years before).

async/await is mostly specialized syntax over generators. I'd note that ES4 had generators in the early 2000s

F# introduced async/await in 2007.

C# was mostly copying F# (like it's done for almost every new feature in the past decade or so).

Haskell libraries added support around the same time as C# (likely inspired by F#)

JS had the feature for several years via transpilers before it was finally added officially.

Post reply on HN