Is JavaScript more like Lisp/Scheme with C-like syntax?

In Douglas Crockford's JavaScript: The World's Most Misunderstood Language, he writes:

JavaScript's C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java.

@bh is this really true?

Yes. It has a real lambda (unlike Python's half-assed one) and lexically scoped internal definitions. Types are properly associated with data rather than with variables. Other than the syntax, its only real weakness is that it gets object prototyping wrong -- it has a separate kind of thing called a prototype, which is just a class in sheep's clothing, as opposed to the Snap! OOP system, in which any object can serve as the prototype for another object.

But, yeah, if someone held a gun to my head and told me I had to teach a language that students can get a job in, I'd definitely choose JavaScript.

I think you're talking about SELF. JavaScript's prototypes pretty much exactly match Snap's, and any object can be any other's prototype. Other than that I agree: JavaScript is more of a functional programming language at heart.

Really? So, all that foo.prototype.method stuff I see both in online-tutorial code and in the Snap! source is just a convention?

the foo.prototype pattern makes a quasi-class for "foos", that's all.

Yes, I know that. My question is whether this is something JS requires, or just something that everyone does because they're copying each other, or what. A "quasi-class" is what prototyping is supposed to avoid!

Hey you,don't argue :slight_smile:

Not arguing! Trying to learn something by asking questions.

ok :smiley:

I think the reason is that In JS you don't have object persistence in a project, as we have in Snap and as there is in Smalltalk. That means that in JS you don't really create a live system, but a system that in turn will create a live system. It's this one more step of indirectness that we're seeing in such constructs. So, when you make an object "foo" that's inheriting from "bar" you can just do that in JavaScript, too. But in oder to use the new keyword to create what we call clones in Snap! "foo" can't just be another object, but a function that creates another object whose prototype is going to be one specified for the function "foo". That's all.

Yeah, so it is a requirement of the language. That's a misfeature. In Object Logo, a JIT-compiled language, you can say KINDOF FOO or ONEOF FOO about any object foo. The difference is that when you say ONEOF, after creating the clone it sends it the message EXIST. By convention the EXIST method makes and initializes instance variables. You can give ONEOF an extra input that's passed on to EXIST, which by convention is an alist of names and values for instance variables. (So for example that's how you'd do the ID thing that everyone wants for clones.)

But the point is that all that is just a set of conventions. You can use ONEOF without writing an EXIST method, in which case it just inherits the one from the root object.