In Plan 9, you send signals and messages to a file by writing to it. And read messages by reading from it.
It's in essence no different than OOP or actor model or what have you.
In Plan 9, you send signals and messages to a file by writing to it. And read messages by reading from it.
It's in essence no different than OOP or actor model or what have you.
interface UniversalInterface {
fun open(…)
fun read(…)
fun write(…)
fun close(…)
}
If you went to a software engineering design review meeting, proposing that several different kinds of objects representing everything from files, network sockets, to arbitrary devices should all use the interface above, you’d be laughed out of the room.Ultimately, when someone does end up implementing something like the above as the sole interface for some major component, it’ll result in libraries that return a wrapping object with a more useable and pleasing interface that abstracts away the ugliness of using UniversalInterface to interact with said component.
I see two ways forward with this. Either: (a) present the option of using UniversalInterface to interact with X object, in addition to interface that’s much more idiomatic and closer to how X object actually behaves.
Or, (b) come up with an alternative universal (or flexible) object interaction interface that’s much more flexible than UniversalInterface.
You're describing a meeting in which people seem unaware of the purpose of uniform interfaces. Not sure we could call such a meeting "engineering design" meeting, because engineers tend to know better.
If I went up and proposed the same interface for all cables, displays, mice, keyboards, speakers, hard drives, phones... and called it USB, would I also be laughed out of the room?
There's no benefit to reinventing open/close/read/write in 50 different ways. The goal is to do it once, and then build more complex interfaces on top of it. That is, unless you're paid by the number of lines of code you write.
There is an universal interface, it is called "system call". Rather than build unnecessary layer on top of it, improve the syscalls if you don't like them, and get rid of ioctls, /proc, /sys and other pseudo-syscall abstractions.
Hence open is not part of your UniversalInterface, but it is a way to obtain a reference to it. It seems reasonable to have a generic way to dispose of an UniversalInterface (hence close). read/write are simply a generic ways to send and receive messages from UniversalInterface, not unlike a dynamically typed object. Ideally you would do a checked down cast to your actual interface [3], but this was designed to work with C so you have to make do.
[1] I don't subscribe to the Everything is an Object in the OO sense, but having a common base class for most OS resources seem a reasonable solution.
[2] or at the very least there isn't always a cross-resource-type namespace.
[3] Not unlike COM QueryInterface, and in fact UniversalInterface is equivalent to IUnknown
This is very obviously an acceptable solution because the whole world runs on TCP.
> Or, (b) come up with an alternative universal (or flexible) object interaction interface that’s much more flexible than UniversalInterface.
That’s, basically, what COM/Corba/… are. There, UniversalInterface has an additional call “If you are a Foo, give me your Foo interface”, with Foo as an argument to that call.
That's really good. The fact that the file interface just gives you a string of bytes, with no concept of structure or type safety in the interface itself is a major flow of it. Type safety is immensely valuable.
The metadata around files - ownership, permissions, creation time - apply to a lot more than files.
I don't really see it being laughed out of the room.
Yes? All interfaces do that, especially system interfaces. It's the whole purpose of interface - to provide implementation logic in a usable form. Try to call the kernel by hand and see the difference.
Doubtful. Why are the main paradigms?
Everything is an object
Everything is a function
Everything is a resource (REST)
Uniform interfaces are common for good reason: you gain a lot of flexibility for redirection, introspection and policy control.
It’s really “Everything has a File Descriptor”, nothing about the concept of a file has changed.
It's in essence no different than OOP or actor model or what have you.
I’m sure there’s an isomorphism that could be drawn but it does nothing to show that it’s an equally good paradigm to write software in. IMO, it’s a tortured abstraction.
This is akin to how shell piping in Unix is also just... text and bytes. This is limiting and produces many ad-hoc protocols.
But take what Plan 9 was trying to do, and add to it what Microsoft's PowerShell tried to do, where you stream objects, structured information, instead of just bytes, on the way in and out of commands and files...
And suddenly... we got ourselves an Erlang.
Many perfect and awesome systems have been built that never saw significant adoption.
I agree with ESR's observation: "Plan 9 failed simply because it fell short of being a compelling enough improvement on Unix to displace its ancestor. Compared to Plan 9, Unix creaks and clanks and has obvious rust spots, but it gets the job done well enough to hold its position. There is a lesson here for ambitious system architects: the most dangerous enemy of a better solution is an existing codebase that is just good enough." Source: https://www.catb.org/~esr/writings/taoup/html/plan9.html
Another amazing OS that never caught on was BeOS: https://en.wikipedia.org/wiki/BeOS Neal Stephenson's description of BeOS as "fully operational Batmobiles" is accurate and it is sad that BeOS did not become more mainstream. See https://people.cs.georgetown.edu/~clay/classes/spring2010/os...