G'day all. Quoting Peter Simons <[EMAIL PROTECTED]>:
> >> Is there any reason why you would have a function in one > >> of your modules and _not_ export it? > > > Because that function is nobody else's business. > > I'm sorry, but that's not really a convincing technical > argument, that's essentially "because I want it so". Imagine, for a moment, just how much is involved in moving the cursor on your screen every time you move your mouse. Think about it. From the hardware in the mouse, to the CPU, the operating system, the windowing environment, the graphics card, the monitor... It's hugely complex. Probably more complex than most people, including experts, can take in all at once, and yet it fits on your desk or your lap. The reason why it all works is that everyone sticks to their interfaces and doesn't interfere in stuff that is not their business. The people who build the mouse don't worry about what is on the other end of the serial/PS2/USB port, they just work to the published protocol. The people who write the operating system don't concern themselves with semiconductor physics. The people who write the driver for the graphics card don't concern themselves with what's behind the system calls that they use. They do this because if they don't, computers become an unmanageable, fragile mess, and they know it. Private functions are not there just because the author hates you and doesn't want you to have any fun. It's because if you don't stick to the public interface, we all lose. Nobody wants their computers to fail unexpectedly, and if you've ever complained about it happening, then you of all people should want to avoid contributing to the problem. "But", I hear you object, "it's not like I'm building large applications for sale or widescale distribution; this is only for my personal research and/or amusement." This is perfectly reasonable, but as a library author, I still have to ask myself which group I should optimise for: the people who care about robustness and safety, or the people who don't. While Haskell has a wide potential audience, there are an awful lot of people who use declarative languages precisely because they _do_ care about robustness and safety. It's one of the major selling points. And I'm afraid that outweighs your desire to hack. Sorry. :-) > > So while I think you've identified a real problem (the > > modules that you want to use expose insufficient APIs), I > > think your solution is wrong. The right solution is to > > complain to the module writer, and ask them to export a > > functionally complete API. > So my solution is wrong and your solution is right. ;-) Yup. But it's not just my opinion. I have a lot of engineering experience (the overwhelming majority of it not mine personally) to back me up. > Having that out of the way, what are your reasons for this > opinion? (Other than that the "art of programming" says it > ought to be this way.) Perhaps rather than the "art of programming", you should be reading "The Mythical Man Month", or "The Psychology of Computer Programming". If you need to do something that badly, then it's worth doing it right. Doing it wrong is not engineering, it's hackery. And hackery almost always comes back to haunt you. (It's "almost always" because sometimes you've moved on and instead it come back to haunt the _next_ poor sod who has to maintain your code. "Almost always", the next poor sod is you.) Most engineers know this by bitter experience. To use XP language, "do the smallest thing that could possibly work" only works in conjunction with "aggressively refactor". > >> The only reason I could think of is that a function is > >> considered to be "internal" [...] > > > Right. And I agree with David: This is reason enough. > > How is an internal function any _more_ internal if you don't > export it? How is it less internal if you _do_ export it? If it's not exported, you can GUARANTEE that nobody outside your module is using it. So the cost of changing it is limited to only that which is inside the module. > Why doesn't the approach > > -- | /Attention:/ this function is internal and may change > -- at random without even so much as shrug. > > foo = ... > > suffice? Because someone will use it anyway, and complain when their code breaks. That someone will be on your team, and will hold up shipping YOUR product because if it, and you will be blamed. By the way: The goal of an engineer, according to Dilbert, is to get through their career without being blamed for a major failure. So modularise your code. :-) By the way: very often, a function changes in such a way that it doesn't change the type of the function. (It might change things which are encapsulated in a monad, for example.) So you might break their code, and they might not know about it. That's even worse. > > With my business hat on: Every time you expose something > > for use, you must at the very least document it. > > I'd recommend documenting _all_ functions I write, not just > the exported ones. There's developer documentation and there's user documentation. Developer documentation is what that you need to know to modify the internals. User documentation is what you need to know to use it from the outside. If you leak internal information to users, you increase the surface area of the module. > You mean "Foreign.Ptr"? Foreign.Ptr only really works on foreign data, and requires you to go to serious amounts of trouble to use it. Actually, if you could use private functions from modules by prefixing the call with yesIKnowThisIsntKosher, then I might be happier with it. > Why is that? My intuition would say that the exact opposite > is true: a more fine-grained set of modules is _less_ likely > to require recursive modules. But that's just intuition. Do > you have an concrete example which illustrates this point? I think Iavor is right. If you have data types which are only used privately in some module, then those data types don't appear the interface of that module. So while it might not introduce recursive modules, it does increase the size of the module interface, introduce dependencies which need not be there, and generally make your program more complicated than it needs to be. Cheers, Andrew Bromage _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe