7 ms·
The MicroPHP Fallacy
- symbiotic 15y agoI don't think there's any disagreement about using the right tool for the job. What I took from the original MicroPHP Manifesto is that the solution is not to have a ton of hammers to choose from. Instead, make sure you have a couple different types of hammer heads and a couple different types of handles that you can mix and match so that the right hammer is always available. This way your toolbox is much lighter and easier to carry around (easier to keep up to date with improvements to the code and easier to maintain). I think it's about breaking things into smaller pieces.
- ErrantX 15y agoI used to feel this way. However I tended to find myself, on most projects, spending a surprising amount of time tweaking incompatibilities between the various lightweight libraries I was using. And it was a bit of an effort to unify things like logging and error reporting. Which is when I realised the utility of a bulky framework; for the most part it is a suite of libraries that work together/are compatible but which someone else maintains for me :) This was a big step for me. (although I still use the lightweight approach for smaller projects)
- symbiotic 15y agoThat's a reasonable complaint, but maybe it means we need better lightweight libraries with well thought out interfaces or better library management like deweller suggested in the comments on the original thread.
- ErrantX 15y agoThat would be good - but then you begin to talk about a unified logging interface and standardisation like folder structure, class loading, class interfaces and so on. At which point it's basically a framework (perhaps without the routing/initialisation code). One thing I would like to see (no idea if it exists) is a core package architecture (that did all of the above) and let you hang packages as and when you need them. I've been keeping an eye out for such a thing for a while with no joy.
- sequoia 15y agoI'm excited to see that there is discussion going on here! I might suggest that the "manifesto" author did not say "I'm a PHP developer" to be limiting (i.e. I only write PHP) but to contrast with being e.g. a "Cake developer" or a "Rails developer." Assuming this is a reasonable interpretation, he is actually making the same "Don't tie yourself to one framework" point that OP is making here. So: agreement! (I think.) I don't know how relevant this is but I couldn't help but notice that the "hammer" analogy for frameworks was an interesting choice in light of Joel S.'s well known "Hammer Factory Factory" article. http://discuss.joelonsoftware.com/default.asp?joel.3.219431.12 http://discuss.joelonsoftware.com/default.asp?joel.3.219431.... Was this a coincidence or intentional? Anyway I thought it was a funny coincidence. :)
- digitallimit0 15y agoYeah, by being a "PHP developer" rather than say, a Zend developer, he was making that right-hammer-for-the-job argument back in the original article long before ircmaxell got around to implying anything else. I think there's a lot of agreement here that got lost in "simple isn't always better!"
- Periodic 15y agoLooking at it now I see you're right. "PHP developer" is meant to be less limiting than the options the author of the MicroPHP Manifesto was considering. When it was brought up in the context of this article, I read it as someone being proud to be a developer of PHP. Among many academic crowds and HN it feels like PHP is a dirty word.
- astrodust 15y agoThe hammer is a tool many are familiar with, and metaphors involving it go back a long way, such as the "Golden Hammer" principle (http://en.wikipedia.org/wiki/Law_of_the_instrument http://en.wikipedia.org/wiki/Law_of_the_instrument cites a usage in 1966).
- digitallimit0 15y agoHis last bit on the latter part of the manifesto "I like simple, readable code" seems pretty unnecessary. I doubt the original article's author would argue against good coding practices like abstraction layers. And really, the example he provides doesn't even stand against "simple" or "readable". Abstracted code is exactly that.
- astrodust 15y agoYou know what "simple, readable code" is? It's something that hasn't been exposed to the real world. Once your application has been in circulation, exposed to the elements, hostile or indifferent users, it will develop barnacle-like patches that look ugly but serve a specific and important purpose. You can keep code clean(er) if you're vigilant, but sometimes there's no way to express very complicated logic in a concise manner. Often abstraction looks cleaner but generally only hides complexity and can tend to increase complexity on the whole.
- chernevik 15y agoAs a noob I find terms "simple, readable code" really confusing. I recently had to learn some PHP (I'm mostly Python) to implement a seemingly stupid simple interface between some HTML form input and a REST API. Should be simple, right? But there is all this weirdness validating data inputs like dates. And we have to process the form data data so each field input goes to the proper API field. And hey look that mapping only varies in its _data_ among form / API target pairings, so I should abstract that code out into a function or I'll be chasing bugs through the copied-and-pasted. The API provides a library for formulating requests but this doesn't expose some key functionalities to unit testing so I ant to revise to do that. Et cetera. And, the next thing I know this thing is umpty-ump lines, and while the scripts actually processing the data are reasonably legible, they're sitting over a tangle of stuff that's rather harder to navigate. I've got classes to manipulate various core data to produce various data structures supporting sundry activities, but this essentially means those data structures are abstractions and thus hard to inspect when trying to remember how some process is working or what's going wrong. (The unit tests are worthwhile if only b/c their check values provide concrete examples of how those derived structures look.) To make the code "simple" in one place, I've created complexity elsewhere. Obviously, this is in part a novice problem. If I can lay out and document the supporting code better everything gets easier to follow. But still, 5000 lines to input some form data, am I doing this right? So is "simple, readable code" that helpful as a goal? At the end of the day it seems like there is X degree of complexity in any of these tasks, and any strategy to "simplify" is really just a framework for deciding where to place what complexities. And if that's right, then "simple, readable code" can become either a time suck or a discouragement in a hurry. I'm either playing Whack-A-Mole as I chase Complexity from one corner to the next and back to the start, or I'm going home depressed b/c I'm too stupid to write "simple, readable code". It sounds great, I suppose it is where people end up when they get good, so it's probably very helpful as an indicator of whether you're good yet. But I'm not sure it's very helpful for figuring out how to get to good.
- astrodust 15y agoIf using an example involving Dave Grohl can't set this straight, nothing will.
- sequoia 15y agoBut where does Rick Allen fit in here? I must know!!
- stdbrouw 15y ago> Programming in a language involves limiting thoughts and implementations to only constructs that the language directly supports. However, programming into a language involves finding the solution they want to do, and then determining how to express those thoughts in the language. Learning how to program involves learning to think like a computer, and seeing the world in terms of loops and filters and manipulations. Mastering a specific programming language takes that one step further, because you become so familiar with it that you start thinking in terms of the specific constructs and the idiom that it offers. The speed gains are enormous once your brain adapts to that way of thinking, and I wouldn't give that up for anything. I appreciate the sentiment – be a programmer, not the master of one specific way of programming – but I think there are better ways to achieve that goal than by programming "into" a language. The Pragmatic Programmer credo, for example, to learn a new language ever year, is much more appealing.
- billpatrianakos 15y agoThis article wasn't really necessary. Okay, so the guy who wrote the MicroPHP Manifesto didn't use a perfect analogy. So what? I'm pretty sure we all got his point. Everything that got refuted here in this post didn't need to be refuted. We're all smart enough to understand that the MicroPHP Manifesto was a reaction to large, sometimes complicated frameworks that caused the author frustration. All he was saying was that he just wants to use less code and simplify things. Who can argue with that? Even a novice developer would understand that his manifesto wasn't the one true way. It's just something to think about before diving into Zend or Cake by default. Why nitpick? There's always more to what you read than just the words on screen. Considering the motivation and circumstances behind the MicroPHP Manifesto I can't see why anyone would make it out to be something it isn't, bad analogies or not.
- lincolnwebs 15y agoI believe it was both necessary and not a nitpick. While I agree choosing Cake or Zend by default is a fool's errand, the MicroPHP Manifesto read like someone who'd just found CodeIgniter for the first time.
- grumpycanuck 15y agoI suggest you do some research about the author of the MicroPHP manifesto before throwing snark out there like that. Ed is a personal friend (and we do a podcast together) with many, MANY years of experience building applications using PHP. While I don't agree with him on some points in there, he does deserve to not be shit on by people who can't be bothered to do 30 seconds of research about the author.
- lincolnwebs 15y agoI didn't "shit on him", I criticized his tenor in that article.
- billpatrianakos 15y agoI didn't do any research about the author and just now found out his name is Ed. I mention this because I'm someone whose only experience with this author was that one post and even with that small amount of information I was able to infer that the guy had experience and knew what he was talking about. I also think its very obvious that what Ed suggests is not to be taken at face value. When I read the microPHP Manifesto my reaction was that it made total sense but of course, as always, follow it if and when it makes sense. Taking into account that the post was probably a kind of rant as a reaction to some framework frustrations his manifesto makes perfect sense. Now the author of this article refuting the Manifesto seems to be under the impression that what Ed suggests should be the way things are done from now on. It's clear as day that all Ed was sayng was that sometimes the MicroPHP Manifesto tenets make more sense. And they do! Sometimes! Guess what? Everyone is right! Hopefully that doesn't make some people's brain explode but both authors are correct. Mileage varies. The thing I didn't like most about this was how he picked apart the drummer analogy. I felt like it was a low blow and not really necessary.
- lincolnwebs 15y agoThis perfectly encapsulates my unease about the MicroPHP Manifesto. Neither drummer was doing it wrong; they both chose the most fitting tools. The reviling of "overkill" solutions is a natural step in becoming an experienced developer but that doesn't mean it should top HN every time someone has that epiphany.
- gwillen 15y agoOf the two methods he shows, I want to cast a strong dissenting vote that I prefer method number 1. In method 1, the complexity of the operation -- and it's not that much complexity, let's be honest here! -- is all in one place where I can examine and work with it, but there's not so much that it's a barrier to understanding. By contrast, in method 2, the complexity is hidden. If there's a bug in method 2, I have way more levels of abstraction to dig through before I've got a clue what's going on. If someone else wrote method 2, I've got probably three or four source files to do archaeology in before I can even be sure what it does.
- ircmaxell 15y agoIf that's all that your code does, then that's fine to use #1. But in a larger class, it's needlessly cluttering the class with operations below its abstraction level. Why should a logger care about file locks and the such? Why should you care about file locks when editing the logger? Hint: You shouldn't normally. As far as "the complexity is hidden", you're absolutely right. I want that complexity hidden. By hiding the complexity in this way, I can reduce duplication and at the same time make the code far easier to read. Sure, you do need to dig through more levels of abstraction if you need to debug something. But abstracting in this way enables bugs to be fixed far easier, since the methods are really small and simple, the "ripple" effect is far easier to understand and contain. Think about how long it took you to understand what log() did. With the first one, you needed to parse a whole lot of detail (including the flag passed to fopen, the two exception checks, the arguments passed to flock, the fprintf declaration and the flock call arguments). With the second, all you needed to do is read the two steps: 1. createLogMessage() and 2. file->append($message). At a glance you know what the method is supposed to be doing. Why is there such a hang up that people want to know what code is doing at all levels? If you name your APIs well, you should be able to look at the method's name (and perhaps its arguments in some cases) and know without a doubt what it's doing (at least to the abstraction level the API is designed for). If you really need to know details, you can go deeper, but I know when I read $file->append($message) that I'm appending a message to a file. I don't need to worry about anything else 99.9% of the time. So I'd rather get the clean win with well named APIs, than spend my time sifting through methods like the first one...
- lux 15y agoThe code example given seems a bit disingenuous, since the same level of complexity is present in the code, only the parts of it are broken up into single-purpose methods that may or may not be overkill depending on the needs of the project. For example, you can swap `$this->file` with a different object to write to alternate logging backends, but you could just as easily replace `$this->logFile` with an alternate stream wrapper to do the same thing in the original example... For reference, here's the first example: public function log($message, $level) { $f = fopen($this->logFile, 'a'); if (!$f) { throw new LogicException('Could not open file for writing'); } if (!flock($f, LOCK_EX | LOCK_NB)) { throw new RuntimeException('Could not lock file'); } fprintf($f, '%s [%s] %s - %s', $this->machineName, date('Y-m-d H:i:s'), $level, $message); flock($f, LOCK_UN); fclose($f); } And here's what your improved example would actually be: /* In $this->file's class */ public function append ($message) { $f = fopen($this->logFile, 'a'); if (!$f) { throw new LogicException('Could not open file for writing'); } if (!flock($f, LOCK_EX | LOCK_NB)) { throw new RuntimeException('Could not lock file'); } fwrite($f, $message); flock($f, LOCK_UN); fclose($f); } /* In Log class */ public function createLogMessage ($message, $level) { return sprintf('%s [%s] %s - %s', $this->machineName, date('Y-m-d H:i:s'), $level, $message); } public function log($message, $level = 'notice') { $message = $this->createLogMessage($message, $level); $this->file->append($message); } Just a nitpick, but sometimes we over-abstract because we're too used to doing so. To me, a separate `createLogMessage()` method that just wraps a `sprintf()` seems like a sign of that. (not saying I haven't been equally guilty of this 1000x before :)
- randallsquared 15y agoIf you're going to be creating log messages all over the place, that createLogMessage method is actually really useful. Not only does it enforce having the machine name and date (and date in a certain format), but calling it saves looking up what the argument to date has to be to get the format you want (which I nearly always have to do). It seems like an excellent case of hiding the fiddly details.