Why in principle should everything we do on computers behave and beshaped like a file?
it's just something that every program running on a computer knows how to do, so why bother with special APIs you have to link against if you can just write to a file? (note you can still develop those layers if you wish, but you can also write a device driver in sh if you wish, because why not?)
Bad abstractions are notoriously problematic, and no abstraction is fit for every purpose.
A fairer analogy would be if everything in the kitchen was bowl-shaped, but you could do bowl-like actions and get non-bowl behavior. Drop the carrot in the peelbowl and it is peeled, drop the carrot in the knifebowl and it is diced, drop the cubes in the stovebowl and they are cooked. Every manipulation is placing things in bowls. Every bowl is the same shape which means you can store them however is intuitive to you (instead of by shape).
People have access to user-mode filesystems and FUSE, people could have made everything have a file-like interface by now if that was desirable - apparently it isn't. And because different tasks are different, it makes sense that they would fit different abstractions and interfaces, wouldn't it?
A file system is a tree of named objects. These objects are seamlessly part of the OS and served by a program or kernel driver called a file server which can then be shared over a network. Security is then handled by file permissions so authentication is native through the system and not bolted on. It fits together very well and removes so much pointless code and mechanisms.
A great example is a old uni demo where a system was built to control X10 outlets and switches (early home automation gear). Each device was a file in a directory tree that represents a building with sub directories for floors and rooms - e.g. 'cat /mnt/admin-building/2fl/rm201/lights' would return 'on' or 'off' (maybe it's a dimmer and its 0-255, or an r,g,b, value or w/e, sky's the limit, just put the logic in the fs). To change the state of the lights you just echo off >/mnt/admin-building/2fl/rm201/lights.
Now you can make a script that shuts all the lights off in the building by walking directories and looking for "lights" then writing off to those files. Maybe it's a stage, all your lights are on DMX and you like the current settings so then you 'tar -c /mnt/auditorium/stage/lighting|gzip >student_orientation_lighting_preset.tar.gz' and do the reverse over-writing all the archived settings back to their respective files. You could even serve those files over smb to a windows machine and turn lights on and off using notepad or whatever. And the file data doesn't have to be text, it could be binary too. It's just that for some things like the state of lights, temperature or w/e can easily be stored and retrieved as human readable text.
That is the beauty and power of 9p - its removes protocol barriers and hands you named objects seamlessly integrated into your OS which you can read/write using regular every day tools. It's a shame so many people can't grasp it.
> "sky's the limit, just put the logic in the fs"
You can, but why is it better to do that? "just" put the logic in a Python script seems much simpler than putting it in a low level pretend filesystem driver, on the other side of an arbitrary interface you had to come up with to satisfy an ideology that everything should have to go through this interface, right?
Over Christmas I set some LED displays running, controlled by an RS-232 serial port. It would be possible to echo a line of text to a pretend filename and have it appear on the sign, but there is a command for whether the text is static or scrolling and one for whether the text appears on the top line or bottom line. That information has to be somewhere, either as different paths in the filesystem e.g. /mnt/sign/static/row/top vs /mnt/sign/scrolling/row/top or as formatted content inside the file, or both.
There's a command to change the colour of the subsequent text, which can be used anywhere in the message, many times over - so that can't easily go in the filesystem path so now there needs to be some intermediate structure which both the shell script and the filesystem driver speak, to be able to pass this command through the file interface. With a COM port in Windows, if one script opens it and another script tries to open it then there's a clear error that the port is in use. If a usermode filesystem driver held the com port open, what would happen if two scripts tried to write to these files? Does one get a mysterious "write failed" filesystem error to catch and debug instead of a proper relevant error message? Do they have to proxy error messages through /mnt/sign/meta/error ?
This is one of the most trivial things a computer can do, sending a short text, which is possible with echoing to a com port /dev/ttyS0, and the abstraction idea of making it a file is already creaking under the weight of the task, adding the burden of arbitrary path decisions and data formatting and task-specific escape codes and control sequences, and bodgy-error handling, while assisting with basically nothing - while you can find /mnt/* you get no help with that, no link to any documentation, no further discovery, no interactivity like you get from a command line binary program interface. Much much easier to put the sign's commands directly in a short Python script, isn't it? And other more complex tasks just get more and more intense, as the "plain text" files in /etc/ are an ad-hoc mix of formats and data types and parsing rules and symbolic links to /opt/ and other random places.
As I say in another comment, usermode filesystems never became the default or popular way to do things, why not?