JS is a good starting language, for the typical starting student, because it helps them cultivate their intrinsic motivation.
Less importantly, but still important to me: JS is also a more beautiful language than most mainstream languages, except for the ten or fifteen god-awful warts that it admittedly has, that everyone is disproportionately obsessed with.
(I, unlike most of my students, was interested in computational thinking from the very beginning: iteration, recursion, data types, algorithms, etc, and I was uninterested in actually making things. My first languages were BASIC and Pascal and C, and as far as I can tell, that worked out okay.)
For instance: brush your teeth, then put on your clothes, then get in the car, then start it.
The "JavaScript" way to do this is that starting your car is somehow nested inside of the brush your teeth event. Everything is a callback of everything else, so trying to explain to your computer what you want it to do ends up as a giant spaghetti mess.
Obviously there is a JavaScript way of thinking that allows you to think of brushing your teeth as a dependency to starting your car, but I don't think that this is how most humans think by default, so it's a terrible way to teach students.
It makes them think that computers are these complicated things that take some immense skill to operate, but they're not anymore. You just need to tell the machine what to do, and good languages like python make that really easy.
At this point in my life, I'm mostly writing C++, JavaScript, and golang, but I'm extremely thankful that I started with python. When I need to bang out a prototype, or test something in code, it is always my go to.
function first(cb) {
console.log('first');
cb();
}
function second() {
console.log('second');
}
first(second);
can now be expressed as new Promise().then(console.log('first'))
.then(console.log('second');
or async function first() {
console.log('first');
}
async function second() {
console.log('second');
}
async () => {
await first();
await second();
}();
depending on exactly what your goals are. The inversion of order ("callback hell") can be avoided if you stick to modern concepts. print "first"
print "second"
I mean...imagine explaining your example to somebody. That's difficult for some programmers to fully understand. import asyncio
async def first():
print("first")
async def second():
print("second")
async def _():
await first()
await second()
asyncio.run(_())
prior to python3.7, python didn't have similarly clean asynchronous programming tools. With python 3.5+, you could use the old event loop syntax [1] to do it, and prior to that, you needed to use `yield` and `yield from` for similar semantics.If you want synchronous stuff in JS, this suffices:
console.log('first');
console.log('second');
EDIT:The problem that JS had (prior to promises in ES5) was that the only way to do deferred/asynchronous things (like "run this after I get data from a network call") was to provide a callback, something like
function(resource_url, callback) {
data = get(resource_url);
callback(data);
}
This gets very trick very fast if you want to have chained calls (imagine that `callback` also conditionally requests a resource, and you want to do something with that resource, and based on that you may want to redraw the DOM and then...).There wasn't a good pattern for describing that in JS. The "common" pattern was to just have callbacks within callbacks, and unlike in python you'd often use anonymous functions, so you end up with nested anonymous functions which inverts the way you think, it's really hard to grok.
Promises and async/await linearize that, but that's a problem that python never really had to address because up until very recently, python didn't get used for async stuff.
[1]: https://docs.python.org/3.6/library/asyncio-task.html#exampl...