I tried Io during my undergraduate coursework. The language was my introduction to prototypical OOP. Compared to class-based OOP, I found prototypes conceptually simpler and my program architecture less rigid. They naturally lend themselves to an "organic" approach of modeling.
I later learned JavaScript and was extremely disappointed by its lackluster handling of prototypes. What's unfortunate is most programmers don't have experience with prototypes outside of JavaScript and I'm sorry to say its poor implementation of them has left a bad impression on the engineering mindshare. This ultimately culminated with ES6 introducing classes to replace what should have been the conceptually simpler and more flexible system.
Io is worth exploring, even if it's just out of curiosity. I'd especially recommend it to anyone whose only experience with prototypes is JavaScript.
Classes are just syntactic sugar on top of prototypes though. Were there categories of things you could easily express in Io that you could not express in JS?
Prototypical OOP and class-based OOP are both concepts, but it's the implementation of those concepts that distinguishes languages. Prototypes in Io are simply better implemented as a concept compared to JavaScript. Even something as minute as Io's "new slot" operator is a quality of life improvement. Then there are larger differences like multiple inheritance.
> Prototypes in Io are simply better implemented as a concept compared to JavaScript.
Of course it is: javascript is prototypal out of practical convenience, namely that whipping up a prototypal object system was much easier to implement over a few weeks than a full-blown class-based one. It was never a philosophical / design intention, and thus the prototypal object system:
1. was never really good in the first place
2. was never significantly improved for convenience, some inroads were made in ES5, then promptly ignored thereafter
JS developers never came from or were interested in prototypal inheritance and that's doubly understandable from javascript being their first introduction to it (even after the ES5 improvements, and accounting for proprietary extensions like `__proto__`, it remained garbage), few will be motivated into looking up a Self environment to try it out after that, odds are much higher they'll jigger a frankenclass system and try to forget about prototypes entirely.
Talking about Self, and Io, and prototypes, having never really used either in anger I was surprised (and a bit dismayed) that Io's prototypes are a list thereof, that seems so much less sensible and pretty and flexible than Self's parent slots it just killed any interest I had in Io immediately.
And Io makes the same vocabulary mistake Javascript does (to the extent that I always assumed Io grew from an exploration of Javascript leaning more on prototypes, rather than growing from the original): while Self's OO is called prototypes-based, prototypes do not actually have much relevance to the runtime system: a prototype is the object you clone (shallowly), the objects you link to (via parent slots) are called / classified as mixins or traits depending whether they themselves have parents[0].
That is, Self's `copy` on clonables (as opposed to oddballs) is equivalent to Javascript's `Object.assign`, not `Object.create`, or IO's `clone` (an other name I find awful since it doesn't clone anything).
I later learned JavaScript and was extremely disappointed by its lackluster handling of prototypes. What's unfortunate is most programmers don't have experience with prototypes outside of JavaScript and I'm sorry to say its poor implementation of them has left a bad impression on the engineering mindshare. This ultimately culminated with ES6 introducing classes to replace what should have been the conceptually simpler and more flexible system.
Io is worth exploring, even if it's just out of curiosity. I'd especially recommend it to anyone whose only experience with prototypes is JavaScript.