13 ms·
The everything-is-a-file principle – Linus Torvalds
- Nokinside 8y ago> The whole point with "everything is a file" is not that you have some random filename (indeed, sockets and pipes show that "file" and "filename" have nothing to do with each other), but the fact that you can use common tools to operate on different things.
- fnord123 8y agoThe problem is that the POSIX style API is too low level to do easily do anything interesting and correct. Enter rocksdb, sqlite, etc.
- coldtea 8y agoIs that a problem though? It also means that POSIX doesn't constrict you -- it gives you the tools to build rocksdb, sqlite, etc and have them be performant.
- heinrichhartman 8y agoI hear there is quite some complexity in sqlite to work around quirks of the file system API, in order to avoid data loss, yet there are still ways this can happen: https://sqlite.org/howtocorrupt.html https://sqlite.org/howtocorrupt.html It's a bad sign if you have to repair the shortcomings of a lower layer in your application.
- mmt 8y agoHow many of those characteristics identified on that page are really shortcomings rather than, as the parent comment says, freedom-enhancing (if not performance-enhancing) features? The workarounds seem to have more to do with SQLite's use as an embedded library than with filesystem behavior. All of section 1 is about rogue overwriting. Absent a particularly fine-grained filesystem permission model, or enforced locking. The former might only have "freedom" implications without any performance penalty, but perhaps not the latter. Section 2 is about locking, so see above. Even if it's advisory, that just moves any slowdown from the kernel to the application. Of course, broken locking is clearly a shortcoming, and this is one of the quirkiest (maybe newest?) aspects of the filesystem. If anything qualifies under the "bad sign" characterization, this does. However, it's also not exactly fundamental to the filesystem, as even section 2.3 describes what SQLite will do if POSIX adivsory locking is not supported over NFS (i.e. it is possible for locking to be unavailable). The remaining sections all appear to be about bugs, either hardware, thread library, elsewhere in the kernel, SQLite itself, or in configuration/usage (disabling corruption protections).
- SamReidHughes 8y agoPOSIX does constrict you. That is, it doesn't let you get the full performance you could get by talking directly to the hardware. It doesn't offer abstract features that would be useful to people making rocksdb, sqlite, etc. In fact, it does a rather brutal job of constricting you. Of course, disk drive protocols also constrict you, relative to having direct control of firmware and visibility over raw flash devices, drive head position, etc. For example, it would be neat if you could send block A and block B to the disk at the same time, only to have the disk compute the checksum of block A and put it at offset k of block B before writing block B.
- coldtea 8y ago>POSIX does constrict you. That is, it doesn't let you get the full performance you could get by talking directly to the hardware. If it gave you that, it wouldn't be a standard anymore, just a bunch of instructions to talk to hardware. So, of course it constricts you in some degree, but way lesser than the higher order abstractions the parent talk about.
- SamReidHughes 8y agoWell it's more than just not being a bunch of instructions. It doesn't give you a ton of not hardware specific stuff that would be useful.
- fnord123 8y agoThe difficulty in getting things correct is a constriction for users of the API. And the overly strong API guarantees is a constriction on implementer. POSIX I/O is like C. It's super powerful. It's everywhere. It's not going away. But it has sharp edges. And we can sacrifice a little efficiency on the small scale to grab huge gains in other areas like productivity and reliability. Also relevant is Glenn Lockwood's excellent article on What's bad about POSIX I/O: https://www.nextplatform.com/2017/09/11/whats-bad-posix-io/ https://www.nextplatform.com/2017/09/11/whats-bad-posix-io/
- amyjess 8y agoI agree. In fact, I find myself looking at Classic Mac OS's resource fork and feeling profoundly sad that it feel by the wayside as *nix took over the world. The resource fork was a beautiful idea; structured data built into the filesystem itself, and I wonder what the computing world would have looked like if it was used by the dominant operating system of the Internet instead of a sideshow.
- fjsolwmv 8y agoWhy is the resource fork better than having say a foo.rsrc file alongside foo? Or operating on directories instead of files, like MacOSX bundles (like .app and .rtfd)?
- perl4ever 8y agoBeing able to operate on everything with the same tools is not a goal that everyone desires all the time. For instance, look at all the things with torx screws instead of phillips heads. Or, type systems in computer languages. Or, support for non-variadic functions. Or, file systems with forks.
- simongr3dal 8y agoThis might just be because I'm european, but phillips head screws really are the worst. They are so easy to strip because it is so easy to use an over- or undersized screwdriver. Torx or Hex screws are good because you can't really use the wrong sized screwdriver and the screws doesn't get stripped as easily.
- zxcmx 8y ago“you must have the correct tool” vs “if you have to, you can open this with a butter knife from the kitchen drawer”. They’ve both got their place IMHO and vive-la-difference :)
- rascul 8y agoI'm an American (of the U.S. variety) and I've been using and hating phillips head screws all my life. I agree with everything you said.
- fjsolwmv 8y agoPhillips was specifically designed so that cheap screws (or drivers) would take damage instead of the expensive thing being screwed into. http://www.acontinuouslean.com/2013/04/05/a-better-way-to-screw/ http://www.acontinuouslean.com/2013/04/05/a-better-way-to-sc...
- mmt 8y agoMy read on it is that it was to avoid anything taking damage, especially the screw (and screw head, other than, perhaps, the slots themselves, insofar as they could be used for future driving purposes).
- pjmlp 8y agoTry to apply the file concept to graphics programming. You won't get Crysis running out of it.
- ori_b 8y agoLinux already uses file operations like mmap with a few extra ioctls to implement graphics.
- coldtea 8y agoIf I am not mistaken, this is not unlike how all game graphics were done in the 80s... directly writing to some frame buffer...
- theoh 8y agoThe point is that writing to a file is basically passing a message to the kernel. Writing to a framebuffer is writing straight into memory.
- nly 8y agoSo mmap() the file?
- ninkendo 8y agoIn other words, don't treat it as a file any more?
- JdeBP 8y agoOnly if one also opines that memory mapping is a thing that one cannot generally do to files. (-:
- zbentley 8y agoIf we posit that memory mapping is a thing that one can generally do to files, then a ton of other abstractions break: how do you memory map a socket? Not a fixed piece of a socket's buffer, but communication on the socket itself?
- adamnemecek 8y agoI think that "everything is a file" is superseded by "everything is a reference". Memory for example isn't a file. Neither is a GPU. I believe that Windows' HANDLE is closer to the correct abstraction.
- partycoder 8y agoBut some things can be abstracted as files, and that's where Windows interoperability (and as a consequence, automation) falls short.
- anticensor 8y agoWindows has NPFS for them. Windows API is not just object system.
- enriquto 8y ago> Memory for example isn't a file. from proc(5) : /proc/[pid]/mem This file can be used to access the pages of a process's memory through open(2), read(2), and lseek(2)
- adamnemecek 8y agoI'm aware but I'm just not convinced the analogy fits.
- enriquto 8y agoIt's not an analogy, it's a file interface to memory.
- rosser 8y agoThe point isn't that everything is a file; it's that you can treat everything like a file. Of course the abstraction maps varying degrees of well, but it also simplifies the hell out of the lion's share of the ways we interact with computers, and serves as a foundation for the rest.
- DonHopkins 8y agoI always wanted /dev/zero, which is used to mmap zeros into memory, to be more general and use the device minor number to define which byte gets mapped, so you could mknod /dev/seven with a minor number of 7, to provide an infinite source of beeps!
- fooker 8y agoIf you really want this and do not have to be bothered about portability, just write a kernel module and load it. It will be about 40-60 lines of code.
- repsilat 8y agoYou can also open `<(yes '\007')` or something, or use `mkfifo` if you don't want to rely on bash. Not as fun as a kernel module, though :-)
- DonHopkins 8y agoIf I had my way you'd be able to define new kernel modules by downloading a few lines of PostScript. ;) Ok, JavaScript these days. But you know what I mean.
- enriquto 8y agopostscript is the cutest language i have ever learnt. I'd love to be able to use it more.
- DonHopkins 8y agoIt's essentially RPN Lisp (with dynamic binding, via the dictionary stack). NeWS had an OOP package that used the dict stack to implement a very Smalltalk-like object system with multiple inheritance, which could dynamically define methods and properties in objects and classes, etc.
- 8y ago
- osrec 8y agoI appreciate the work Linus has done a great deal. Clearly he's a gifted individual, but he does come across a bit aggressive in his communication at times! It can be funny, but also somewhat offensive. "... and a black star for being stupid"
- vortico 8y agoAs a BDFL, it's the only way to survive, unless you're on sedatives your whole life. You very frequently come across ideas that are so unexplainably stupid that the only way to fix them is to stop them in their tracks. Opening a friendly debate about the advantages and disadvantages is just a huge waste of multiple hours, because you'll never end up convincing people that their pet ideas/projects should go back to square one (or square zero in programming). His aggression has turned contributers away from the project and made negative relations, but the end goal is to maintain the Linux operating system, and his aggression, strictness, and blows to self esteem have had a proven effectiveness 10x more than soft discussions. Think about it this way: A dictator has to be extremely assertive because if he said "No, I don't want that in Linux" with no basis, he'd eventually lose his dictatorship power as people would form their own "unions" to try to change things, making several directionless forks of Linux. If he instead said, "This is a completely idiotic approach and anyone that thinks it's okay is braindead," nobody would question it and most people would just take his word for it. Most heated debates have an equal number of supporters for each side, and it takes someone with a strong voice to remind them that one decision must be chosen regardless.
- osrec 8y agoFair enough! Given the wild swings in up/down votes on my original comment, the subject is clearly divisive :P
- chris_wot 8y agoExcept it sort of seems to me that he changes his mind years later.
- fjsolwmv 8y agoYou skipped the middle ground between "no basis" and "ad hominem is the only basis". Lying about things and people is a bad way to force people to accept decisions. Calling someone or something stupid isn't a technical argument, it's a poorly worded conclusion.
- fooker 8y agoI am glad Linux chooses pragmatism over what I call 'aesthetic engineering', where new interfaces and abstractions do not buy anything.
- DonHopkins 8y agoI prefer the "everything is a computer" API. (Which happens to be Alan Kay's model of object oriented programming as message passing.) https://softwareengineering.stackexchange.com/questions/46592/so-what-did-alan-kay-really-mean-by-the-term-object-oriented https://softwareengineering.stackexchange.com/questions/4659... >"I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages (so messaging came at the very beginning -- it took a while to see how to do messaging in a programming language efficiently enough to be useful)." -Alan Kay NeFS -- aka NFS 3.0 -- used a PostScript interpreter as the file system API. https://news.ycombinator.com/item?id=17061967 https://news.ycombinator.com/item?id=17061967
- agumonkey 8y agoSame, I think the file 'abstraction' is only valid for data flow. But whenever you have system components represented as files, you end up with a bunch of side API bolted (kinda like ioctl in linux). Plan 9 had a different view IIRC, something like everything has a protocol.
- pjmlp 8y agoYes, but Carmack had some issues having a framebuffer as file. https://marc.info/?a=111558719100068&r=1&w=4 https://marc.info/?a=111558719100068&r=1&w=4
- theoh 8y agoPlan 9's rio window system expected most graphical clients to use the draw functions, which operate by writing to /dev/draw. /dev/draw wasn't even a framebuffer—it was a control file that you wrote messages into. It clearly wouldn't have met Carmack's requirements though as the thread you link to points out, the Plan 9 team would have been happy for him to map the framebuffer into the address space of his process.
- agumonkey 8y agothis carmack guy is really not cut for graphics programming
- dozzie 8y agoEverything is a file... except processes (you can't just delete a process), network interfaces (try setting an IP address with a write() or ioctl()), and plenty of other things. Unix never had "everything is a file" as its mantra, and Torvalds never introduced it.
- yjftsjthsd-h 8y ago> you can't just delete a process Kill? Possibly kill -9?
- agumonkey 8y agowell if they were files you'd use 'rm /proc/$pid'
- DonHopkins 8y agoThe power management system should be integrated with the file system so you can turn the power off by going "rm /dev/power". And also with the desktop so you can drag the power into the garbage can.
- smcl 8y agoSurely /dev/power would return “1” when you read it (“0” when it is powered down, of course), and “echo 0 > /dev/power” would turn the machine off. :-)
- laumars 8y agoPower is a physical state rather than a logical one. It would make more sense defining runlevels that way.
- yjftsjthsd-h 8y agoOh, we actually do something like that already; CPUs are listed in /sys and you can enable or disable them by echoing 0/1 to their power file.
- vbezhenar 8y ago"Everything is a file" is like "Everything is a REST". Sounds good but doesn't work in practice.
- w8rbt 8y agoHas worked great on Unix for how many years now? Keep it simple is all that Linus is saying.
- vbezhenar 8y agoThere are many abstractions with Unix that are not files. I don't even know any modern unix, where directory is a file.
- lazyant 8y agoA directory is just a special type of file that contains a list of file names and their corresponding inodes, how is a directory NOT a file?
- ioquatix 8y agoThat's a reasonable point at an abstract level. But in reality, while you use `open`, `read`, `write` and `close` for files, the equivalent for directories is `opendir`, `readdir`, `closedir`.
- elderK 8y agoI don't see how providing specialized open/read/close calls for directories breaks the file abstraction. Imagine byte-level access to a directory. You'd have to have some library in userspace that would correctly be able to manipulate that directory's metadata. Now imagine doing that for various filesystems. Plan 9's namespaces and file-servers were pretty awesome and flexible. It really opened my eyes to the generality of the file abstraction.
- 21 8y agoLet's not forget the massive pain that /dev/urandom being a file was, that they had to add a syscall for it: getrandom()
- Aaron1011 8y agoI thought that the issue with /dev/urandom was that it wouldn't block when read shortly after startup (when the entropy pool wasn't yet initialized).
- mmebane 8y agoThat's part of it. Another concern was ensuring that fetching a random number couldn't fail due to file descriptor exhaustion. [1] [1]: https://lwn.net/Articles/605828/ https://lwn.net/Articles/605828/
- hsivonen 8y agoLikewise, it would be nice if on ARMv7 one could figure out if NEON is available without having to have permission to open a file under /proc.
- ggm 8y agoI liked the idea of filerefs for everything precisely because I hate the sockets() semantics. But, most of this is about the awful pain of the ioctl() stuff you either have to call as setup magic on the FD, or pass as setsockopts() because you cant coerce enough into the limited modality of file-like moments opening the (pseudo) file. Really it feels more like 'what is the hierarchical structure of my namespace' because once you nail that down, the file semantics become clearer. if its async io under the class of io its open("/io/async/my-thing", ...) So its one of those yes.. but its so hard to nail it down moments.
- stevebmark 8y agoI've always wondered what sad life Linus leads to make him communicate like every developer I've worked with that I don't want to work with. Clearly he has deeper issues that lead to his blooming sarcasm and condescension, that our community already struggles with. This behavior is not normal, nor sustainable.
- bdcravens 8y ago> This behavior is not normal, nor sustainable. I can't speak to how Linus's personality has changed over time, but for a 27 year old software project, I'd say it hasn't impacted sustainability.
- RcouF1uZ4gsC 8y agoOne thing though is that the “nice” maintainers of popular open source projects burn out (see Guido’s recent retirement as BDFL). Linus seems to be going strong. I would rather have a mean, effective Linus than a nice, burned out Linus.
- vortico 8y agoYes, this is absolutely the reason. Open-source software maintainance burns out people daily, and most can only tolerate <4 years. 20+ years is godlike, and can only be achieved if you have the world's longest patience, or correctly direct your madness on exactly the people who caused it. It's the only way. All maintainers do it to some extent, depending on how far separated they are with their contributers. Linus works very closely with them, which is why he experiences so much BS firsthand.
- userbinator 8y agoThis behavior is not normal Some of the other comments here have mentioned, but it bears repeating: this is not the "normal" Linus. He doesn't rant 100% of the time, but when he does, you had better pay attention because it must be something very important.
- peterwwillis 8y ago
- _bxg1 8y agoI would be terrified to ever try and contribute anything to Linux, lest Linus yell at me and call me stupid. Seems like he does that in every excerpt that gets posted here.
- curun1r 8y agoThere's a form of survivorship bias at play there..."Linus responds sensibly" doesn't normally get posted to HN or anywhere beyond the actual forum where he responded, for that matter.
- _bxg1 8y agoThat's probably true
- ur-whale 8y agoWhy are you terrified by the idea of getting yelled at? What ever happened to sticks and stones?
- deleted 8y ago[deleted]
- fjsolwmv 8y agoHumans aren't robots.
- gizmodo59 8y agoI don’t think that should stop you. The worry comes much later when your contribution is significant. Furthermore, his rants are not absurd IMHO.
- _bxg1 8y agoI'm not a systems programmer so that wouldn't actually be the thing stopping me. That said, the validity of his rants would just make it worse...
- 8y ago
- Animats 8y agoIn QNX, everything is a message, including files. The basic primitive is MsgSend, sent to another process which has a MsgRecv outstanding. The other process sends a reply back with a MsgReply, which unblocks the MsgSend and returns data. Any amount of data can be sent. POSIX file primitives, open/close/read/write, are small functions that make MsgSend calls. MsgSend is a more useful primitive than a file. It's a subroutine call across processes, a better fit to anything that isn't stream I/O. In most OSs, you want a subroutine call, but the OS gives you an I/O operation. Linux has to stand on its head for operations such as getting all the properties of a pluggable device, because returning a variable length array of fixed-format records as an atomic operation isn't a Linux primitive. Microkernels have a bad reputation because interprocess communication in Mach was botched. Mach was built on BSD. To do this right, you have to design CPU scheduling and message passing together, and they need to be tightly coupled. The key to interprocess communication is arranging the normal path for a message pass to throw control from one process to another without a trip through the scheduler. Get that wrong and your microkernel will be sluggish.
- the8472 8y agoWell, on linux you can also sendmsg files between processes, by using files (unix domain sockets). So you can sendmsg everything. Even memory (memfd)
- _wmd 8y agosendmsg isn't a synchronous operation, and there is no lock-step operation of sender and receiver supplying and retrieving a result. Sure you can make something QNX-like, but parent's point was much more general than that: most OS APIs and primitives are not easily expressed in terms of bytestreams
- Animats 8y agoYes, and when you express them as bytestreams, you end up with framing and marshalling and serialization. People start sending JSON. Then they want to put everything in one process because the performance is so low.
- tobyhinloopen 8y agoLinus is an asshole. But if you have made some nice things, you are allowed to be an ass, it seems.
- rossdavidh 8y agoHypothesis: the reason Linus Torvalds is still BDFL for Linux, but Guido van Rossum recently announced he is stepping down as BDFL of Python, is that GvR is just a lot nicer as a human being. Being a BDFL either requires getting a lot of abuse and not responding in kind, or being such an irascible boor that it doesn't bother you. Just a hypothesis; I've never met either one and never been a BDFL either.
- mabynogy 8y agoRob Pike designed a nice windowing system around files: http://doc.cat-v.org/plan_9/3rd_edition/rio/rio_slides.pdf http://doc.cat-v.org/plan_9/3rd_edition/rio/rio_slides.pdf
- kchr 8y agoI first learned of Rob Pike when starting to dabble with golang. Now I notice he's been involved in more or less everything I already use or stumble over. Busy guy!
- popee 8y agoHe is right, but I feel fat now
- theshadowknows 8y agoIt must be very frustrating being Linus
- lisper 8y agoWow, Linus had me all the way to the very end: > If you can read on it, it's a file. Um, no. If you can SEEK on it, it's a file. If you can't, it's a socket or a pipe.
- UlisesAC4 8y agoMaybe you could see them as in memory files. Or buffers of files.
- lisper 8y agoHuh? See what as memory files? (And what the fleep is a "memory file"?)
- fjsolwmv 8y agoI think Linus understands Linux files. Reread the message: > In UNIX, a file descriptor is pretty much anything. You could say that sockets aren't remotely file-like, and you'd be right. What's your point? The fact that you can't seek on a socket is irrelevant to the thread, which is about accessing files, not navigating them.
- lisper 8y ago> I think Linus understands Linux files. Sure, but that doesn't mean he doesn't occasionally make a mistake. > In that message, he's talking about... Yes, I know. But the larger context is Linus debunking (correctly) the unix philosophy that "everything is a file". Linus is correct: it is not the case, never has been the case, nor should it be the case, that everything is a file. But then he undermines his own argument with the (mistaken) claim that "if you can read it, it's a file." No. There's a salient difference between files one the one hand, and pipes and sockets on the other, and it has nothing to do with whether or not they have names. A named pipe is still a pipe, not a file. "Files" in /dev are not files, neither are "files" in /proc, despite the fact that they have names. It's a detail, but an important one in the larger context IMHO.
- gsaga 8y ago>But there's absolutely no point in opening /dev/futex from a shell script or similar, because you don't get anything from it. The same can be said for files in '/dev/input'. Why are mouse and touchpad input exposed as files?
- LukeShu 8y agoNo, you can't say the same thing. You open it from a shell script, you literally do get something from it. In the email you quote, Linus gives two reasons why futex and sockets should not be files: > there's absolutely no point in opening /dev/futex from a shell script or similar, because you don't get anything from it. > Perhaps because you cannot enumerate sockets and pipes? It stands to reason that the converse of those _are_ reasons to make things a file: I can open /dev/input/$X and get something from it. The normal thing to do is open a file under /dev/input/ and read data from it. No, we don't usually do that directly, because libinput does it for us; but that's what it's doing. As an exception, if code deals with joysticks, it seems to me that it's common to open /dev/input/js$X yourself. I can list the entries in /dev/input/ and enumerate the input devices attached to the system.
- dmitrygr 8y agoTry evtest to see
- rurban 8y agoHe really has to be awarded an Anti-UNIX prize somewhen.
- FrozenVoid 8y agoHaving everything as X isn't as flexible and performant as specialized types."When all you have is a hammer". This results in systems being built ontop of narrow file-as-everything service, providing a wider interface to real data(events,sockets,pipes,messages,async IO). Of course, people don't like it and build libraries to bypass it(and even the kernel layer itself https://blog.cloudflare.com/kernel-bypass/ https://blog.cloudflare.com/kernel-bypass/ ) just because the interface is inherently limited and inflexible.
- zvrba 8y agoWindows does it nicely: everything is a securable (with ACL) object. Process, thread, file, socket, console, service... is an object, in a namespace. The only exception I've encountered so far is network management stuff, like routing tables. WinObj is a nice tool to inspect how Windows handles this (https://docs.microsoft.com/en-us/sysinternals/downloads/winobj https://docs.microsoft.com/en-us/sysinternals/downloads/wino...) > In Windows, you have 15 different versions of "read()" with sockets and files and pipes all having strange special cases and special system calls. That's not correct. ReadFile can be used for all kinds of objects, including sockets: https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-readfile https://docs.microsoft.com/en-us/windows/desktop/api/fileapi... Yes, it behaves differently depending on the type of the object, but so does read(2) (E.g., you'll never get SIGCHLD when reading from a file, for example.)
- forapurpose 8y agoRemember that Linus wrote that in 2007. Let's say he was talking about XP; might things have changed since then?
- zvrba 8y agoThe concepts of objects and ACLs are in the NT kernel itself. So things have worked like this on all windows versions built on the NT kernel: from WinNT 3.1, to Win2k, ... to this day. Windows TCPIP stack has improved since then, but I'd be _very_ surprised if ReadFile didn't work on sockets on XP (or anything NT-based, actually). In any case, he's very rash to call out Windows when Linux has its share of special-purpose syscalls that do the "same" thing (e.g.: send, sendv, sendmsg, sendfile, sendmmsg, …) with myriads of options to alter their behavior.
- mpweiher 8y agoLinus wrote (2002): "But what would you _do_ with them? What would be the advantage as compared to the current situation?" Here is one answer (2008): "This paper presents PipesFS, an I/O architecture for Linux 2.6 that increases I/O throughput and adds support for heterogeneous parallel processors by (1) collapsing many I/O interfaces onto one: the Unix pipeline, (2) increasing pipe efficiency and (3) exploiting pipeline modularity to spread computation across all available processors. PipesFS extends the pipeline model to kernel I/O and communicates with applications through a Linux virtual filesystem (VFS), where directory nodes represent operations and pipe nodes export live kernel data. Users can thus interact with kernel I/O through existing calls like mkdir, tools like grep, most languages and even shell scripts. To support performance critical tasks, PipesFS improves pipe throughput through copy, context switch and cache miss avoidance. To integrate heterogeneous processors (e.g., the Cell) it transparently moves operations to the most efficient type of core" Sounds pretty good to me! https://research.vu.nl/en/publications/pipesfs-fast-linux-io-in-the-unix-tradition https://research.vu.nl/en/publications/pipesfs-fast-linux-io...
- Froyoh 8y agoGosh is this guy an ass. So condescending.
- sctb 8y agoCould you please work on making your comments more thoughtful and informative? https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html