[HN Gopher] The story of Max, a real programmer
___________________________________________________________________
The story of Max, a real programmer
Author : surprisetalk
Score : 118 points
Date : 2025-06-30 12:57 UTC (3 days ago)
(HTM) web link (incoherency.co.uk)
(TXT) w3m dump (incoherency.co.uk)
| fithisux wrote:
| I think Max's brain was not polluted with terror and showed trust
| in his tools.
|
| Today many devs (and not prograamers)
|
| are always suspicious, and terrified on the potential of
| something going wrong because someone will point a finger
|
| even if the error is harmless or improbable.
|
| My experience is that many modern devs are incapable of assigning
| significance or probabilities, they are usually not creative,
| fearful of "not using best practices", and do not take into
| consideration the anthropic aspect of software.
|
| My 2 cents
| xyzzy123 wrote:
| For years every external pentest of every perimeter of
| companies with old-school stuff like this has been finding
| these things and exploiting them and there are usually several
| webshells and weird stuff already on the server by the time
| they get to it. Very often the company forgot, or didn't know
| they had the thing.
|
| The end state of running 15 year old unmaintained PHP is that
| you accumulate webshells on your server or it gets wiped. Or
| you just lose it or forget about it, or the server stops
| running because the same dev practices that got you the PHP
| means you probably don't bother with things like backups,
| config management, version control, IaC etc (I don't mean the
| author, who probably does care about those things, I just mean
| in general).
|
| If these things are not a big deal (often it is not! and it's
| fun!) then absolutely go for it. In a non-work context I have
| no issues.
|
| TBH I'm not 100% sure that either the PHP version _or_ the go
| versions of that code are free from RCE style problems. I think
| it depends on server config (modern php defaults are probs
| fine), binary versions (like an old exiftool would bone you),
| OS (windows path stuff can be surprising) and internal details
| about how the commands handle flags and paths. But as you point
| out, it probably doesn't matter.
|
| Am I just doing the meme? :)
| s1mplicissimus wrote:
| > For years Imagebin was wide open to the public and anybody
| could upload their own images to it. Almost nobody did.
|
| There's your explanation why it could be so simple
| stavros wrote:
| The next version was equally open to the public.
| jonstewart wrote:
| Max wrote a simple php script. Mel wrote delay loops by accessing
| previous memory addresses on drums. They are not the same.
| wwfn wrote:
| I didn't get the reference. For anyone else in my shoes:
| https://en.wikipedia.org/wiki/The_Story_of_Mel
| stuartd wrote:
| I remembered this story the other day but couldn't remember
| the name - and then coincidentally came across this link to
| it! https://users.cs.utah.edu/~elb/folklore/mel.html
| bitwize wrote:
| I think that's the point. Max did things in the stupidest way
| that could possibly work, and it did work, and was simpler than
| the "smart" way, so was he less of a "real" programmer than
| Mel?
|
| I think for a kid, Max's code was great but ultimately you do
| need to learn to think about things like error handling,
| especially if your code is intended to go into "production"
| (i.e., someone besides yourself will use/host it).
| mrweasel wrote:
| No they are not, which makes the case for breaking up
| applications whenever possible. Some thinks that means micro
| services, but that's not my point.
|
| The example with the image sharing is pretty good, because it
| only needs to share images. In, shall we say more commercial
| settings, it would grow to handle meta data, scaling, comments,
| video sharing, account management and everything in between.
| When that happens Max's approach breaks down.
|
| If you keep your systems as "image sharing", "comments" and
| "blog" and just string them together via convention or simply
| hard coding links, you can keep the simple solutions. This is
| at the cost if integration, but for many use that's perfectly
| fine.
|
| Edit: Oh, that Mel.
| ferguess_k wrote:
| I'd argue that early computers are simple enough that one can
| actually put everything into one's head. Nowadays it is
| impossible.
| andrewvc wrote:
| It's a fun trip down memory lane, but the real story today, the
| sadder story, is that there is no longer any use for simple
| little programs like this that scratch an itch.
|
| They've all been solved 100x over by founders who've been funded
| on this site. It used to make sense to have a directory or cgi-
| bin of helpful scripts. Now it only makes sense as a bit of
| nostalgia.
|
| I miss the days when we had less, could get less done in a day...
| but felt more ownership over it. Those days are gone.
| layer8 wrote:
| It still makes sense to self-host, to have that ownership.
| tomasphan wrote:
| There is still use for small niche programs. I host my own gif
| repository, a website for collecting vinyls and my own weather
| dashboard. I don't expect anyone else to use these sites so
| they're tailored to my user experience and it's great.
| anonzzzies wrote:
| I have many 1000s of small tools and sites. Some have a few
| other users, most do not. It makes me productive so he.
| JadeNB wrote:
| > It's a fun trip down memory lane, but the real story today,
| the sadder story, is that there is no longer any use for simple
| little programs like this that scratch an itch.
|
| > They've all been solved 100x over by founders who've been
| funded on this site. It used to make sense to have a directory
| or cgi-bin of helpful scripts. Now it only makes sense as a bit
| of nostalgia.
|
| Why does it make more sense to learn the syntax for someone
| else's helper scripts than to roll my own, if the latter is as
| easy or easier, and afterwards I know how to solve the problem
| myself?
| newswasboring wrote:
| Because time is finite and you probably set out to achieve
| something else which is now on hold. Nothing wrong with
| distractions but let's not glorify them :).
| JadeNB wrote:
| > Because time is finite and you probably set out to
| achieve something else which is now on hold. Nothing wrong
| with distractions but let's not glorify them :).
|
| That's true, but it was also true before. To the extent
| that solving a problem to learn the details of solving it
| was ever worthwhile, which I think is and was quite a lot,
| I'd say it's still true now, even though there are lots of
| almost-but-not-quite solutions out there. That doesn't mean
| that you should solve _all_ problems on your own, but I
| think you also shouldn 't always use someone else's
| solution.
| ubermonkey wrote:
| "Itch-scratching" programming is all I ever do now, as my
| career pivoted away from being a full time developer a long
| time ago.
|
| But they're personal itches, not productizable itches. The joy
| is still there, though.
| FL410 wrote:
| I would argue those days are coming back. Thanks to LLMs, I
| have probably 10x more "utility" scripts/programs than I had 2
| years ago. Rather than bang my head against the wall for a
| couple hours to figure out how to (just barely) do something in
| Python to scratch an itch, I can get a nice, well documented,
| reusable and versatile tool in seconds. I'm less inclined than
| ever to go find some library or product that _kinda_ does what
| I need it to do, and instead create a simple tool of my own
| that does _exactly_ what I need it to.
| loloquwowndueo wrote:
| Just please if you ever give that tool to someone else to
| use, understand, maintain, or fix, mention that it was
| created using an LLM. Maybe ask your LLM to mention itself in
| a comment near the top of the file.
| kfajdsl wrote:
| The 'as is' nature of open source applies regardless of
| whether a human or LLM wrote the code.
| voidUpdate wrote:
| I mean, if you're going purely off LOC, in the go one each
| closing brace gets its own line, which probably inflates it quite
| a bit
| onli wrote:
| There is this part in there:
|
| > _Are our tools just worse now? Was early 2000s PHP actually
| good?_
|
| Not sure how rhetorical that was, but of course? PHP is a super
| efficient language that is tailor made to write dynamic web
| sites, unlike Go. The author mentions a couple of the features
| that made the original version easier to write and easier to
| maintain, they are made for the usecase, like $_GET.
|
| And if something like a template engine is needed, like it will
| be if the project is a little bit bigger, then PHP supports that
| just fine.
|
| > _Max didn 't need a request router, he just put his PHP file at
| the right place on the disk._
|
| The tendency to abstract code away leads to complexity, while a
| real useful abstraction is about minimizing complexity. Here, the
| placement of PHP files makes stuff easier -> it's a good
| abstraction.
|
| And that's why the original code is so much better.
| msteffen wrote:
| It still runs much of Facebook, I think
| theptip wrote:
| Only kind of, they have their own language (Hack) that
| descends from PHP. It's JIT instead of interpreted, and
| breaks back-compat in a few ways.
| Szpadel wrote:
| php is also jited nowadays. currently I believe the main
| advantage is that hack is async, you can fire multiple
| SQL/http requests in parallel and cut some wall time.
| theptip wrote:
| > Max didn't need a request router, he just put his PHP file at
| the right place on the disk.
|
| This also elides a bit of complexity; if I assume I already
| have the Nginx and gunicorn process then my Python web server
| isn't much worse. (Back in the day, LAMP stack used Apache.)
|
| I'll for sure grant the templating and web serving language
| features though.
| 13hunteo wrote:
| Mostly unrelated, but I dislike how normalized AI art is.
| ancarda wrote:
| I don't think it's unrelated at all. I saw the same picture and
| just closed the tab right away. Why should I read this article,
| the whole thing might be written by an LLM.
| naikrovek wrote:
| I think adding a AI image to filter out readers who think
| that way might have been intentional.
|
| I certainly consider it a good idea, now that it has come to
| mind.
| archerx wrote:
| The neo-Luddite filter
| LastTrain wrote:
| Could you also tag it "AI enhanced" or some such for us as
| well? Thanks.
| naikrovek wrote:
| nope. i don't use AI to write anything. I will just put
| an obviously AI image in the article to give those who
| make assumptions a reason to bail.
|
| and it will work very well.
| LastTrain wrote:
| What's wrong with using AI to write something?
| navane wrote:
| If anything, the ubiquity of style he used makes it into a
| deliberate meme. It's a little joke.
| mapcars wrote:
| Dislike it or not, its normalised as is everything else that is
| useful.
| layer8 wrote:
| It's not really useful in most instances.
| csomar wrote:
| Useful? I concur with a sibling comment. I stopped reading
| and closed the article as soon as I saw it.
| Melonai wrote:
| This happened to me too (almost subconsciously I might
| add). I'm actually not anti-AI at all, maybe a bit
| uninterested in AI-made art, since I don't fully see much
| use for it except for generating fun pictures of Golden
| Retriever dogs in silly situations, but this imitation-
| Ghibli art style is probably one of the least pleasing
| things to my eye that people love making. It's so round and
| without edge, it's colors are washed out in a very non-
| offensive way, and also it does not even look like the
| source material. I wouldn't be so aggrieved by it, I think,
| if there wasn't that wave where everyone and their dog was
| making pictures in that style. Sorry, just a small rant
| tangentially related to the article, which is fine. :)
| tudorizer wrote:
| same. Would have prefered a lo-fi stick figure drawn on a
| napkin. The cartoon Max detracts from the rest of article,
| which is a good read.
| riskable wrote:
| Your comment reminds me of people complaining about how using
| emoji in communications/text has become normalized. Generating
| images with AI is pretty fun and seems like an appropriate
| thing to do for a personal blog. As in, this is the exact sort
| of place where it's _most_ appropriate.
|
| It's not like this person was ever going to pay someone to make
| a cartoon drawing so nobody lost their livelihood over it.
| Seems like a harmless visual identifier (that helps you
| remember if you read the article if you stumble across it again
| later).
|
| Is it really such a bad thing when people use generative AI for
| fun or for their hobbies? This isn't the New York Times.
| Kostarrr wrote:
| Ok now I want to know. Does Max php code have security issues?
| Because especially in early straightforward PHP, those were all
| over the place. I vaguely remember PHP3 just injected query
| variables into your variables? But as $_GET is mentioned, this is
| probably at least not the case...
| Retr0id wrote:
| Both versions have security issues if you're sufficiently
| paranoid, because they shell out to exiftool on untrusted input
| files without any sandboxing. Exiftool has had RCE flaws in the
| past, and will likely have them again.
|
| But for a service with 1 user, it's fine.
| msteffen wrote:
| > The reason the Go code is so much bigger is because it checks
| and (kind of) handles errors everywhere (?) they could occur
|
| I've said before and will say again: error handling is most of
| what's hard about programming (certainly most of what's hard
| about distributed systems).
|
| I keep looking for a programming language that makes error
| handling a central part of the design (rather than focusing on
| non-error control flow of various kinds), but honestly I don't
| even know what would be better than the current options
| (Java/Python's exceptions, or Go's multiple returns, or Rust's
| similar-seeming Result<T, E>). I know Linus likes using goto for
| errors (though I think it just kind of looks like try/catch in C)
| but I don't know of much else.
|
| It would need to be the case that code that doesn't want to
| handle errors (like Max's simple website) doesn't have any error
| handling code, but it's easy to add, and common patterns (e.g.
| "retry this inner operation N times, maybe with back off and
| jitter, and then fail this outer operation, either exiting the
| program or leaving unaffected parts running") are easy to express
| cratermoon wrote:
| 1. Define Errors Out of Existence https://wiki.tcl-
| lang.org/page/Define+Errors+Out+of+Existenc... 2. Treat errors
| not as something going wrong but as incomplete actions leading
| to alternate valid code paths.
|
| On the second point, make errors part of the domain, and treat
| them as a kind of result outside the scope of the expected. Be
| like jazz musician Miles Davis and instead of covering up
| mistakes, make something wrong into something right.
| https://www.youtube.com/watch?v=FL4LxrN-iyw&t=183
| rauhl wrote:
| Have you seen Common Lisp's condition system? It's a step above
| exceptions, because one can signal a condition in low-level
| code, handle it in high-level code and then resume back at the
| lower level, or anywhere in between which has established a
| restart.
|
| https://gigamonkeys.com/book/beyond-exception-handling-condi...
| is a nice introduction;
| https://news.ycombinator.com/item?id=24867548 points to a great
| book about it. I believe that Smalltalk ended up using a
| similar system, too.
|
| > It would need to be the case that code that doesn't want to
| handle errors (like Max's simple website) doesn't have any
| error handling code, but it's easy to add, and common patterns
| (e.g. "retry this inner operation N times, maybe with back off
| and jitter, and then fail this outer operation, either exiting
| the program or leaving unaffected parts running") are easy to
| express
|
| Lisp's condition system can handle that! Here's a dumb function
| which signals a continuable error when i <= 3:
| (defun foo () (loop for i from 0 do
| (if (> i 3) (return (format nil "good i:
| ~d" i)) (cerror "Keep going." "~d is too
| low" i))))
|
| If one runs (foo) by hand then i starts at 0 and FOO signals an
| error; the debugger will include the option to continue, then i
| is 1 and FOO signals another error and one may choose to
| continue. That's good for interactive use, but kind of a pain
| in a program. Fortunately, there are ways to retry, and to even
| ignore errors completely.
|
| If one wishes to retry up to six times, one can bind a handler
| which invokes the CONTINUE restart: (let ((j
| 0)) (handler-bind ((error #'(lambda (c)
| (declare (ignore c)) ;; only retry six times
| (unless (> (incf j) 6) (invoke-restart
| 'continue))))) (foo)))
|
| If one wants to ignore errors, then (ignore-errors (foo)) will
| run and handle the error by returning two values: NIL and the
| first error.
| msteffen wrote:
| I had heard CL's error handling was different but didn't
| understand the details. Thanks for the explanation!
| WorldMaker wrote:
| In terms of developer ergonomics, try/catch seems among the
| best we've come up with so far. We want to focus on the success
| case and leave the error case as a footnote.
|
| That's the simplicity argument here too: sometimes we only want
| to write the success case, and are happy with platform defaults
| for error reporting. (Another thing that PHP handled out-of-
| the-box because its domain was so constrained; it had started
| with strong default HTML output for error conditions that's
| fairly readable and useful for debugging. It's also useful for
| disclosure leaks which is why the defaults and security best
| practices have shifted so much from the early days of PHP when
| even php_info() was by default turned on and easy to run to
| debug some random cgi-bin server you were assigned by the
| hosting company that week.)
|
| Most of the problems with try/catch aren't even really problems
| with that form of error handling, but with the types of the
| errors themselves. In C++/Java/C#/others, when an error happens
| we want stack traces for debugging and stack walks are
| expensive and may require pulling symbols data from somewhere
| else and that can be expensive. But that's not actually
| inherent to the try/catch pattern. You can throw cheaper error
| types. (JS you don't have to throw the nice Error family that
| does stack traces, you could throw a cheap string, for
| instance. Python has some stack walking tricks that keep its
| Exceptions somewhat cheaper and a lot lazier, because Python
| expects try/except to be a common flow control idiom.)
|
| We also know from Haskell do-notation and now async/await in so
| many languages (and some of Rust's syntax sugar, etc) that you
| can have the try/catch syntax sugar but still power it with
| Result/Either monads. You can have that cake and eat it, too.
| In JS, a Promise is a future Either<ResolvedType, RejectedType>
| but in an async/await function you are writing your
| interactions with it as "normal JS" try/catch. Both can and do
| coexist in the same language together, it's not really a
| "battle" between the two styles, the simple conceptual model of
| try/catch "footnotes" and the robust type system affordances of
| a Result/Either monad type.
|
| (If there is a war, it's with Go doing a _worst_ of both worlds
| and not using a true flat-mappable Monad for its return type.
| But then that would make try /catch easy syntax sugar to build
| on top of it, and that seems to be the big thing they don't
| want, for reasons that seem as much obstinance as anything to
| me.)
| immibis wrote:
| Abstracting error checking pays huge dividends, then. In PHP,
| if something crashes, it continues running and outputs nonsense
| (probably alright for the simplest of sites but you should turn
| this off if your thing has any kind of authentication) or it
| stops processing the page. PHP implicitly runs one process per
| request (not necessarily an OS process); everything is scoped
| to the request, and if the request fails it can just release
| every resource scoped to the request, and continue on. You
| could do the same in a CGI script by calling exit or abort.
| With any platform that handles all concurrent requests in a
| single process, you have to explicitly clean up a bunch of
| stuff, flush and close the response, and so on.
|
| There's a similar effect in transactional databases - or
| transactional anything. If you run into any problem, you just
| abort the transaction and you don't have to care about
| individual cleanup steps.
| huhtenberg wrote:
| The title is wrong. It should've been PHP, a Real
| Programming Tool.
|
| That's it. That's the story.
| naikrovek wrote:
| It's certainly useful, but without looking, what is the
| difference between these two methods in the standard library:
|
| array_sort
|
| sortArray
|
| Even if you _can_ answer that off the top of your head,
| consider how ridiculous it is that you needed to memorize that
| at some point. This is not the only example of such a thing a
| PHP dev needed to remember to be effective, either.
|
| Any programming language can be wielded in a simple way. Perl,
| for example, is superior to PHP in every way that is important
| to me.
|
| Go is as well, even though it's slightly more verbose than PHP
| for the authors imagebin tool.
|
| We don't do things simply because we've all been taught that
| complexity is cool and that using new tools is better than
| using old tools and so on.
|
| My employer creates pods in Kubernetes to run command line
| programs on a fixed schedule that could (FAR MORE SIMPLY) run
| in a cronjob on a utility server somewhere. And that cronjob
| could email us all when there is a problem. But instead I have
| to remember to regularly open a bookmark to an opensearch host
| with a stupidly complex 75-character hostname somewhere, find
| the index for the pod, search through all the logs for errors,
| and if I find any, I need to the dig further to get any useful
| contextual information about the failure ... or I could simply
| read an email that cron automatically delivered directly to my
| inbox. We stumble over ourselves to shove more things like that
| into kubernetes every day, and it drives me nuts. This entire
| industry has lost its goddamned mind.
| hnthrow90348765 wrote:
| >This entire industry has lost its goddamned mind.
|
| Yep, stay-with-the-fad pressures mean people need to farm
| experience using those fads.
|
| It won't change until the industry is okay with slowing down
| mgkimsal wrote:
| > ... I'm going to let my server keep running PHP.
|
| Please get it running at least PHP 8.3. Running PHP 5 or 7 on
| servers available to the public is negligent in 2025.
| maxehmookau wrote:
| I appreciated this, just because my name is Max and any sort of
| validation from HN is hard to come by.
|
| Also, the image kinda looks like me. It's not me though. I don't
| think.
| chbkall wrote:
| Reading this reminds me of the era which was envisioned will
| happen when I was in college (which was not long ago) -
| individuals and societies building their own independent custom
| stuff (both hardware and software) with the power of computers in
| everyone's hands. I am sure that is still happening in small
| pockets but most of the 'stuff' we use are built by large
| mindless corporates on which we have almost no control - and who
| prioritize profits over well-being of the employees and the
| community.
|
| I don't know for sure what the problem was (I have my theories)
| and why could we not get there where most people build their own
| custom products.
| rswail wrote:
| Who said you can't do that now? This article is about apache
| and php and a single script. You can do that today.
| chbkall wrote:
| Oh the point wasn't that we can't do it now. The point is
| that not enough people choose to make their own custom
| software and the systemic reason behind it.
| shayway wrote:
| This is something that's been on my mind a lot over the past
| few years. I think things were on that trajectory, but
| somewhere along the line it got out of wack.
|
| User interfaces became more user-friendly [0], while developer
| experience - though simpler in many ways - also became more
| complex, to handle the complex demands of modern software while
| maintaining a smooth user experience. In isolation both of
| these things make sense. But taken together, it means that
| instead of developer and user experience converging into a
| middle place where tools are a bit easier to learn and
| interfaces a bit more involved, they've diverged further, to
| where all the cognitive load is placed on the development side
| and the user expects an entirely frictionless experience.
|
| Specialization is at the core of our big interconnected
| society, so it's not a surprising outcome if you look at the
| past century or two of civilization. But at the same time I
| think there's something lost when roles become too segregated.
| In the same way homesteading has its own niche popularity, I
| believe there's a latent demand for digital homesteading too;
| we see its fringes in the slow rise of things like Neocities,
| the indie web, and open source software over the past few
| years.
|
| Personally I think we just have yet to see the 'killer app' for
| digital homesteading, some sort of central pillar or set of
| principles to grow around. The (small) web is the closest we
| have at the moment, but it carries a lot of technical baggage
| with it, too much to be able to walk the fine line needed
| between approachability and flexibility.
|
| Anyway, that's enough rambling for now. I'll save the rest for
| a blog post.
|
| [0] user-friendly as in being able to use it without learning
| anything first; not that that's necessarily in the user's best
| interest
| chbkall wrote:
| A bunch of useful insights in your reply. I really liked the
| insight of User Interfaces getting simpler while developer
| experience getting more complex. A counter argument that
| comes to mind is how violin has the most difficult UI - but a
| lot of people spend lot of time mastering it and enjoy
| creating music from it - often independently or in smaller
| bands. How can that happen with more people in development -
| maybe making developer experience more joyful is the way to
| go. I'm not against specialization - but specialization can
| be done at a small community level too.
| brazzy wrote:
| Early 2000s PHP was a DSL for very simple web apps. So it's no
| surprise it excels at that.
|
| People soon found out that it was _not_ very good at complex web
| apps, though.
|
| These days, there's almost no demand for very simple web apps,
| partially because common use cases are covered by SaaS providers,
| and those with a need and the money for custom web apps have seen
| all the fancy stuff that's possible and want it.
|
| So it's no surprise that today's languages and frameworks are
| more concerned with making complex web apps manageable, and don't
| optimize much (or at all) for the "very simple" case.
| Taikonerd wrote:
| > _People soon found out that it was not very good at complex
| web apps, though._
|
| They eventually made it fit for purpose with Laravel ;-)
| lelanthran wrote:
| > These days, there's almost no demand for very simple web
| apps, partially because common use cases are covered by SaaS
| providers, and those with a need and the money for custom web
| apps have seen all the fancy stuff that's possible and want it.
|
| I dunno about that.
|
| In 2000, one needed a cluster of backends to handle, say, a
| webapp built for 5000 concurrent requests.
|
| In 2025, a single monolith running on a single VM, using a
| single DB on another instance can vertically scale to handle
| 100k concurrent users. Put a load balancer in front of 10
| instances of that monolith and use RO DB followers for RO
| queries, and you can easily handle 10x that load.
|
| > So it's no surprise that today's languages and frameworks are
| more concerned with making complex web apps manageable, and
| don't optimize much (or at all) for the "very simple" case.
|
| Maybe the goal is to make complex web apps manageable, but in
| practice what I see are even very simply webapps being mad with
| those frameworks.
| timw4mail wrote:
| I disagree. I would say most of the migration from PHP was due
| to the appeal of one language for frontend and backend, and
| fashion/hype. PHP is still very usable for server-side
| rendering and APIs. You say "very simple" as if you can't have
| complex systems with PHP.
|
| I see the current state of web development as a spiral of
| complexity with a lot of performance pitfalls. Over-engineering
| seems to be the default.
| brazzy wrote:
| > I would say most of the migration from PHP was due to the
| appeal of one language for frontend and backend
|
| Definitely not. PHP lost far more market share to Java,C# and
| Ruby on Rails than to node.js
|
| > PHP is still very usable for server-side rendering and
| APIs.
|
| Not "is still", but "has become". It has changed _a lot_
| since the PHP 3 days.
|
| > You say "very simple" as if you can't have complex systems
| with PHP.
|
| With early 2000s PHP, you really couldn't, not without
| suffering constantly from the language's inadequacies.
|
| > I see the current state of web development as a spiral of
| complexity with a lot of performance pitfalls. Over-
| engineering seems to be the default.
|
| I don't disagree, but that seems to happen most of all in the
| frontend space.
| throwaway2037 wrote:
| This part really hits home. The first time I got to see a huge
| enterprise C project, I could not believe how simple the code
| was. Few to no tricks. > To be perfectly
| honest, as a teenager I never thought Max was all that great at
| programming. I thought his style was overly-simplistic. I thought
| he just didn't know any better. But 15 years on, I now see that
| the simplicity that I dismissed as naive was actually what made
| his code great.
| jumploops wrote:
| > I now see that the simplicity that I dismissed as naive was
| actually what made his code great.
|
| Simple is robust.
| ajd555 wrote:
| What a great read! And so many good insights! It _almost_ made me
| want to convert a project to PHP - perhaps I will for a smaller
| project.
|
| I love the simplicity and some of the great tools that PHP offers
| out of the box. I do believe that it only works in some cases. I
| use go because I need the error handling, the goroutines and the
| continuously running server to listen for kafka events. But I
| always always try to keep it simple, sometimes preferring a
| longer function than writing a useless abstraction that will only
| add more constraints. This is a great reminder to double my
| efforts when it comes to KISS!
| jerf wrote:
| A few perhaps less obvious lessons:
|
| I think of "straight-line code" as a distinct sort of code. It's
| the sort of code that does a thing, then does the next thing,
| then does the next thing, and if anything fails it basically just
| stops and yields some kind of error because there's nothing else
| to do. Programmers _feel_ like they ought to do something about
| it, like this is bad, but I think there 's actually great value
| in matching the code to the task. Straight-line code is not
| necessarily improved by some sort of heavyweight "command"
| pattern implementation that abstracts it into steps, or bouncing
| around a dozen functions, or through many objects in some other
| pattern. There's a time and a place for that too; for instance,
| if these must be _configured_ that may be superior. But a lot of
| times, if you have a straight-line task, straight-line code is
| truly the best solution. You have to make sure it doesn 't become
| hairy, there are some traps, but there's also a lot of traps in a
| lot of the supposed "fixes", many of them that will actually bite
| you worse.
|
| For many years now I've been banging on the drum that if you've
| been living solely in the dynamic scripting language world for
| over a decade, you might want to look back at static languages to
| put one in your tool belt. When the dynamic scripting languages
| first came out, they would routinely be estimated at using 1/10th
| the lines of static languages, and at the time I would have
| called that a pretty good estimate. However, since then, the gap
| has closed. In 1998, replacing a 233-line PHP script with a
| merely 305-line static-code replacement would have been
| _unthinkable_. And that 's Go, with all its inline error-
| handling; an exception-based, modern static language might have
| been able to effectively match the PHP! Post this in the late 90s
| and people are going to be telling you how amazing it was the
| static code didn't take over 2000 lines. This doesn't represent
| our tools falling behind... this represents a _staggering_
| advance! And also the Go code is going to likely be faster.
| Probably not in a relevant way to this user, but at scale it
| would be highly relevant.
|
| A final observation is that in the early PHP era, _everything_
| worked that way. Everything functioned by being a file that
| represented a program on the disk corresponding to that specific
| path. If you want to get fancy you had a path like "/cgi-
| bin/my.cgi/fake/path/here" and had your "my.cgi" receive the
| remainder of the path as a parameter, and that was a big deal. It
| took the web world more-or-less a decade to get over the idea
| that a URL ought to literally and physically correspond to
| something on the disk. We didn't get rid of that because we all
| hate fun and convenience. We got rid of that because it produces
| a lot of big problems at even a medium scale and it's not a good
| way to structure things in general. It's not something to mourn
| for, it's something we've had better ways of doing now for so
| long that people can forget _why_ they 're the better way.
| nottorp wrote:
| But imgbin is a tiny project with exactly one moving part that
| only interacts with the file system and the user.
|
| When the project becomes more complex, things change for the
| worse.
|
| Also, you need to protect modules not only from errors, but from
| the other programmers in your team.
| leeoniya wrote:
| > You might think that Max's practices make for a maintenance
| nightmare. But I've been "maintaining" it for the last 15 years
| and I haven't found it to be a nightmare.
|
| c'mon, you're talking about 200 LoC here. anything except
| BrainFuck would be maintainable at this scale.
|
| have you ever had to fix a non-trivial third party WordPress
| plugin? the whole API used to be a dumpster fire of global state
| and magic functions. i dont know what it is now, but 15 years ago
| it was a total nightmare.
| cratermoon wrote:
| A couple of hundred lines of code is going always to be easy to
| maintain unless it's purposely written in an obfuscated and
| confusing style. A project with only two maintainers in its
| lifetime isn't going to be subject to the kind of style
| meanderings that muck up a codebase that's gone through dozens of
| maintainers over its lifetime. A couple of thousand lines needs
| some organization, one function of two thousand lines is
| impenetrable.
| et1337 wrote:
| To make it a fair comparison, you also need to consider all the
| old-school Apache and PHP config files required to get that
| beautiful little script working. :) I still have battle scars.
| reactordev wrote:
| Ahh lamp stacks... I remember there was a distro that had
| everything preconfigured for /var/www/ and hardened but for the
| life of me I can't remember its name.
| EvanAnderson wrote:
| A lot of distros did and still do that. Getting an Apache
| instance up and running with PHP running as a CGI process was
| just a matter of installing the right packages on RedHat-
| derived distros going back to the early 2000s, for example.
| reactordev wrote:
| They weren't hardened at all. Installing lamp is one thing,
| ensuring it's secure is another. Even RedHat would send a
| SA to your place to do that for you.
| EvanAnderson wrote:
| Fair enough. I wasn't getting the emphasis on hardening
| in your comment since the parent was just talking about
| the "battle scars" of configuration.
|
| Re: hardening - I guess I deployed a lot of "insecure"
| LAMP-style boxes. My experience, mainly w/ Fedora Core
| and then CentOS, was to turn off all unnecessary
| services, apply security updates, limit inbound and
| outbound connectivity to only the bare minimum necessary
| w/ iptables, make sure only public key auth was
| configured for SSH, and make sure no default passwords or
| accounts were enabled. Depending on the application
| grubbing thru SELinux logs and adjusting labels might be
| necessary. I don't recall what tweaks there were on the
| default Apache or PHP configs, but I'm sure there were
| some (not allowing overrides thru .htaccess files in
| user-writeable directories, making sure PHP error
| messages weren't returned to clients, not allowing
| directory listings in directories without a default
| document, etc).
|
| Everything else was in the application and whatever
| stupidity it had (world-writeable directories in shitty
| PHP apps, etc). That was always case-by-case.
|
| It didn't strike me as a horribly difficult thing to be
| better-than-average in security posture. I'm sure I was
| missing a lot of obvious stuff, in retrospect, but I
| think I had the basics covered.
| reactordev wrote:
| My point was there was a distro circa 1997-2003 or so
| that had all of that pre-baked. No having to mess with
| SELinux (or disabling it!), iptables, php.ini, apache's
| httpd.conf, or any of that other than putting your
| project into /var/www/ and doing a _chown -R www_ on it.
| jimbobimbo wrote:
| You actually don't need to. Just upload this little php script
| to a shared host for $1/mo and call it a day.
| tudorizer wrote:
| The gist of the article is a fun thought experiment.
|
| Why count lines of code? Error handling is nothing to sniff at,
| especially in prod. Imagebin had a small handful of known users.
| Open it up to the world and most the error handling in Go comes
| handy.
|
| For PHP, quite a bit was left on the shoulders of the HTTP server
| (eg. routes). The final result of Go is a binary which includes
| the server. The comparison is not fully fair, unless I'm missing
| something.
| riskable wrote:
| Lines of Code has always been a tertiary indicator at best.
| It's _supposed_ to only be used as a (very) rough indicator
| when you 're trying to figure out the overall complexity of a
| project. As in, "there's 50 million lines of code in Windows."
|
| Knowing a figure like that, you can reason that it's too big
| for a single developer. Therefore, you'll likely need at least
| two; and maybe a few thousand marketing people to sell it.
| the_af wrote:
| I suppose everybody knows this is a riff on "The Story of Mel, a
| Real Programmer" (1983), but I'm posting the link to the classic
| story here just in case:
| https://users.cs.utah.edu/~elb/folklore/mel.html
|
| (Actually, the reworked story in free verse style, which is its
| most popular form)
|
| TFA is cute but it kinda misses the point, because the original
| Mel didn't write code that was simple or easy to understand. It
| was simple _to him_ , and arguably there was some elegance to it
| once you understood it, but unlike the PHP from the updated
| story, Mel's code was machine code, really hard to understand or
| modify, and the design was all in his mind.
|
| Mel would also scoff at PHP.
| marcofloriano wrote:
| "It's so simple that nothing goes wrong."
|
| This. The hardest part of solving a problem is to think about the
| problem and then come up with the right solution. We actually do
| the opposite: we write code and then think about it.
| riskable wrote:
| Speak for yourself! Some of us don't think about the problem at
| all, write the code, then don't think about it afterwards
| either!
|
| This is how "features" get added to most Microsoft products
| these days :thumbsup:
| marcofloriano wrote:
| "And I think that's how it should be. I didn't feel comfortable
| hacking up the code of a Real Programmer."
|
| Ok, i actually cried at this part.
| prewett wrote:
| Perhaps you'd like the original story he's referencing:
| https://foldoc.org/The%20Story%20of%20Mel. (Actually, he's
| referencing the free verse version, but I don't like it as
| much, because it doesn't mention "most pessimum")
| wavemode wrote:
| This is the simple elegance of code whose requirements never
| change.
|
| Lots of software projects don't have this luxury, sadly.
| knowitnone wrote:
| Comparing Go to PHP is like comparing C to Assembly
___________________________________________________________________
(page generated 2025-07-03 23:01 UTC)