Well, clearly Whitney has been hugely successful with his odd little language.
There's the case for a kind of extreme pragmatism — writing code that does the one thing it needs to do, without particular concerns for things like abstraction.
We all write one-off scripts that are short and precise, but for a myriad of reasons won't scale to anything bigger or more general: we cheat and use global variables; we target one specific use case but don't allow parametization/configuration to support others; we target one OS and a certain constellation of dependencies; and so on.
What Whitney has accomplished, I suspect, is that he has found a way to reduce the problem surface by going for extreme simplicity in absolutely all areas of his system, which is by making certain assumptions. Everything is lists or simple data types, there are no abstractions (by which I mean things like interfaces, generics, abstract data types, even custom types), almost everything is in-memory.
You can do this with a Lisp or a Scheme, too. But the temptation is always to reach out for abstractions and patterns and build complicated systems out of subsystems. A database would have a cache manager, a page manager, a planner, an index manager, an SQL parser, a transaction log manager, etc. etc.
K shows that you don't need go for this clean, compartmentalized, layered subsystem approach if the whole program is small enough to make it easy to see the whole system on the screen. You can use global variables because it doesn't violate any layering. You don't abstract things like indexes and operators into abstract internal APIs because you know at any point what they are.
An example of this kind of extremist simplification is how kdb+ stores tables: It memory-maps the entire table file and treats it as an in-memory list. Instead of having to invent a paging mechanism and create functions that work on tuples in pages, they can simply reuse all the vector-oriented K operators, which work on the tuples exactly the way they work on other in-memory lists.
I don't think I could write K, but it is certainly a source of inspiration when designing systems. We developers have a tendency to pattern-match and generalize, when often "ad hoc" techniques would be better. The old adage is "make everything as simple as possible, but not simpler", but it's actually possible to make things simpler.
I don't understand your last sentence. Things can be made simpler than possible?
If you focus just on inner loops, this kind of simplicity is widespread and essential for performance. APL and its derivates are great specification languages for array manipulation.
If you are writing a networked window system, on the other hand, a "high ceremony" language is more appropriate because you need to cope with protocols and abstractions. Right?
My point is that it's wise to challenge assumptions about what "simple" means. Self-imposed constraints often yield more novel, more optimized solutions than when you have all the freedom in the world. Maybe flat files interacted with via fopen() works better; maybe we just don't need our layers to accrete until we have AbstractSingletonProxyFactoryBean.
A networked window system — perhaps not the best example. With that one I think the assumptions are flawed (ie., that you can make one without introducing painful leaky abstractions) to begin with. ;-)
Well, in terms of whether the example is a well-posed question, a networked window system isn't too different from the WWW, which as we know by now works pretty flawlessly.
Perhaps the key contrast here is between the tendency toward static mathematical perfection of the APL family and the notion of dynamic languages for building systems that Alan Kay et al would propose.
"APL is like a beautiful diamond - flawless, beautifully symmetrical. But you can’t add anything to it. If you try to glue on another diamond, you don’t get a bigger diamond."
--Joel Moses
There's a talk by Ian Piumarta that tries to get to the core of what the VPRI guys feel is important. I'm not sure about it but it seems worth mentioning in this context:
Ian Piumarta "Building Your Own Dynamic Language"
http://www.youtube.com/watch?v=cn7kTPbW6QQ
There's the case for a kind of extreme pragmatism — writing code that does the one thing it needs to do, without particular concerns for things like abstraction.
We all write one-off scripts that are short and precise, but for a myriad of reasons won't scale to anything bigger or more general: we cheat and use global variables; we target one specific use case but don't allow parametization/configuration to support others; we target one OS and a certain constellation of dependencies; and so on.
What Whitney has accomplished, I suspect, is that he has found a way to reduce the problem surface by going for extreme simplicity in absolutely all areas of his system, which is by making certain assumptions. Everything is lists or simple data types, there are no abstractions (by which I mean things like interfaces, generics, abstract data types, even custom types), almost everything is in-memory.
You can do this with a Lisp or a Scheme, too. But the temptation is always to reach out for abstractions and patterns and build complicated systems out of subsystems. A database would have a cache manager, a page manager, a planner, an index manager, an SQL parser, a transaction log manager, etc. etc.
K shows that you don't need go for this clean, compartmentalized, layered subsystem approach if the whole program is small enough to make it easy to see the whole system on the screen. You can use global variables because it doesn't violate any layering. You don't abstract things like indexes and operators into abstract internal APIs because you know at any point what they are.
An example of this kind of extremist simplification is how kdb+ stores tables: It memory-maps the entire table file and treats it as an in-memory list. Instead of having to invent a paging mechanism and create functions that work on tuples in pages, they can simply reuse all the vector-oriented K operators, which work on the tuples exactly the way they work on other in-memory lists.
I don't think I could write K, but it is certainly a source of inspiration when designing systems. We developers have a tendency to pattern-match and generalize, when often "ad hoc" techniques would be better. The old adage is "make everything as simple as possible, but not simpler", but it's actually possible to make things simpler.