The hardest program I've ever written (2015)
38 comments
·October 29, 2025PaulKeeble
About the worst job on any enterprise software project is the PDF output, they always end up doing it for emails or something else and its a never ending list of bugs. Text formatting is a never ending list of problems since its so got a lot of vague inputs and a relatively strict output. Far too many little details go wrong.
kbbgl87
Thinking about phantomjs and rasterize brings back nightmares
vbezhenar
With PDF, my best approach was to go very low level. I've used PDFKit and PDFBox libraries and both provide a way to output vector operations. It allows to implement extremely performant code. The resulting PDF is tiny and looks gorgeous (because it's vector). And you can implement anything. Code will be verbose, but it's worth it.
I even think that it's viable to output PDF without any libraries. I've investigated that format a bit and it doesn't seem too complicated, at least for relatively dumb output.
huflungdung
[dead]
b4ckup
I once wrote a formatter for powerquery that's still in use today. It's a much simpler language and I took a simpler approach. It was a really fun problem to solve.
cjfd
One can talk about about the technical side of writing a code formatter, but what about the ethical side? Automatically formatted code looks kind of okay but never great. Uniformity for the sake of uniformity. It is not a very humanistic.
o11c
There are 3 major problems with automated code formatters:
* Handling of multiple newlines to break sections, or none to group related functions (e.g. a getter with a setter). Sometimes it's even best to move functions around for better grouping.
* They don't factor out an expression into a separate variable.
* They destroy `git blame`. This one is avoided if the tooling has always enforced formatting.
zahlman
> * They don't factor out an expression into a separate variable.
* They implicitly enable people to write deeply nested code that lacks such factoring, without feeling like anything has gone wrong.
dragonwriter
> * They don't factor out an expression into a separate variable.
That's...not formatting, and there's probably no good deterministic rule for when to do that, anyhow.
layer8
Regarding the second one, a formatter shouldn’t be changing the AST. At most inserting parentheses/braces/semicolons for clarity, which doesn’t change the AST structurally (or, depending on one‘s definition of “AST”, doesn’t change it at all).
o11c
Perhaps, but it is absolutely relevant. Most of the horrible formatting results are due to the formatter trying really hard when the user really should introduce a variable.
chaps
This might just be the most HN comment I've ever read.
7thpower
There seem to be a lot of posts that attempt to cast seemingly mundane things through an “ethical” lens and I often wonder what the authors of them must be like in real life.
kjs3
You do not want to get cornered by them at a party talking about their pet peeve.
null
mjsir911
yeah, I've come to terms that I mostly do programming-as-an-art and that includes how my code is structured, and I'm on exactly the same page.
In pragmatic business environments it's not worth the fuss but I never feel great about anything I make in those kinds of environments anyways, and I always appreciate being able to shine when there's no enforced code formatting.
jbreckmckye
I agree, actually. Humans are visual creatures and they take cues from the visual design of program code: alignment, grouping, density. All these things are used to signify meaning in product design, including digital design. But we are not allowed to "design" source code.
nkrisc
What is the ethical dilemma presented?
kjs3
The one they invented to justify hating coding standards.
vbezhenar
The human might use a carefully selected mix of tabs and spaces to output a picture. And formatter will destroy it, thus destroying artist expression.
Compare:
#define/**/Q(x,y)r;char*q/* */=y#x","#y")",*p,x=*p%67;}
/*-IOCCC2020-*/#include/* */<stdio.h>/*-BBQlock--*/
int(y),x,i,k,Q(s[9<<9/* 12 */];float(f)[3];void(Z)
(){*f=r<0?r:-r;f[1]/* 11 1 */=42.5;f[2]=22.5;for
(k=0;++k<39;*f/=(k/* 10 2 */%2?k:-k)*6875.5/i)
y=f[1+k%2]+=*f;k=/* */f[2];p=s+k/2*86+y
;}int(main)(){p=/* 9 o-------> 3 */s;for(;i<1978;*q
>32?k=i++/86-11/* / */,y=(750>r*r+k*k
*4)*4+y/2,*p++=/* 8 L 4 */r<44?y?"+0X+0X"
"+!"[y]-1:*q++/* 7 5 */:10:*q++)r=-41
+i%86;r=20;for/* 6 */(x=13;(i=3600*
--x);*p++="XR"/* */"MOQSUWAY"[x%+
10]-9,*p+=x/10/* */*41)Z();sscanf
(__TIME__,"%d"/* \ / -------+ */":%d:%d",&k,&x
,&i);r=10;for(i/* \ / ------ | */+=(k*60+x)*60;r
+18;*p=k%2?*p%2/* \ / ------ | */?59:44:*p>39?59
:39,i=r--?i:i%(+/* \ / ------ | */3600)*12)Z();for
(p=s;*p;putchar(k/* X ------ | */%2&&k<14?q="End",
printf("%c%c",224|/* __/ \__ | | */(21554>>k&3),"gCS"
"gGMX"[k/2]+65),"E"/* / \ / \ | | */"Gh_BrG"[k/2]+64:*p
),++p)k,"#define/**/"/* \__/ \__/ +--+ */"Q(x,y)r;cha""r*q=y#"
"x\",\"#y\")\",*p,x=*p"/* */"%67;}/*-IOCCC2020-*/#"
"include<stdio.h>/*-BBQl"/* */"ock--*/int(y),x,i,k,Q(")
and clang-formatted version: #define /**/ Q(x, y) \
r; \
char *q /* */ = y #x "," #y ")", *p, x = *p % 67; \
}
/*-IOCCC2020-*/ #include /* */<stdio.h> /*-BBQlock--*/
int(y),x,i,k,Q(s[9<<9/* 12 */];float(f)[3];void(Z)
(){
*f = r < 0 ? r : -r;
f[1] /* 11 1 */ = 42.5;
f[2] = 22.5;
for (k = 0; ++k < 39;
*f /= (k /* 10 2 */ % 2 ? k : -k) * 6875.5 / i)
y = f[1 + k % 2] += *f;
k = /* */ f[2];
p = s + k / 2 * 86 + y;}int(main)(){
p = /* 9 o-------> 3 */ s;
for (; i < 1978; *q > 32 ? k = i++ / 86 - 11 /* / */,
y = (750 > r * r + k * k * 4) * 4 + y / 2,
*p++ = /* 8 L 4 */ r < 44
? y ? "+0X+0X"
"+!"[y] -
1
: *q++ /* 7 5 */
: 10
: *q++)
r = -41 + i % 86;
r = 20;for/* 6 */(x=13;(i=3600*
--x);*p++="XR"/* */"MOQSUWAY"[x%+
10]-9,*p+=x/10/* */*41)
Z();
sscanf(__TIME__, "%d" /* \ / -------+ */ ":%d:%d", &k, &x, &i);
r = 10;
for (i /* \ / ------ | */ += (k * 60 + x) * 60; r + 18;
*p = k % 2 ? *p % 2 /* \ / ------ | */ ? 59 : 44
: *p > 39 ? 59
: 39,
i = r-- ? i : i % (+/* \ / ------ | */ 3600) * 12)
Z();
for (p = s; *p;
putchar(k /* X ------ | */ % 2 &&k < 14
? q = "End",
printf("%c%c",
224 | /* __/ \__ | | */ (21554 >> k & 3),
"gCS"
"gGMX"[k / 2] +
65),
"E" /* / \ / \ | | */ "Gh_BrG"[k / 2] + 64 : *p),
++p)k,"#define/**/"/* \__/ \__/ +--+ */"Q(x,y)r;cha""r*q=y#"
"x\",\"#y\")\",*p,x=*p"/* */"%67;}/*-IOCCC2020-*/#"
"include<stdio.h>/*-BBQl"/* */"ock--*/int(y),x,i,k,Q(")
The beauty is gone!andrewflnr
"Ethics" is overdramatizing it. The goal of a code formatter is not greatness, but adequacy, in a context where the code is a means to an end. They're particularly used in contexts where you may be sharing the project with people who don't care about formatting at all. Forcing me to work in or clean up the messes of my lazy co-workers is also, I would suggest, not very humanistic.
Feel free to not use one in your art projects.
mackeye
semantic code style varies plenty between people; i can often tell who wrote which code, among the members of my research group, even though we format our code. i'd prefer to be recognized by my preference for short lambdas (vs. defs) and partial functions, than my preference to put if statements on one line.
dredmorbius
Ethical, or aesthetic?
Both are branches of philosophy, but rather distinct from one another.
mmaunder
Is solving formatting made easier with the use of LLMs?
jibal
No.
mmaunder
A downvote and curt response. Seems I've touched a nerve. Which makes sense, since what I'm asking is if this high effort craftsmanship is potentially being, or has been replaced by LLM's. It seems both a shame and disrespectful if that has occurred. Perhaps it is better to live in denial.
Maxatar
I'll just speak for myself, but I use Copilot with Visual Studio and C++ and Copilot does an excellent job of interpreting the instructions given to it and ensuring that the code I write is consistent with the coding style and standards specified in the instructions.
I have it set to check my code live, as I write it, and it will reformat my code on the fly to break lines up, fix typos, insert code snippets, autocomplete documentation, etc...
I will admit it was very awkward using it at first and I actually kind of hated it because it felt so intrusive, like having it modify code as I write it felt really distracting at first, but after maybe 2-3 days of doing it I got used to it and now I feel a lot more productive having it there. Especially for a language like C++ where sometimes the most menial syntax issue can have significant and hard to track down consequences, it's nice to have an LLM that can focus on these menial details while I focus on the higher level task.
jibal
https://news.ycombinator.com/newsguidelines.html
"Please don't comment about the voting on comments. It never does any good, and it makes boring reading."
Other elements also apply.
kjs3
No...it's that "can an LLM do it better" with no other commentary is perhaps the absolute lowest effort, lowest value comment possible on HN these days and mercifully gets an appropriate downvote. The condescending response to downvote is also par for the course from a particular sort of reader.
> That handful of code took me almost a year to write.
Formatting can be tough. See Knuth's extensive bug list for TEX from 1987 at https://yurichev.com/mirrors/knuth1989.pdf to see the kind of tarpit one can get trapped in.