Encapsulation may be in the eye of the beholder

May 28, 2009

Here is an interesting question: is getloadavg() a more or less encapsulated way of getting the load average than (on Linux) reading /proc/loadavg? I wound up thinking about this in the aftermath of feeling rueful about discovering Python's interface to getloadavg(), and I don't think it's as simple as I made it out to be in my original entry.

For me, what it comes down to is different perspectives. An interface like getloadavg() is nicely encapsulated for someone who can easily use the C library; you get an interface that works on any system that supports it. But for someone using alternate languages like Python, Perl, or Ruby, a file as an interface is much more accessible than a something that's wrapped up in the C library, and thus the interface it provides is much more abstract and usable. You would much rather be able to get the information by just reading a file than have it only available if you can figure out how to call a new C library function.

(I would go so far as to say that a new interface that is only available by calling a C library function is not so much wrapped up in the C library as locked up in the C library.)

So: from the perspective of getting the load average on a lot of different Unixes in a C program, getloadavg() is more encapsulated. But from the perspective of getting the load average from a lot of different environments on a Linux system, I'd argue that /proc/loadavg may be more abstracted and encapsulated, since it's available to everything and you use it just the same way in all of the languages.

Comments on this page:

From at 2009-05-29 10:59:16:

That is the great benefit of C: it actually offers portability instead of the pseudo-portability of many interpreted languages often advertised as portable. (Yes, I am thinking of Java here.)

For the same reason I recommend that everyone should stay away from the /proc-interface. It is a ugly hack even in the Linux world.

Finally, it is a sad state of affairs that a portable program has started to refer to a program that runs both on Ubuntu and on Fedora (imagine that!). For us old-timers a portable program has to run both on Linux and on AIX as well as on x86 and on SPARC. Increasingly we are a minority and I believe this has started to show also in the quality of code (or the lack thereof).

By cks at 2009-05-30 02:24:28:

I disagree. I strongly believe that as many APIs as possible should be exposed in language-independent ways, and on Unix-like systems today that means that a /proc-like interface is the right way. Everyone can read and write files; not everyone can call specific language libraries.

(And with some work, reading and writing files can be a perfectly good and portable API too. It is just fashionable these days to cast APIs as library function calls, partly because we have better tools for writing APIs that way.)

From at 2009-05-30 05:17:43:

Few things.

The /proc-interface is a so-called Linux'ism and should therefore be left as such (if we ignore Plan9 as a research operating system). It is a start of an end for an interpreted language when its standard libraries tie themselves to such interfaces. Wasn't the raison d'etre of interpreted languages the exact opposite?

Perhaps I look things from a too different perspective, but I don't quite understand your comment about APIs and libraries. How again do you retrieve kernel data from userspace without using a system call (a "library")? How can you not call C functions when practically all interpreters are written in C? If this is impossible, shouldn't this be understood as a limitation of interpreted languages in the context of system programming instead of understanding the system as a limiting factor? Why interpreted languages should be used as system programming languages when they were not designed to be ones?

I have always had a big distaste of the /proc-interface and the usage of it in the Linux kernel. It has become a free dumpyard to which every imaginable interface and driver is free to export whatever is deemed as necessary. This critique is hardly unique among Linux kernel developers.

My critique had nothing to do with "reading and writing files". We have always had several ways to achieve this from the perspective of a kernel.

The irony is obviously visible in your comment about "reading and writing" kernel data from userspace. The /proc-interface has started to replace the older and much better structured sysctl-inteface (at least as a usage scenario where people change the kernel dynamically by "echoing" to some knob). Somehow also, for an example, good-old characteristic devices and ioctls are just not as "cool" as the /proc-interface, even though these would be much better suited for "language-independent" implementations.

Two cents and few more.

By cks at 2009-05-30 13:33:59:

Given an existing non-C language environment and a just-introduced C library call, the former often cannot use the latter without you doing considerable work (often work that steps outside the language, sometimes very far outside the language). In some cases it may even be impossible to do this, because the information you need to call the C library function is not exposed.

(Consider a new C function involving stdio in an environment where the language does not expose the FILE *'s it uses inside its own standard IO package. Not exposing them is even good programming practice.)

That the API to access information from a language is to 'open' 'files' does not mean that the language has to implement this API by making OS calls to open and read real files (and thus has to run on an OS where those files are available). We are conditioned to think of APIs as function calls and file access as file access, but this is not a state of affairs that is mandated by the universe.

I believe that Plan 9 demonstrates the power of using real files as a large part of your API, which is why I would like to see more of it. As for ioctls et al, they have serious problems that the Linux kernel people routinely discuss. In fact I believe that these days the Linux kernel people have basically stopped accepting new ioctls and ioctl based APIs, and now tell people to provide sysfs based interfaces.

Written on 28 May 2009.
« Hosted servers, cloud computing, and backups
The cost of program energy efficiency »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Thu May 28 01:20:01 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.