Fixing Linux, Part One: “The Space Between”

I’ve been thinking about how to best improve the Linux* userland over the last few days. I was venting pretty loudly about my Linux gripe of the day–I don’t even remember what I was complaining about at the time, but it was a mess of shell scripting, pipes, and about half a dozen command line programs that were conspiring to drive me up the wall. Before I could get into a really quality rant, the kind that would peel paint off the walls, the friend who I was giving an earful to asked me a question, probably to shut me up.

“So what would you do to fix it?”

That’s not exactly a new question, but I hadn’t been asked it before. So I put a little thought into it. My first instinct was to look toward the kernel, but that was pretty stupid of me–the kernel no doubt has problems, but I’m not a kernel hacker and I’m not qualified to talk about them. The area where I routinely run into problems and annoyances is userspace, so why not look at that?

I ended up on what I’m starting to think might be the biggest problem with Linux today: what I’m calling “the space between.” This has three different meanings related to different issues I’ve seen and had with Linux. (I could come up with more tortured uses of “the space between,” but then I’d run the risk of sounding like a certain balding South African musician.) Also–I’m not claiming to be coming up with anything new, so don’t ascribe some kind of weird arrogance to me for it. I’m just putting things how I see it. It’s my blog, dammit, I can do that.

.

.

The first issue is nothing really new to anyone: the space between usage paradigms–the space between the GUI and CLI. The prevalent mindset among open-source developers seems to be “I’m only going to cater to my own style of usage.” Some developers only use the command line, and so their tools are all command-line; if there’s a GUI at all, it’s a thin wrapper over the command line application. Other developers (me, sad to say, though I try not to do this) prefer GUI tools, and so there’s not a lot in the way of command line access for those programs. Most programers will agree, if you ask them, that applications should be divided into a library with different interfaces as necessary–GUI, CLI, web, toaster, whatever. Whether these programmers actually do it…well, that’s a little more sketchy. Mind you, I’m not saying that programmers have an obligation to write a full-featured GUI for people who don’t like using the command line. They just need to make it reasonably possible by extracting the code into libraries that can be easily consumed.

.

.

The next issue is something that might be a little touchy: the space between languages. And sometimes, there’s a lot of space between languages. Say you’re writing an application in…let’s pick any ol’ pet language. Ruby. You’re writing your app in Ruby, and you need to accomplish X. No doubt there’s a libDoesX somewhere–no? No libDoesX? Crap. Welp, surely somebody else is going to use this code–you’d better make a library out of it. And a name–how’s libRubyDoesX sound? Cool, so now you’re peddling your library to accomplish X. In Ruby.

So you’ve written the application, and the handy library, in Ruby. Now I come along, waving my pet language, Python (anybody who knows me will now indulge in some uncontrollable laughter), and I need function X. Surely somebody’s written a libDoesX, so I’m gonna go find it! And there it is.

Your libRubyDoesX.

In Ruby.

Uggggggh.

I guess I’d better get to making libPyDoesX. Or figuring out some way to host Ruby within my Python application just to use your libRubyDoesX.

See the issue? Countless man-hours are wasted, doing the same thing over and over again. Some duplication is good–new features might crawl out of the woodwork. Lots of duplication? Not so good. That time could be spent doing what you originally wanted to do, rather than screwing around with writing yet another libDoesX. You didn’t want to write libRubyDoesX! You just wanted to accomplish X, but there was nothing out there for it. I didn’t want to write libPyDoesX, either, I just wanted to accomplish X, too. But since libRubyDoesX is the only game in town, I had to duplicate your work in order to do so.

There’s also the other common path for libraries to go, equally wastefully. Somebody writes the library in a relatively consumable language, like C. Then, as people need to use it, bindings pop up for it–Ruby bindings, Python bindings, Perl bindings, whatever. As “language purity” starts to take hold (and most of the time, at some point or another, it does), for some reason it becomes important not to depend on that C library anymore, and it’s time to reimplement that C library in Ruby, in Python, in Perl. C’mon, let me hear you now: “uggggggggh.”

.

.

The third “space between” is the space between programs. This relates somewhat to the first point, the space between usage paradigms, but is a bit different.

What has always been “the UNIX way” is to have a lot of little programs that can be piped together in all sorts of interesting and different ways in order to accomplish a task. That’s fine. That’s great. I’m not saying that that should go away for people who want to operate in that fashion. It’s not my bag to go whipping around sed and awk while hoping I don’t put my eye out or change Planck’s constant, but if that’s your M.O., more power to you. The problem I see with the UNIX way is that the lingua franca is absolutely horrible. Text, especially text that should be readable to humans as well, is, in my opinion, a bad way for two programs to talk to each other***. It’s hackish and while you can do some cool things with it, you can also shoot off your foot. We could have an easier way, something that doesn’t require you to jabber at sed and hope you didn’t miss a slash or something equally inane.

.

.

The question then becomes “what do you do about these issues?”, and it’s a loaded question. I mean, it’s not like you’re going to get people to all start hacking away in your One True Language of Choice, and I’m not sure you’d want people to anyway. You’re also not going to really get a developer hacking away at command-line apps to break their important functionality out into a library if it doesn’t benefit them (and somebody could go crazy doing it for them!). And you certainly don’t want to offend the people who like playing the aforementioned shell scripting games; I’m convinced they know magic and I don’t want to be turned into a toad. Not me, no way.

In my next Fixing Linux post, I plan to explore what I think is a good way**** to address these issues moving forward. Hope to see you back here for it.

I’d love to know what you think about this article; please feel free to comment.

.ff

.

.

Check out the second part of my jabbering about this topic over here.

* - I don’t intend to exclude BSD with these comments herein. I just get annoyed by saying “Linux and BSD” every time and I don’t like typing *nix all the time.

** - You there in the back, shut up–I know about Masaki Fukushima’s old Ruby/Python extension library. To the best of my knowledge, it’s old and unmaintained. His website, which is the first hit for the topic, says it was updated in September of 2000.

*** - I’ve made similar comments about SOAP in the past, but I can’t think of a better method for communicating between services on different hosts.

**** - False modesty alert. Yeah, I said “a good way”. I’d be a grandstanding asshole if I said “the best way,” wouldn’t I?

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]
This entry was posted in Open Source and tagged , , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

27 Comments

  1. Narbonne
    Posted August 5, 2008 at 3:32 am | Permalink

    Good remarks but unixians and administrators like bash scripting power so, i think we need both GUI and CLI for tools that could be interesant to use in script as sed, awk, ex, aptitude, rm, touch, grep…. yes we don’t need a comand line version of Firefox or monodevelop but many tools as open office could be a way to store or publish automaticaly data…

    so it should be improved.

    an other way to improve compatibility between languages should be a common standart API rules set that should be as easy to implement than to learn a comand-line tool…

  2. Posted August 5, 2008 at 8:48 am | Permalink

    Much of the “the space between language” is solved by using a managed environment like .NET. What you describe is very much the old bindings-hell. Mono (.NET) solves this. One binding and I can use the library/code in question from C#, Python, PHP, or any other language for which there is a managed implementation.

    As for “the space between usage paradigm” have you used Power Shell? While the product is closed source the concept and usage in unparalleled beauty. Applications can simply provide commandlets and you can easily do the same things you can in shell scripts (or other scripts) without all the shell-ish madness since it is OO - you can loop over files without worrying about spaces in the filenames, etc… since you are iterating File objects instead of file names, etc…

  3. Ed
    Posted August 5, 2008 at 9:54 am | Permalink

    Narbonne:

    I don’t disagree at all with regards to the shell being valuable for some users. I specifically said that (mostly because, like I said, you never want to piss off the shell wizards, they’ll turn you into a toad).

    Managed code (which will be the subject of the next article) is a pretty good way to bridge the gap between the two. Somebody writes a GUI-only program? Reference the assemblies, yank out their object model, and you’re off to the races. The same goes for the other way ’round–if you want to avail yourself of somebody’s CLI application, just reference it and wrap around its object model. (This necessitates that people write code in a cleaner, more object-oriented fashion, but I don’t see that being a terrible thing if everybody’s buying into it.)

    Adam:

    A managed code environment is indeed one answer to the questions I pose, and (to my mind) a good one. The only problem is grinding out the necessary code to make it work. You stole my thunder! ;)

    I haven’t used PowerShell much, but it’s a model similar to what I’m going to suggest. I’m not an open-source zealot; I have no problems with closed-source code and PowerShell seems to be on the right track. A similar model would benefit open source, although with the flexibility of open source I could see an expansion on this method coming into play pretty quickly.

  4. Tak
    Posted August 5, 2008 at 11:17 am | Permalink

    Vala[1] is another good bridge for the space between languages. It provides many of the benefits of a managed language (automatic garbage collection, simplicity of programming, ease of binding (due to gobject backend)) along with many of the benefits of C (no virtual machine, bindable from /any/ language (not just ones blessed for the current vm), portable to any hardware with a C compiler).

    1. http://live.gnome.org/Vala

  5. Ed
    Posted August 5, 2008 at 11:56 am | Permalink

    Tak:

    I don’t agree about Vala being a good bridge. It has a few pluses–automatic garbage collection is always a plus, and personally I’m a fan of C#-ish syntax–but being tied to GObject is really not an awesome thing IMO, and is something of a deal-breaker. I’m not a GTK+ fan in the least (Qt for me, thank you). I’d be uncomfortable requiring CLI applications to depend on anything for GTK or Qt.

    WRT “blessed for the current vm”–that’s a bit of a loaded phrase, don’t you think? As far as I know, there’s nothing stopping any specific language from being used on, say, Mono 1.9.x; I can’t think of any CLR languages that don’t work on it except for the newest beta of IronPython (and a beta not working on a beta doesn’t really bother me all that much).

    The portability aspect, however, is an argument that kind of misses my target here (which is targeting the underpinnings of a Linux desktop more than anything, I’m not a server dude). x86, x86_64, and PowerPC all have Mono and Java, so I don’t really see a big win here for Vala, though I might be missing something.

  6. Jacob Kroon
    Posted August 5, 2008 at 12:08 pm | Permalink

    Being a user of GObject is not the same as being a user of GTK+. GTK+ is stacked on _top_ of GObject. There is no dependency the other way. Vala is itself a CLI program, and is using GObject (heavily).

  7. Ed
    Posted August 5, 2008 at 12:14 pm | Permalink

    Ahh, I misunderstood, my apologies. (I’ve never used GNOME long enough to end up poking around their software stack.)

    Vala still doesn’t seem to address what I consider a fairly fundamental point, though I may just be missing something–it’s yet another language that, while it preprocesses to C, is still mutually incompatible with a lot of other languages in which programmers may sling code. (The compatibility is one-way, that is–a Python programmer could consume Vala code, but the reverse is not so clear-cut, if doable at all.) In a managed environment, the disparate languages all target the same underlying framework.

    Perhaps I’m still misunderstanding you, but unless you’re advocating that everybody work in languages that preprocess down to C, I’m not seeing how this really helps bridge the gap between languages. It seems more like an extension of the status quo.

  8. Jacob Kroon
    Posted August 5, 2008 at 12:55 pm | Permalink

    Yeah, I see your point. I guess Vala is a viable option for a _standalone_ library, or a library depending on other C/Vala libraries. Still not too bad, but a platform like Java or .NET still has its uses I agree.

  9. Ed
    Posted August 5, 2008 at 2:21 pm | Permalink

    As native libraries go, C libraries are obviously the A++ best choice for compatibility (and I guess if you’re OK with tying to GObject, Vala too). They’re the libraries that can talk to *anyone*. My beef is that we’re getting away from that into other, specific languages, which can’t readily talk to each other.

    My next post on this topic should be done this evening, and it’ll be a treatment of the possibility of a managed-code userspace (which obviously depends on the low-level libraries to effect functionality; that goes without saying). It’s a pretty gigantic suggestion that I’m going to be making, and one I don’t really expect anyone to take seriously–heck, I’m not sure whether *I* take them seriously, though I think it’s a good idea.

    Anyway, take a gander back this evening and there should be a post up.

  10. jg
    Posted August 5, 2008 at 9:31 pm | Permalink

    DBus was supposed to address the issue of programs being able to have advanced control over, and communication with, each other, as well as exchange data. It should have made obsolete the tradition of communication via “piping the text input/output of programs via the command line”.

    But like too, too many free software projects, all the time was spent on coding (and usually writing code scant of comments, so it’s really, really difficult to glean what the code does and how it works), rather than documentation/tutorials. So very few people ended up using it because they just didn’t know how to do so without good docs and tutorials. Surprise, surprise! When are open source programmers going to learn that, if you aren’t going to document your code in an explicit and clear manner, then you may as well not even release it publically, because very, very few people are going to use it. You’ll get more usage if you pare your feature list way down, and instead spend more time writing docs/tutorials. THAT’S how Microsoft got all that 3rd party developer support for their equivalents to things like DBus (ie COM and ActiveX) — because MS (0r the Windows development community) releases lots of docs, examples, and well-commented example source. Linux is in desperate need of good doc and tutorial authors. If you want to make a difference, start there. Hell, start with DBus. If you can explain it well to developers (other than the ones who created it), maybe they’ll start using it more, and that will make your work infinitely easier when they do.

  11. Ed
    Posted August 5, 2008 at 9:37 pm | Permalink

    jg:

    *I* don’t understand DBus. And I’ve tried.

    In any case, that’s not quite what I’m driving at. I’m not talking about inter-process communication, I’m talking about inter-program communication, the sort of thing that’s usually handled by “oh, go shell FooBar -lxqrz 42 and catch the output.”

  12. Tak
    Posted August 6, 2008 at 10:18 am | Permalink

    In “blessed for the current vm”, I wasn’t differentiating between .NET and Mono, but rather CLR and JVM (and whatever the next one will be).

    As far as portability goes, if you only care about x86 and x86-64, then you’re fine with Java or Mono. However, desktop-type software is being run on more architectures (ARM, Blackfin), and a C baseline is an advantage in those circumstances.

  13. Posted August 6, 2008 at 12:47 pm | Permalink

    BTW, there is an Open Source PowerShell-work-alike. It is “Pash” over on SourceForge. Unfortunately development seems to have petered out in mid-July before they shipped a can-build-with-Mono version; very sad.

  14. jg
    Posted August 6, 2008 at 10:12 pm | Permalink

    >I’m not talking about inter-process communication, I’m
    >talking about inter-program communication

    Um, you can’t have inter-program communication (without piping the text input/output of programs via the command line) without first having inter-process communication. *IF* the Dbus folks had ever documented their work, and provided clear tutorials/examples, so that others could easily implement it in their programs, then adding user scripting on top of that would be as easy as it was for Microsoft to create VBscript and Jscript, just as soon as most windows software provided a COM (ie, ActiveX object) interface. (And frankly, MS was uncharacteristically unforthcoming with ActiveX scripting docs. Even so, they eventually released enough adequate docs/examples so that, within about 2 years, most major apps supported ActiveX scripting). And of course, the Windows’ version of Python also has the ability to interface with any programs’ ActiveX interace, thanks to that documentation/tutorials/examples. Want to control Works from your python program? Just create an instance of its ActiveX object, and start calling its functions. Easy. Want to exchange Works data with Excel? Then create an instance of Excel’s ActiveX object too, and your python scripts goes to town calling functions in both objects to do what you want to do with those 2 apps.

    It would have already happened by now in Linux if the documentation and tutorials had been done. Your python script would just create an instance of some program’s “DBus object” (or whatever the DBus scripting component would call it), and start calling its functions to control the program, and exchange data with it. It wouldn’t matter whether the program was GUI-based, or command line. (You wouldn’t need to know). And it wouldn’t matter what language the program was written in. There’s your “managed environment”.

    Did you know that a Python script can actually call a function written in another language, such as Java or Ruby, passing data to it, and getting back its value? Yep. All it takes is for both your Python interpreter to support ActiveX and also the other language’s interpreter to do the same. That’s how your can embed both Jscript and VBscript code in the same object tags on a web page, and have a Jscript function call a VBscript function or vice versa.

    Could be happening in Linux… if developers had actually documented their stuff, and spent some time writing good tutorials/examples rather than adding more features to software that is already underutilized due to poor docs/tutorials/examples. And then after a few years of no one using his stuff, the open source developer gets discouraged, abandons it, and moves on to fork some other abandoned project, repeating the same mistake of not taking the time to document it.

    The reason Linux doesn’t have this is because no one can build a scripting implementation upon inter-process communications like Dbus for two reasons:

    1) The docs/tutorials for the inter-process communication frameworks like DBus are so awful/inadequate, that the overwhelming number of programmers don’t know how to implement it in their software.

    2) There’s nothing useful you can do with a scripting implementation if it isn’t using some inter-process communication also used by lots of programs. ie, If virtually no apps have a DBus interface, what good is it to have a scripting implementation that works via DBus?

    And even if, magically, all known Linux software were to suddenly have some sort of DBus interface via the wave of a magic wand, the guy who writes the scripting interface now needs to utilize DBus too, and he ain’t gonna do it easily given the horrible state of Dbus documentation.

    It’s all down to inadequate/poor documentation, tutorials, and examples for Linux open source alternatives. People are coding the stuff (without even commenting their code adequately), and then tossing it out there without letting others know how it works or what it can do. Thud. That’s the sound of something falling flat on its face, and not being a viable alternative as a result. What’s the point of having access to source code if you don’t know what it does, how it works, and how to use it? That’s a rhetorical question. The answer is: There’s no point at all, and even if such software could potentially address the problems you have, it isn’t doing so now, and very likely will never do so.

    Hammer it into every open source developer’s mind that his software is only as good/useful as his docs/tutorials/examples, and things will start to improve. And not until then.

  15. Ed
    Posted August 6, 2008 at 10:33 pm | Permalink

    > Um, you can’t have inter-program communication (without piping
    > the text input/output of programs via the command line) without
    > first having inter-process communication.

    I think you and I are talking at cross purposes here. I don’t disagree with anything you’re saying, I’m talking about not wanting to have to talk to another process at all. I don’t *want* inter-program communication*; I want to be able to consume another application *within* mine and avail myself of its functionality. The “Unix way” is, in my opinion, inferior to just incorporating the library that encapsulates the functionality of $some_tool and using directly. As the second post mentions, I’m in favor of a managed code solution because it opens up the vast majority of that code for anybody’s use regardless of language, so long as you target the CLR.

    * EDIT: I should say that I don’t want inter-program communication for the low-level stuff. IMO, it’s conceptually easier to use these as objects. Of course inter-process communication, a la DBus, is important.

  16. jg
    Posted August 6, 2008 at 10:49 pm | Permalink

    >I want to be able to consume another application *within* mine and
    >avail myself of its functionality.

    That’s what ActiveX scripting does! For example, it lets your Python program totally control every aspect of some other program, from starting it up, to closing it down, to doing anything with it that its ActiveX scripting object exposes. It also lets you call functions in any ActiveX shared library, regardless of what language the lib was written in. And it even lets you call functions written in any interpreted language (ie, a Python script calling that Ruby code) provided the interpreter supports ActiveX (and most all Windows script engines do today).

    I’m beginning to think that you’ve never used ActiveX scripting. You owe to yourself to do so, so that you can see how something like this is exactly what you’re saying you need.

    Think of ActiveX as a way to allow a program written in any language (ie, Python, Ruby, Perl, C, etc) to treat any other program (written in any language, such as Python, Ruby, Perl, C, etc) as if it’s a shared lib whose API is callable by that first program. It’s that “managed code environment” that you’re lusting after.

    If you want more technical info about ActiveX scripting, I wrote an entire series of articles over at Code Project:

    http://www.codeproject.com/KB/COM/com_in_c1.aspx
    http://www.codeproject.com/KB/COM/com_in_c2.aspx
    http://www.codeproject.com/KB/COM/com_in_c3.aspx
    http://www.codeproject.com/KB/COM/com_in_c4.aspx
    http://www.codeproject.com/KB/COM/com_in_c5.aspx
    http://www.codeproject.com/KB/COM/com_in_c6.aspx
    http://www.codeproject.com/KB/COM/com_in_c7.aspx
    http://www.codeproject.com/KB/COM/com_in_c8.aspx

    But that doesn’t address the problem of: How and where do we get info like the above, about Linux alternatives, so that they can be used as much and as effectively, as ActiveX scripting is used on Windows? Hmmmm?

  17. Ed
    Posted August 7, 2008 at 12:00 am | Permalink

    > That’s what ActiveX scripting does! For example, it lets your Python
    > program totally control every aspect of some other program, from starting it
    > up, to closing it down, to doing anything with it that its ActiveX scripting
    > object exposes. It also lets you call functions in any ActiveX shared library,
    > regardless of what language the lib was written in. And it even lets you call
    > functions written in any interpreted language (ie, a Python script calling
    > that Ruby code) provided the interpreter supports ActiveX (and most all
    > Windows script engines do today).

    Yes, I realize that; I used to use Visual Basic 6, I damn well better know what ActiveX is–I was thinking of ActiveX in that sense, using it as a user control wrapper. I forgot about the other capabilities. My bad.

    I see more clearly what you mean now, though, and, yeah, your suggestion would work. However, it’s *not* a managed code userland. A managed code userland would be based on a bytecode language, like the JVM or Mono’s CLR. A managed code userland offers not just the ability for you to use *functions* from other programs (written in other languages or not), but entire objects. If I write a class Foo in C#, the next guy writing PHP on Mono can just reference my code assembly and consume the *object*, not the program. You just import their public object model in its entirety and manipulate it. And nobody has to do anything to enable it for the end user (though writing the managed code userland is certainly a nontrivial task).

    The benefits of your userland being primarily managed are pretty impressive. In the other post, somebody brought up one I didn’t even think of: versioning. Third party, closed-source developers have it easier: the Global Assembly Cache is versioning-capable, which is *huge* for these developers–if version 1.1.0.6 of libFoo sticks around in the Global Assembly Cache even after you upgrade to 1.2.0.4, you no longer have to fear breaking API changes. Whereas with an ActiveX-alike, you don’t get this sort of benefit.

    I see your point, and I won’t deny that an ActiveX-type of communication model would benefit Linux’s native code apps–but I think that’s approaching things the wrong way, and we need to be moving *away* from that native code.

    As far as education: that’s the other nice thing about managed code. It’s natural to be referencing other people’s managed code assemblies. Everybody uses it. You don’t have to educate them about it because it’s the same workflow they use for *any* libraries.

  18. jg
    Posted August 7, 2008 at 12:58 am | Permalink

    >A managed code userland offers not just the ability for you to use >*functions* from other programs (written in other languages or not), but >entire objects.

    But an ActiveX object *is* treated like an object in an object-oriented language. Take this bit of VBscript for example:

    Set objConnection = CreateObject(”ADODB.Connection”)
    objConnection.Provider = “ADsDSOObject”
    objConnection.Open “Active Directory Provider”

    You’re not setting a variable named objConnection.Provider. You’re setting the Provider member of an instance (ie, object) of the “ADODB.Connection” class. And you’re not just calling a function named Open. You’re calling the Open method in the same object. That first line has actually created/imported an entire object into your VBscript program. (And incidentally, that object is written in C++). You have done exactly what you want to do (and for some reason assume that you can’t do with ActiveX).

    And you can do the same with Python. It takes one line of code to create/import an entire ActiveX object (written in any language) into your program, and from there you treat it just like any other object. You access its data members the same way, and call its functions the same way.

    Same thing with any other object oriented language using ActiveX.

    Dbus was supposed to make all this possible. The reason it hasn’t is because no one knows how to use it, and so its potential remains completely untapped for such use.

    That was my point all along.

    All managed code gives you is some automatic garbage collection. But your problem isn’t memory leaks. Your problem is that you want the kind of control and flexibility you get by being able to interface to some program as if it had a directly accessible API, wrapped in your own language’s object-oriented implementation. Well, that’s the whole idea behind ActiveX. Essentially .NET is just some automatic garbage collection added to ActiveX, plus the requirement that all interpreted languages include a “compiler” that produces one of these “byte code” things. (ie, Essentially a platform neutral sort of assembly code). But again, your issue isn’t speed either, so you don’t care about the byte code thing either. Your issue is that you need simply what ActiveX gives you… and you need it on Linux. Well… there’s DBus. But how do you use it? And do more than a handful of people actually use it in their software? There’s the REAL problem.

  19. jg
    Posted August 7, 2008 at 1:00 am | Permalink

    Correction:

    plus the requirement that all interpreted languages include a “compiler”

    Should read:

    plus the requirement that all supported languages include a “compiler”

  20. Ed
    Posted August 7, 2008 at 1:04 am | Permalink

    Interesting. However, unless there’s some deep magic involved here that I’m not seeing, instantiating objects in this way kills type safety, doesn’t it? (That alone would be a reason to stay away from it.)

    Can you use reflection with ActiveX components? How would you do this with an equivalent Linux system?

    Can you use extension methods with the objects from a library you’re using via ActiveX? How would you do this with an equivalent Linux system?

    Can you inherit from an object from a library you’re using via ActiveX? How would you do this with an equivalent Linux system?

    Can ActiveX components throw exceptions to any program consuming them? (That’d be a trick, seeing as how at least one language ActiveX is used with doesn’t even support exceptions.) How would you do this with an equivalent Linux system?

    Can you package metadata with ActiveX controls in order to facilitate development (IntelliSense parsing, for example)? How would you do this with an equivalent Linux system without requiring massive rework on the part of the library programmer anyway (whereas we can just wrap the library with managed bindings and the native code library programmer doesn’t have to do anything)?

    Managed code allows a *tight* interoperability between various assemblies–”tight” in the sense of “I can actually do stuff with this” beyond just “I can use it.” Does ActiveX?

    I’ve been reading a bit about ActiveX tonight, and I’m not impressed. ActiveX was nice, I guess, when there was no better, though you’re the first person I’ve ever heard speak of it in any sort of positive way and frankly I’m mystified as to why. ActiveX is a technology that even Microsoft is moving away from–in favor of managed code–and you aren’t discussing any plusses that managed code doesn’t easily surpass.

  21. jg
    Posted August 7, 2008 at 1:55 am | Permalink

    > instantiating objects in this way kills type safety, doesn’t it?

    No. All ActiveX objects that can be used from an interpreted language such as VBscript, Python, Perl, etc, must include something called a “type library”. The script engine accesses this type library (and I won’t get into the details of how that’s done — you can read about that in my series of articles) to find out how many arguments are passed to a particular function, what are the datatypes of each of those args (and ActiveX objects must be written to support only “automation compatible datatypes” — essentially only types that are supported by all languages — no pointers or handles or “structs” or stuff like that), and whether the function returns a value, and what that return’s datatype is.

    For an object’s data member, it can check what the datatype of that member is.

    The type library can even tell someone the names of all functions and data members in the object, so your program can determine at run time what is available in a given object.

    Let me give you a breakdown of what communication happens between the Vbscript engine running those 3 lines above, and the operating system and ActiveX object. There’s a LOT going on behind the scenes because, after all, ActiveX scripting is designed to do all those things that you’re saying you’d like to have (and that’s a lot).

    Set objConnection = CreateObject(”ADODB.Connection”)

    VB engine: “Operating system? Do you have an ActiveX object registered under the name “ADODB.Connection” installed on this computer?

    The operating system answers “Yes” or “No”. If no, then the VB engine raises an error on that first line, informing the user there’s no such ActiveX object installed on the computer. If “Yes”, things proceed as so:

    VB: “Operating system, please load this ActiveX object. Whether it’s an EXE or DLL, or some script written in another language, I don’t care. Just load it and give me a pointer to the standardized interface that all ActiveX objects implement. If it’s an interpreted language, run its interpreter and tell it to give me that standardized ActiveX object, assuming its interpreter supports ActiveX. And you know whether it does because Windows has a standardized installation API, that includes the ability for a script engine to notify the OS that it supports ActiveX”.

    OS: “Done. Here’s your pointer.” (Of course, there could be a problem doing this, in which case, that is reported to the VB engine, instead of “Done”).

    VB: “Ok, I’m storing this pointer and associating it with the VB variable named objConnection. From now on, the script can reference it just like any other VB object, and I’ll do all the work of communicating with this ActiveX object.”

    Now, the VB engine executes the second line:

    objConnection.Provider = “ADsDSOObject”

    VB: “ActiveX object, do you have a data member named Provider?”

    The ActiveX object answers yes or no. If no, VB raises an error. If yes, things proceed:

    VB: “ActiveX object, this VB code wants to set the value to a string. Does this member variable store a string?”

    The ActiveX object answers yes or no. If no, VB raises an error. If yes, things proceed:

    VB: “ActiveX object, set the value of your Provider data member to the string ‘ADsDSOObject’”.

    ActiveX: “Done”. (Of course, there could be a problem doing this, in which case, that is reported to the VB engine, instead of “Done”).

    Now we get to the third VB line.

    objConnection.Open “Active Directory Provider”

    VB: “ActiveX object, do you have a function named Open?”

    The ActiveX object answers yes or no. If no, VB raises an error. If yes, things proceed:

    VB: “ActiveX object, this VB code wants to pass one argument — a string. Does your Open function take one arg, with a string datatype?”

    The ActiveX object answers yes or no. If no, VB raises an error. If yes, things proceed:

    VB: “ActiveX object, call your Open function passing it one string arg of “Active Directory Provider”. I’ll wait until you’re done executing your Open function, in whatever language it is written in. By the way, I don’t need any return value because the VB script isn’t asking for that. If it was, I’d check what type of variable the script wants to store your return in, ask you if Open returns that type, and tell you to return a value to me”.

    So you see, it all works like how you want your “managed environment” to work. But unlike NET, it just doesn’t have automatic garbage collection (so that VB script had better free up resources as soon as its done with them, or other apps may be denied access to them), nor compiling to bytecode (so it ain’t gonna be as fast if that ActiveX object wraps some interpreted code — but it actually is faster if wrapping some truly compiled code like C++, C, Pascal, etc). But your issue isn’t memory leaks nor speed. Your issue is not having this framework implemented for your use… on Linux.

    Complain to Linux open source developers that they need to document their software better, and provide good tutorials/examples so others know how to use them. DBus has been around for awhile now, but whereas MS got lots of folks to add ActiveX script support to their software (within the same amount of time that DBus has been around), the only people using DBus are the guys who wrote it, and a few people who spent lots and lots and lots of time trying to figure out how to use it, and actually succeeding.

    And that’s why you don’t have all this support for Linux.

  22. jg
    Posted August 7, 2008 at 2:34 am | Permalink

    You edited your preceding post after I wrote my above reply to add a lot more questions. I think from my description of the type library, you can deduce a lot of answers to those questions. For example, VB.NET’s IDE has an “object browser” that queries the type libraries of all installed ActiveX components to get the names of all functions/data members, and number and datatype of all args and returns to functions. So of course, that’s how the IDE’s “IntelliSense” works. And when you install a new ActiveX component, it automatically works with it. You don’t have to update your IDE, or rewrite some sort of “keyword file” or whatever. The IDE automatically recognizes it, and utilizes the standardized type library in all ActiveX components to extract the needed info.

    “Exceptions” are generally handled by IError “sub-objects” in an ActiveX component. So yes, there is a standardized method for error reporting designed to be used by various languages.

    Obviously, a lot of implementation issues were considered by MS developers when they came up with this. Certainly some developers have not been entirely pleased with everything. (Frankly, I’ve had some really scathing things to say about IDispatch. That seems to be a sore point with others too. I would have implemented that functionality very differently. And don’t even get me started about ActiveX’s debugger helper API). I’m not sure what “articles” you’ve read about ActiveX, but the dirty little secret is that, contrary to what Ubuntu fanbois will typically tell you, not everything associated with Microsoft is awful and unusable. In fact, some of it frankly blows the competition away. For whatever faults it has, ActiveX is one of those examples because Linux doesn’t even have something comparable to that, despite the existence of things like DBus.

    Yes, MS is moving away from ActiveX scripting to .NET. Hey, they can sell you something new if you want it. What company doesn’t want to have something new to sell you? And there are some things that .NET will give you, like the garbage collection, and speed-up of interpreted languages I alluded to. But I think it’s a bit overrated, has its own problems that earlier alternatives didn’t have, and frankly, I think that a language like C# is so overly abstract that it ends up producing code and programmers that don’t know how to write stable, reliable, efficient apps. You may disagree, but that’s what I see.

    But the bottom line is: ActiveX scripting would do the things you stated in your blog you wanted to do (and certainly better than what you’re doing now), and Linux doesn’t have the same level of support for such. My take on this is that it’s largely due to the failure of most open source programmers to document and demonstrate their code as well as MS’ community of developers do. Dbus should have done this already. It hasn’t. Why? It’s the docs/tutorials/examples. What do you think Ballmer was really saying when he said it’s about “Developers! Developers! Developers!”? He’s saying that MS is going to make sure devs have what they need to get their work done as easily, efficiently, and effectively as possible. And for a start, you can’t do it with the state of Linux docs/tutorials/examples.

    Your friend asked what you would do. I’m telling you my answer to absolutely everyone involved with Linux is to start right there with the docs/tutorials/examples, especially for the programmers who bring you the software you need to do your work. Ballmer knows it. Shouldn’t someone else too?

  23. jg
    Posted August 7, 2008 at 2:42 am | Permalink

    Oh, as far as your questions “How do you do this with Linux?”, that’s the problem. Even though I’ve been writing Linux software, and would definitely be availing myself of Linux alternatives to ActiveX scripting, had my scouring of the internet found good docs/tutorials/examples for such, I just haven’t found those answers. Maybe someone, somewhere, has the answers (such as the guy who wrote DBus). But apparently, he’s not telling — at least not in a way that makes sense to me (and if you read my articles above, you’ll see I’m not a dimwit. Given a decent tutorial written in English, instead of techno-babble, I can usually figure out the gist of what’s going on). But I haven’t with any Linux alternative to ActiveX scripting… and that’s a problem that I think others are having too. And it’s a problem that infests much more than just a Linux alternative to ActiveX scripting.

    Again. What should you be doing about fixing linux support? Attend to the docs/tutorials/examples, and make sure everyone else understands the importance of that too. Things will fall into place after that.

  24. Jamie
    Posted August 8, 2008 at 10:06 pm | Permalink

    You know I had a similar feeling when I started playing with Linux. I’m a paid up MSDN subscriber kinda guy. I would lay awake at night dreaming of how to fix linux. But if you look at how you’d “fix” linux, do you see yourself implementing windows-like solutions? I do. Question is, do these windows-like changes have any other effects. The conclusion that I came to is that the windows-like solutions would put in place all the constraints that makes windows less useful than linux. This became vastly clearer to me when I stopped playing with linux, and started using it to make money.

    Example. I set up vsftpd today. I had to muck about with firewalls, openssl, vsftp.conf and pam. I edited numerous text files. The end results is I have real and virtual users logging in to my ftp box and it all works. Migrating this to another machine is a matter of copying over the keys and the config files. I know where they are and it works. I write this shit down in my own private blog that no-one can see. Its almost like, like, keeping a journal, like, when you have to get your MEng!

    Another example: I needed to format some data for a web page. It was just simple to sed the stdout of a program than it was to muck about with the program. Could have. Didn’t need to.

    You talk about libDoesX, libRubyDoesX etc. You seem to want a C based libDoesX that Ruby, C# etc can bind to. I have a couple of problems with this:

    1) C and C++ are dead as far as I’m concerned. Nothing useful should be done in them unless you are programming a kernel or a video game (and I’ve done both). You cannot write good code as quickly as you can in a modern language.
    2) Mono-culture. If everyone has to use libC++DoesX, then libC++DoesX is a bottleneck. Its a lowest common denominator. And chances are its not even the fastest at presenting information to the various different higher level languages.

    Unlike Microsoft, the free software world is not a mono culture. It does not matter if two groups do the same work in parallel, because those two groups will implement their own best solution. If the first group wrote libDoesX in C, it would take them longer. The second group would find that this libDoesX doesn’t do quite what they need, and starts to modify it - hating having to use C the whole time. I believe that each group would save time writing it from scratch in their own language.

    Another disadvantage of monoculture is libDoesXandYandZandDependsOnAandBandC as a result, and each of those then has to depend on everything else. Someone did a call graph for an http request in apache vs IE. What a difference. This is why Server 2008 with *no* features installed takes 800Mb to boot.

    I now have a number of linux machines that work, work well and work securely. The perform vastly faster than windows, because they don’t take 800Mb of RAM just to boot.

    ****

    In my view, the “space between” is the “space between” *testing* paradigms: although one might thing of sed/awk/perl as separate applications, they are not - they are like methods in the larger application whose source is made up of a myriad of .sh/.conf files. This has problems:

    1) most people who would put their .cs files into svn, don’t put their whatever.conf in. They just don’t equate it to source code.
    2) there are no unit testing frameworks for bash^H^H^H well f*** me there is, but I’ve never seen anyone use it.
    3) executables are great, because they are a single lump of stuff immune to tampering. however, .sh applications can be broken in many ways by changing files seemingly completely unrelated. The executable in this case is human editable, i.e. breakable. Binary blobs are not. As a result, binaries are less fragile and more trust-worthy (unless you are pwned).

    Now that I have a lot of unix boxes, I’m working on this myself.

  25. Rob
    Posted August 17, 2008 at 11:22 am | Permalink

    Didn’t read through the above comments but making things work through the command line first is the whole ‘nix philosophy. That’s why a properly designed program can interact and work with virtually any other through pipes and all that. Trying to use .NET/managed code as mentioned above is just trying to make ‘nix act like Windows and that would not be a good thing.

  26. Posted August 17, 2008 at 5:08 pm | Permalink

    The problems you mention in the article are really at the very heart of the problems with, not only *nix, but Windows and most operating systems. The operating system provides an enviroment that is inherently fragmented (different languages and libraries) and unsafe (C pointers, no OS control over processes).

    Last night, I spent several hours reading about managed OS’s, including SharpOS, Singularity, and Midori. After reading a lengthly research article about Singularity, I concluded that a managed OS running managed code is going to be the future.

    All processes are completely separated from the kernel and from other processes and can only communicate with each other via pre-defined, strongly typed, ‘contracts.’ You can use C#, managed Ruby, managed Python, or whatever language you want, and they can all reference the same assemblies due to strong-typing and the nature of managed code.

    Another benefit of a managed OS is the inherent modularity of the OS (due to the microkernel approach), making it an ideal platform to be use for everything from mobile phones to cloud computing environments.

    One of the currentl downsides of managed code is the need for the CLR. In Singularity and SharpOS, there is no CLR. Applications are compiled to IL code, verified for type-safety, and then compiled to native code (Singularity project acknowledges the need for strongly typed assembly), thus eliminating the overhead of managed code.

    I would love to see the FOSS community grab ahold of SharpOS and turn it into a functional OS, proving that it can innovate and provide real solutions for the future.

  27. Timothy Fries
    Posted August 18, 2008 at 5:39 pm | Permalink

    > It does not matter if two groups do the same work in parallel, because those two groups will implement their own best solution. If the first group wrote libDoesX in C, it would take them longer. The second group would find that this libDoesX doesn’t do quite what they need, and starts to modify it - hating having to use C the whole time. I believe that each group would save time writing it from scratch in their own language.

    I have to strongly disagree on this point, on both of your assumptions:

    On the statement that “it doesn’t matter if two groups do the same work in parallel”, I disagree because in the end you’re getting twice the code, and twice the code means twice the bugs. Consolidating libraries into a single implementation means that any testing efforts applied to the library become a value-add to every consumer of the library. Implementing your own library from scratch means you’re increasing your project’s sphere of responsibility (time and cost), and most likely its into an area that’s of only peripheral concern to your project’s primary goal.

    Your second statement that “each group would save time writing it from scratch in their own language” is demonstrably wrong except for the most trivial definitions of “libDoesX”. As an exercise in reductio ad absurdum, if reimplementing libraries was faster than using existing libraries, then every program would come with its own custom operating system. Obviously that’s not true — so you must accept that there is some level of common library that’s more efficient to reuse rather than rewrite, and I’ll maintain given the reasoning I used for your first statement that the bar of complexity where it becomes sensible to reuse rather than reimplement is somewhere around the neighborhood of a few hundred lines of code.

    > Another disadvantage of monoculture is libDoesXandYandZandDependsOnAandBandC as a result, and each of those then has to depend on everything else. Someone did a call graph for an http request in apache vs IE. What a difference. This is why Server 2008 with *no* features installed takes 800Mb to boot.

    Linux and open source is general aren’t exactly innocent in this regard, and I’d argue are much, much worse off.

    Any decent modern memory manager will not even load pages of ‘libDoesXandYandZandDependsOnAandBandC’ and its dependent libraries unless you actually use them; and when it does, because there’s a single implementation, the operating system can share the code pages between multiple processes.

    In contrast, the ‘everyone implements their own’ approach means that not only is each process going to be loading libDoesX and its dependencies, but also that they’re effectively going to be private pages since nobody’s sharing. And that’s not even touching on the ‘DLL Hell on Steroids’ that is the Linux library versioning story, which not only contributes to pages being non-sharable, but also makes dependencies incredibly brittle.

    Windows Server 2008 may take some amount of memory to load (lets stop exaggerating the actual amount), but most of that memory is common libraries that you never need to load again, and thus contribute to keeping the overall memory usage down as more processes are started.

    There are plenty of reasons that maximizing code reuse has been a goal of software engineering for decades — and those good reasons don’t just all fly out the door just because it’s not convenient for open source or Linux to do so.

2 Trackbacks

  1. [...] Ed Ropple’s Homepage Code. Baseball. Whatever. Skip to content Resume « Fixing Linux, Part One: “The Space Between” [...]

  2. [...] That’s not exactly a new question, but I hadn’t been asked it before. So I put a little thought into it. My first instinct was to look toward the kernel, but that was pretty stupid of me–the kernel no doubt has problems, but I’m not a kernel hacker and I’m not qualified to talk about them. The area where I routinely run into problems and annoyances is userspace, so why not look at that? Read more at Ed Ropple’s Homepage [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*