PHP
PHP was great for live coding on production.
One slip and sudden phone calls would tell you there is an error.
Taylor Otwell, inventor and maintainer of popular PHP framework Laravel, is warning against overly complex code and the risks of bypassing the framework. Developers are sometimes drawn to building "cathedrals of complexity that aren't so easy to change," he said, speaking in a podcast for maintainable.fm, a series produced by …
There is far too much software out there with little, or inadequate, documentation. This results in people misusing it with the expected results - including security nightmares.
Sometimes the documentation is only good for gurus, ie people who are highly skilled in the technology; this makes it very hard to new people to learn and, eventually, become gurus.
Documentation is hard to write but is vital.
The first version must be written by the people who created the cathedral as no one else really understands it. But these developers are likely to have poor communication skills so others are needed to tidy it up and make it understandable to mere mortals.
Expect to spend as much effort on writing the holy book as it took to build the cathedral.
But these developers are likely to have poor communication skills so others are needed to tidy it up and make it understandable to mere mortals.
It's not that the developers have poor communication skills. They tend to be constantly communicating with team members, management, and often end users.
The problem is that developers have a higher knowledge base with the product and many things have become obvious to them as the product evolves and they don't think to document them. Just like the product itself, documentation is an iterative process. And just like with UIs and APIs, you need a third party to review the documentation to point out these omissions.
There is also the fact that documentation is treated like a secondary task that few people like to do.
There is also the fact that documentation is treated like a secondary task that few people like to do.
Except for the technical authors who write good docs, by working closely with the developers and making the effort to understand the product (as compared to the ones that just buff up the grammar on the developers' notes).
Sadly most of them have been laid off by the big companies over the past 10 years or so, because having the developers write a blog entry seems cheaper to the beancounters.
Texas Instruments datasheets are very decent too.
Especially if one compares them with those of the one or two German manufacturers remaining. I wonder if they still use forced labour, given the lack of motivation that transpires through the result.
Code and documentation are not the same thing. Code is functions and data structures. You can annotate the code to describe what functions do and what data structures they use to do it but that doesn't describe how the software is intended to be used - though it may help the (different set of) people who have to maintain it.
Documentation serves a different purpose. it explains what tasks the entire body of the code can perform and which functions must be called in which order to achieve specific tasks. It explains what elements of the data structures must be provided by the caller, which are optional and what elements must be preserved across a sequence of function calls. It explains the responsibility for allocating and freeing resources and for the nature and responsibility of any locking required in a multithreaded environment. It explains error conditions and recovery. It explains performance considerations and scalability. In other words it describes the operation of the software as a whole system, not the operation of its individual parts. There isn't a place for it in a particular source file because it's the summation of the salient information from all of them together with the relevant underlying assumptions.
I despair when I look at most software projects with documentation automatically generated from the code because all it tells me is how the software developer chose to decompose the problem into units of code. If I'm lucky there will be a trivial example of a program that strings the function calls together in a sufficiently counter-intuitive way to demonstrate that Id better look elsewhere. Writing documentation may appear to waste the time of the developer that understands their own code, but not doing so wastes the time of everyone else who might want to use that code by forcing them to gain an understanding of it not through a clear explanation of the external interface, but by inspecting the innards in minute detail in the hope of being able to infer the bigger picture.
> I despair when I look at most software projects with documentation automatically generated from the code because all it tells me is how the software developer chose to decompose the problem into units of code
Glad you said "most", not "all", because it *is* possible to use something like Doxygen to generate documentation that runs the gamut from end-user to bug-fixing or feature enhancing dev. I *think* I managed it once (once!)[1]: well, the client liked it at the long handover meeting and nobody ever came back to grab me for a quick shout in the following years...
BUT using (in this case, Doxygen) like that was, I admit, very much going against the grain of how Doxygen itself is presented (and the same is true of similar tools I've looked at): they go into detail about how to mark up your code *but* there is little, if any, emphasis on writing SEPARATE files that are just documentation - to the extent I've been asked "what was the point of these dot-dox files, they only make the build system more complicated?"! Bangs head on table. "Why not use Word?" Um, version control; keeping materials together; regenerating and fixing references as the code matures; being able to drop "TODO: write this dox" into the same tracker as we drop "TODO: write this function"; the docs are broken into easy chunks so you aren't constantly looking at hundreds of pages of Word content in a disheartening and never ending task; auto-generating variants (End User Manual is done in PDF without hyperlinks to any code; Installer's Manual in PDF hyperlinks the User features to the INI files, Dev's Manual in HTML has all the same, but now hyperlinks to where the INI settings are acted upon in code...).
Getting just devs to write docs in "the code markup tool" is hard enough, but getting management to allow it, yikes. You can fudge things, sometimes[2] but, again, the tools (that I've seen, so far) don't make it easy.
And "by easy" I don't mean "write another bleeping WYSIWYG IDE that does it all"! You can sensibly allow "I am not a dev" authors to use, say, a WYSIWYG editor for writing Markdown that can then be pulled into the dot-dox, that is good (great, even). But you also need to be able to drive the generation from a build system (GUI begone!), so encourage long and meaningful file name extensions[3]; you need to pull in externals (images, auto-generated lists of CLI options, ...)[4], must support multiple programming languages (without still being so obviously a Python tool that got hacked for C++ and Bison that has those guys foaming at the mouth).
Most important of all:
When you go to the website for the tool (looking at you, Sphinx, Doxygen - well, everyone) and the "how to use this", please, please, START by showing how to write the User docs, the Overview Of My Library, even The Next Great American Novel, as organised prose; output into lots of language lovely End User and Management-friendly formats. THEN segue over to cross-referencing your example code. THEN into adding details into the bulk of your code! That last bit really, really is the least important, honest. Management may leave love to see a table of all the parameters of flump19() but if you haven't got that far yet (as it is last on your list!) a direct copy of just the declaration is a usable standin for anybody who'll actually use that level of the docs! Go back to the history of *when* that struct has five fields, not three, and the arguments that'll at least mean you can say "well, you were warned" when Mr SuperNewbie "optimises" your code and it all stops working!
[1] important note: I had time *scheduled* on this project for a write-up *and* management wasn't demanding it be done in Word (phew), so there was an opportunity.
[2] my little utility for a particular End User doc generates Word files, as per Management demands. Well, to be honest, it generates HTML that looks like the stuff (an old) Word spat out and gives it a dot-dot extension...
[3] seriously, I encourage the use of fred.markdown.txt, or even better, fred.github_markdown.txt! *Any* user can double-click and read it in Notepad, any *sensible* Markdown editor can open them (AND prompt for that as the extension when saving a file! Your's can't? Then it is in the wrong!) Make loves those names, gets all the options set correctly.
[4] sigh, ok, I'll add a pass through another preprocessor into the build - getting further away from one nicely documented document-writing language as we go
I'll second praise for Doxygen; it is a powerful and versatile tool that is capable of producing user documentation, but doing so requires intent on the part of the developer. It truly excels at producing developer documentation, because it can produce useful hyper-linked documentation in text, graphs, and pictures without developer intent or participation. The result is much better if the developer provides minimal cooperation in formatting comments, but I've run impenetrable, barely-commented code through Doxygen and received for my minimal effort a treasured roadmap that displayed the spaghetti code in all its intertwined glory.
> Expectation is that developers write code that is understandable.
Not in a corporate context, no. You *claim* to write code that is as clear and understandable as possible in the circumstances, but if you *actually* do that you can be easily replaced. We wouldn't want that, would we now?
Please be mindful of what you write in a public forum. Young people might get the wrong impression.
(Yes, I'm only here for the BOFH column)
This post has been deleted by its author
"Use the l[e]ast amount of code to get the most amount of results.
Somehow the world thought more slop was better"
Too right. Many many years ago when I was writing software professionally, my boss asked me one day "how many lines of code are in that thing you've made?" (it was clear he was producing a report for his boss and amount of code was a metric being tracked by someone somewhere). I told him it was complicated, did he mean the amount of lines of code in the project, or the number of lines that I had actually typed into the keyboard with my own pink digits? I remember it was at least an order of magnitude difference.
Did I care that I had included a huge amount of code that I hadn't actually written, or even seen with my eyes? Not really, because it meant I could produce something working quickly, and who doesn't want to get their work done quickly? The ease with which a numpty like me could pull in code, whack it together, run it and see that after a bit of cajoling it did what I wanted it to was, with hindsight, terrifying. Looking back, I'm glad it wasn't anything related to safety.
As for avoiding "cathedrals of complexity", keeping it simple is good advice in any discipline. In the other hand, simplicity isn't always easy to find, as Bart Simpson once said "he says there are no simple solutions, I say he's not looking hard enough".
And on the other side, we have people who think that the right approach is to write everything yourself, which means that we end up with twenty different implementations of similar but not identical subsets of the same thing, most of them containing the same bugs, which they will eventually find and need to debug and fix manually. Meanwhile, someone who did that in a portable way found and fixed those in 2004 and has built a lot of useful functionality that will eventually be added. The only question is whether they added enough other stuff to counteract the benefits of having something mature and under active use elsewhere.
But what kind of efficiency, because that's generally the problem when discussing this kind of thing. For example, when you say "Use the l[e]ast amount of code to get the most amount of results", the literal interpretation means code golf. I'm sure that's not what you mean, but a less literal interpretation is not to write for the future. Write the code that achieves the goal you have right now and let expansion be later's problem. Also not a good idea.
Most considerations of efficiency focus too much on one resource. For example, it's popular to complain about RAM usage having increased, and most of those complaints are wrong, something that old-school programmers know better than anyone. They were faced with many conflicting resources which were significantly limited and had to decide how to manage them. If that meant that you waste a bunch of CPU cycles so that you can fit all this data into RAM in a compressed way, that might be the only way to get the program running on the computer they had, so they did it. The same is true if it was RAM they had to use more of to get speed out of the slow CPU at their disposal. They had to pick between those tradeoffs lots of times and they had to choose correctly each time or their software wouldn't run in the environment it needed to.
When someone uses a ton of RAM today, they might be doing it for speed, because being able to use a hundred megabytes when you probably could fit in five can make some types of actions much snappier, but even when they're not, they may be optimizing for another limited resource, with one of the important ones being developer time. It's expensive and in short supply, whereas until you get to a certain level, RAM often isn't. Libraries versus writing it yourself is relevant to that tradeoff. Even if we ignore the many ways that doing everything yourself can mean building the same untested code when someone else's tested stuff exists, there's still time spent building code that is already out there. Every manufacturer of an embedded device could write their own code to access the hardware. Every application could be written in assembly. We built operating systems and compilers to save us time, and to protect us from making mistakes. Libraries can be the same. In both cases, that doesn't mean that you should use anything and everything; it'd be a bad idea to build your embedded devices off a bad kernel (people who build them sometimes need to learn that), and a library might introduce more risks than it solves. Neither of those are guaranteed, and efficiency is not a good argument against them unless you have specific numbers about what inefficiency exists in the specific library you're considering and why the resource it's using more of is among those you need to focus on most.
The photo for this feed on Bluesky was of Sagrada Família (well worth a visit).
However Sagrada Família is not a cathedral! Barcelona already had a cathedral (also well worth a visit), since medieval timers, and Sagrada Família is not replacing it.
Someone needs to check what photo they are associating to these articles to avoid looking ignorant.
Otwell maintains a close grip on Laravel open source. "I'm the only person that merges pull requests,"
A bit like a pilot and co-pilot shouldn't have the same food option whilst on flight-deck duty, let's hope that were Otwell and Torvalds to attend the same function, they opt for different food that is on offer.
One supports a web front-end project, and the other is a crucial server-side resource. It would be a bit unfortunate if both were to end up in hospital at the same time with severe food poisoning.
complex, stick it behind a simple interface.
Thats what I was taught.
So it does'nt matter how well programmed and complex your sort algorithm is, maybe something involving complex numbers and creating something that proves the Riemann hypothesis as a result, you stick it behind something like File.sort(fileName);
Oh and write the documentation up too. maybe because someone might want to read it, but usually because 9 months later you want to figure what you did..
He's a fine one to talk when we have all sorts of complexity in Laravel which is barely documented (I mean, yes it's 'documented' but telling you the names of parameters doesn't necessarily explain how to use them).
The worst offender for me is the "Eloquent" ORM (which is technically separate but all examples are based on it) where the names of Model relationships such as HasOne and BelongsTo aren't immediately clear how they relate to the database and then getting into polymorphic relationships such as MorphedByMany get very complicated - the "English" name of the relationship sounds simple enough but I have to refer to a cheat sheet every time I use them, especially if working table and column names which buck convention.
I'm all for keeping things simple whenever possible but I feel like people in glass houses shouldn't throw stones in this case.
Indeed he should take his own advice, considering a lot of Laravel is built upon Symfony which could be argued is easier to understand. But I agree with Eloquent, there's too much "magic" happening and, several documented, but for the initiated only code features, which would have someone who's trying to read the code come to a dead end scratching their head without knowing about Laravel's automagic table wiring.
I've long considered one of the easiest ways to handle getting data from a database is simple decide on the methods you'd like for getting the data write an interface, then you can have an implementation class with simple PDO calls and SQL statements, because you've used a interface you can then add decorators for event dispatchers and loggers.
Laravel is very much a prime example of a complex and undocumented system. It's entirely constructed from layers of clever abstraction atop clever abstraction.
Meanwhile, the website just offers a set of tutorials which barely cover the basics.
So when it works, it's great: you type a couple of lines, and Laravel does all manner of introspection and extrapolation to perform several thousand lines worth of actions. But when it doesn't, figuring out the issue can be an absolute nightmare. Especially if - speaking from experience - you're dealing with code written by someone who used every single clever trick in the book.
Oddly, pretty much immediately after having written this complex lump of spaghetti, the person who wrote it left the company. More cynical minds may suggest that it was deliberately built in the most complex way possible as a skill-uplifting exercise to help with finding a new job. Great for them, but not so much for anyone who has to maintain their clever code!
Read a book on the Linux kernel internals and marvel at the amazingly huge amount of work done by complex algorithms usually with clever use of complex data structures to make it all run efficiently. Of course using C to execute the algorithms and do all those data structure lookups efficiently is very helpful. I am interested to see if rust can produce a kernel of the magnitude and scale of the Linux kernel while matching it's performance without causing performance or security problems using unsafe code. I am fairly certain that there are places in the current Linux kernel where using rust could improve security. Apparently so do some Linux kernel developers, including Linus.
More importantly, code needs to be obvious.
And I'm not talking about clear to code wizards. I'm talking about the new hire in a company that is tasked with making a change to a business-critical application.
If the code has been written by the kind of C++ wizard who thought that his one-line incredible unreadable function was a good idea, guess again.
You're not coding to show your skills. You're coding to solve a problem and to ensure that the next guy understands what you did and why.
If you expect the next guy to be a code deity, you have nothing to do with business coding.
When mentoring more junior colleagues I have a tendency to quote:
Code as if the next person to work on this code is a psychopath, who knows where you live.
And then remind them of the stress levels when dealing with a critical client incident.
The KISS principle, which stands for "Keep It Simple, Stupid" (some variations use "Keep It Short and Simple" or "Keep It Super Simple"), is a design principle that suggests simplicity should be a key goal in design, development, and other fields, such as engineering, software development, and user interface design. It was was invented by the U.S. Navy in the year 1960 or maybe even earlier.
So honesty is like writing a "Water is wet" at this point.
If I had a penny for every article about KISS in coding, I wouldn't know what to do with so many pennies, melt them into a fake chocolate bar?
Thing is simple coding is not memory safe.
You can be Memory Safe but slow or Simple but fast. There is not such a thing as memory safe and fast.
Code optimisation, as in actually editing your code so it does more with less lines of coding and loads faster, does take time.
The big problem is, the faster languages to code do tend to bloat.
In my experience there are two kinds of software documentation.
First: "This is what it is, this is what it does, this is how it does it."
Second (and regrettably common): "Look how smart we are."
Also remembering endless discussions with clients about how the requirements document should not contain details of design, implementation, methodology, or code.
Not to mention all those times the marketeers and sales droids did design work, the design team did coding, and the devs had to figure out what the thing was actually supposed to do.
In my experience there aretwothree kinds of software documentation.First: "This is what it is, this is what it does, this is how it does it."
Second (and regrettably common): "Look how smart we are."
Third (and even more regrettably, possibly the most common): " "
FTFY.
Let me get this right, he's preaching about maintainability on a Ruby on Rails podcast, talking about a project to build a Rails equivalent in...
Um... yeah speaking as a person who has to update rails based products, let me just say that bwahahahahahaha. That is all.
First, simple is HARD. In many cases, it has take a walk away to realize how to collapse the easy solution into the (much, much better) simple one. That's time spent that a lot of managers don't like to see being spent.
Second, one of the oldest versions of KISS was as follows: "Keep everything as simple as possible, and no more." The reality is that the problem to be solved might well be quite complex. My current favorite example has to do with chef/puppet/k8s kind of systems. The basic questions being asked: "How do I update the system to the desired state?" or "Do I need to add or drop a server to/from a service?" are trivially problems that require Turing complete languages to address, and yet we insist somehow that a DSL is the proper tool for the job.
In practice, however, Rails (I've not worked with Laravel) readily falls into the trap of oversimplification. The 'convention over configuration" rubric fails, and it fails badly, once you move past the prototyping stage. Real-life complexity steps in, and there are certain customizations that you need which mean you have forked Rails. Only the best SWEs can manage such a thing, but the best SWEs will transition you off Rails ASAP.
What's really nasty is that Rails devs are stunted in their professional growth because Rails takes care of so much for them. Yes, they are more productive with Rails. This year. Next? Not so much.
> are trivially problems that require Turing complete languages to address, and yet we insist somehow that a DSL is the proper tool for the job.
Um. Are you trying to say that a DSL (you do mean Domain Specific Language, yes?) can't be Turing Complete? 'cos it can, if you want it (or need it) to be.
(I have no experience with the specific systems you mention and any particular DSLs that they may, or may not, contain, btw, just commenting in general about aspersions being cast against DSLs as a whole)
In order to find simple solutions, you need to think about a problem before you actually start coding. Instead, if you are Big-"Tech" you can just throw dozens of developers onto any trivial problem.
The big advantage, from the point of Big-"Tech" is that you can increase the complexity of standards, raising the barrier of entry for competitors. That's why things like HTTP/2 and HTTP/3 exist.