Yep, and multiple return types are like tuples, minus the ability to compose them and actually use them as a single type. Map and lists were generic, but a special kind the user couldn't make (fixed now I think w/ generics in 1.18). 'range' worked over a magic iterator, but not one you could ever make. Their "enums" are variable bindings minus the ability to be sum types or any other decent property of an enum. Nil is nothing more than "None" or "Empty" in an Option type, but since they didn't use the type system you can get a classic null pointer exception. Their "attributes" are just comments, but now you need to remember their special formatting since each one is effectively arbitrary text.
In so many instances, they made things "special" to avoid bringing in a concept, but you have to learn that concept anyway, but now as a special case. It is almost as if they said "we can have 5 features and I don't care what #6 does..it is out...we must make a language with 5 features!". Instead of saying: "What is a reasonable set of features that compose well, are logical, expressive, and relatively simple such that people can both easily learn and scale their code bases".
A great example is Brainfuck. Everyone would agree it is 'simple' and it only has 8 constructs, but it is not 'easy' to write programs in. 'simple' is not the right metric for a language.
In so many instances, they made things "special" to avoid bringing in a concept, but you have to learn that concept anyway, but now as a special case. It is almost as if they said "we can have 5 features and I don't care what #6 does..it is out...we must make a language with 5 features!". Instead of saying: "What is a reasonable set of features that compose well, are logical, expressive, and relatively simple such that people can both easily learn and scale their code bases".
A great example is Brainfuck. Everyone would agree it is 'simple' and it only has 8 constructs, but it is not 'easy' to write programs in. 'simple' is not the right metric for a language.