A programming language is low level when its programs require attention to the irrelevant.
Just last night I had a discussion with my wife about programming
languages. My wife loves C. Pure C, non of those other derivatives of
curly braces programming. She almost can't imagine why languages would
ever hide registers from the users, or why memory abstractions exist.
If a language doesn't let her do pointer arithmetic and control exactly
what goes where, how it goes there and how to interpret reading it,
it's almost useless. She likes it when it looks like thinly abstracted assembler.
Then again, she comes from programming real-time and embedded systems.
For her those are not low-level irrelevant details - those are the
absolutely necessary mechanics that are critical to achieving her
goals. Strings and string processing are not something she normally
handles, and when she does the byte array properties are more important.
For myself, having been clued in to Ruby in late 2003, I can now no longer even look at non-agile languages. It doesn't stop me from having a day job as an architect of a J2EE system, it's just that I can think
so much faster in Ruby about algorithms and data structure than in
Java. I then have to translate and explain those to the developers, but
the main leap is easy.
I constantly program open-source software for enjoyment's sake, but
between family and day job I only get a couple of hours to program in a
day (usually between midnight and 2am - I catch up every third night
:-). This level of abstraction, using Ruby and Rails (and unit-testing)
is the difference between maintainable and unmaintainbale commitments.