I posted earlier (http://arclanguage.org/item?id=3202) about whether Arc needs modules. I learnt 2 things: 1. Always unit test your comments :) 2. I'm not very good at expressing myself in forums. So here's another crack at saying what I wanted to say... In 'Why Arc Isn't Especially Object Oriented' (http://paulgraham.com/noop.html) Paul Graham wrote: "If a language is itself an object-oriented program, it can be extended by users. Well, maybe. Or maybe you can do even better by offering the sub-concepts of object-oriented programming a la carte. Overloading, for example, is not intrinsically tied to classes. We'll see." I think a similar thing applies to modules. They solve a variety of different problems (hiding state, integrating code etc.) which might be best solved by individual, powerful abstractions. Of course, you can still combine these all together and call it a module system, but you could also combine them with other things and create something totally different, and that's the power of a la carte abstractions. For example, as I and a few others pointed out, you can use with to hide local definitions from the users of your 'module'. (with (local-def-1 [+ _ 1]
local-def-2 car:cdr)
(def public-def (x)
(local-def-2:local-def-1 x)))
But this has a problem: forward reference. (with (foo [bar _]
bar [+ 1 _])
(foo 5))
=> Error: "reference to undefined identifier: _bar"
Without forward reference, you can't have mutually recursive private functions. But that can be fixed by creating a macro that allows forward reference: (forward-with (foo [bar _]
bar [+ 1 _])
(foo 5))
=> 6
But look what just happened... I invented a new abstraction that could have all kinds of uses. As you can see, encapsulation is not intrinsically tied to modules any more than overloading is intrinsically tied to classes.By addressing one of the problems that modules are supposed to solve, instead of addressing the problem of creating modules, I've produced something of general use. That's the power of a la carte thinking. If we keep trying this, we may find out that we don't need modules at all. To quote PG again: "I personally have never needed object-oriented abstractions. Common Lisp has an enormously powerful object system and I've never used it once. I've done a lot of things (e.g. making hash tables full of closures) that would have required object-oriented techniques to do in wimpier languages, but I have never had to use CLOS. Maybe I'm just stupid, or have worked on some limited subset of applications. There is a danger in designing a language based on one's own experience of programming. But it seems more dangerous to put stuff in that you've never needed because it's thought to be a good idea." Replace 'object-oriented' with 'modules' and you'll see what I'm getting at. |