HNHacker News
TopNewBestAskShowJobs

spc476

3,329 karma · joined July 9, 2008

blog: http://boston.conman.org email: sean@conman.org
submissionscomments
spc476··on Vibe engineering
And in my experience, it always comes down to "you're holding it wrong" or "that LLM is older than 20 minutes."
spc476··on Why I chose Lua for this blog
XSL is neat, and it is a functional language, but between XSL and XPath, it is quite verbose. Here's a small section of XSL I use to generate my website (not my blog):

    <xsl:choose>
    
      <!-- ... other code -->
      
      <xsl:when test="name(.) = 'subsection'">
        <xsl:choose>
          <xsl:when test="not(boolean(ancestor-or-self::*/@next)) or ancestor-or-self::*/@next != 'rev'">
            <xsl:if test="boolean(following-sibling::subsection[@listindex != 'no']/attribute::directory)">
              <link rel="next"  href="../{following-sibling::subsection[@listindex != 'no']/attribute::directory}" title="{following-sibling::subsection[@listindex != 'no']/child::title}"/>
            </xsl:if>
            <xsl:if test="boolean(preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory)">
              <link rel="prev"  href="../{preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory}" title="{preceding-sibling::subsection[@listindex != 'no'][position()=1]/child::title}"/>
            </xsl:if>
            <link rel="first" href="../{../subsection[@listindex != 'no'][position()=1]/@directory}" title="{../subsection[@listindex != 'no'][position()=1]/title}"/>
            <link rel="last"  href="../{../subsection[@listindex != 'no'][position()=last()]/@directory}" title="{../subsection[@listindex != 'no'][position()=last()]/title}"/>
          </xsl:when>
   
          <xsl:otherwise>
            <xsl:if test="boolean(preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory)">
              <link rel="next" href="../{preceding-sibling::subsection[@listindex != 'no'][position()=1]/attribute::directory}" title="{preceding-sibling::subsection[@listindex != 'no'][position()=1]/child::title}"/>
            </xsl:if>
            <xsl:if test="boolean(following-sibling::subsection[@listindex != 'no']/attribute::directory)">
              <link rel="prev" href="../{following-sibling::subsection[@listindex != 'no']/attribute::directory}" title="{following-sibling::subsection[@listindex != 'no']/child::title}"/>
            </xsl:if>
            <link rel="first" href="../{../subsection[@listindex != 'no'][position()=last()]/@directory}" title="{../subsection[@listindex != 'no'][position()=last()]/title}"/>
            <link rel="last"  href="../{../subsection[@listindex != 'no'][position()=1]/@directory}" title="{../subsection[@listindex != 'no'][position()=1]/title}"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:when>

      <!-- ... other code ... -->
    </xsl:choose>
And yes, there is other code I've omitted for brevity. This is used to generate the navigation links for the site. I initially write this ... prior to 2009 (that's when I moved it into git). There have been some minor fixes to the XSL over the years, but it's largely unchanged (for a reason that I hope is obvious). Yes, I still use it, because it still works, and it's for a static website.
spc476··on Things you can do with a debugger but not with print debugging
The hardest bug I had to track down took over a month, and a debugger wouldn't have helped one bit.

On the development system, the program would only crash, under a heavy load, on the order of hours (like over 12 hours, sometimes over 24 hours). On the production system, on the order of minutes (usually less than a hour). But never immediately. The program itself was a single process, no threads what-so-ever. Core dumps were useless as they were inconsistent (the crash was never in the same place twice).

I do think that valgrind (had I known about it at the time) would have found it ... maybe. It might have caught the memory corruption, but not the actual root cause of the memory corruption. The root cause was a signal handler (so my "non-threaded code" was technically, "threaded code") calling non-async-safe functions, such as malloc() (not directly, but in code called by the signal handler). Tough lesson I haven't forgotten.

spc476··on Where's the shovelware? Why AI coding claims don't add up
Let me guess ... they're holding it wrong, and the model they're using is older than 20 minutes.
spc476··on Why did books start being divided into chapters? A new history
By using the web? https://bible.conman.org/kj/Matthew.25:40
spc476··on Speed-coding for the 6502 – a simple example
If you read the entire article, they do that at the end of the article.
spc476··on FCC bars providers for non-compliance with robocall protections
Only if your phone supports it. Not all do.
spc476··on FCC bars providers for non-compliance with robocall protections
Set a default ringtone to silence. Give each contact on my phone a custom non-silent ringtone. If a non-contact calls and it's important enough, they'll leave a voice message. The first year or so some spammers would leave a message (usually half a message as my outgoing message caused their canned robot to start speaking), but the past year or so, no bad voice mail messages.
spc476··on Ban me at the IP level if you don't like me
I used CYMRU <https://www.team-cymru.com/ip-asn-mapping> to do the mapping for the post.
spc476··on Privately-Owned Rail Cars
A decade ago a friend of mine rented a private rail car (for cost---he knows the owner) for a family trip/birthday present, and I got to ride on it for a few hours as it was being positioned (https://boston.conman.org/2015/08/05.4). I didn't get a price from him, but it was clear it was pretty much the cost of a new car. The car he was renting came with a lounge, three state rooms, bathroom, dining room, kitchen and two crew members (cook and porter, with their own sleeping quarters).

Their trip was from Miami to Chicago back to Jacksonville (where the car is stored---I rode on it from central Florida to Boca Raton as it was being positioned prior to the start of the family trip; because it was running late, I didn't get a chance to eat lunch on it, sigh) over the course of a week or so. If I could, this is how I would travel, but of course, this being the US, it's not really a viable means of transportation.

spc476··on Checklists are hard, but still a good thing
I did this at a previous job for running a complicated regression test (that couldn't be fully automated for reasons). I initially did this for myself as the regression test wasn't run that often. I also made sure that anyone new to the department would have to run the regression test and report/update with any missing steps.
spc476··on Six Years of Gemini
The author very much did allow others to give input. The original protocol had single digit status codes, I was arguing for three digit codes, he compromised with two digit codes. It was my idea to include the full URL for requests, and for redirections. It's just that it wasn't easy, but he could be reasoned with. The only two hard lines Solderpunk had for the protocol was TLS, and single level lists (why, I don't know).
spc476··on Most ints are not floats
You could store the address of the offending instruction/code sequence that generated the NaN (think software-only implementation).
spc476··on Parameterized types in C using the new tag compatibility rule
So maybe you can answer the following question I have: what is a "protected abstract virtual base pure virtual private destructor," and when was the last time you needed one?" At least with C, I understand the feature set and how they interact.
spc476··on Posit floating point numbers: thin triangles and other tricks (2019)
IEEE does define x/0 to be infinity and -x/0 as -infinity. But what about 0/0? Or sqrt(-1)?
spc476··on Implementing DOES> in Forth, the entire reason I started this mess
It only briefly goes into what it does, this article goes into how it's done for a particular implementation.
spc476··on Machine Code Isn't Scary
Learning the accordion didn't hurt Weird Al's career, nor did using the flute hurt Ian Anderson (lead vocalist and flutist of Jethro Tull).
spc476··on How Monty Python and the Holy Grail became a comedy legend
But then the interviewer will be launched into the Pit of Eternal Peril.
spc476··on Education Secretary Wants 'A1' in Classrooms
Wait! I thought President Trump was getting ride of the Department of Education. How is there still an Education Secretary?
spc476··on Building the System/360 Mainframe Nearly Destroyed IBM
The Motorola 68000, introduced in 1979, had 24 address lines. The Intel 80286, introduced in 1982, also had 24 address lines.
spc476··on In the 1980s we also downloaded software from TV
Here's a recent attempt to load code via video recordings of a TV show from the 80s. It wasn't an easy task. From the Youtube channel Retro Recipies:

Decoding A Program Sent From The Past: https://www.youtube.com/watch?v=MezkfYTN6EQ

Did We Decode A Program Sent From The Past?: https://www.youtube.com/watch?v=VRcs_TUpQ6g

ACTUALLY Receiving A Program Sent From The Past!:https://www.youtube.com/watch?v=jm0EACgCbM0&t=1203s

spc476··on Show HN: The C3 programming language (C alternative language)
For adapting code to different versions of libraries for one thing:

    #if defined(__SunOS)
        presult = getprotobyname_r(proto,&result,tmp,sizeof(tmp));
        if (presult == NULL)
          return luaL_error(L,"protocol: %s",strerror(errno));
    #elif defined(__linux__)
        if (getprotobyname_r(proto,&result,tmp,sizeof(tmp),&presult) != 0)
          return luaL_error(L,"protocol: %s",strerror(errno));
    #else
        presult = getprotobyname(proto);
        if (presult == NULL)
          return luaL_error(L,"protocol: %s",strerror(errno));
        result = *presult;
    #endif
The sometimes annoyingly small differences between platforms.
spc476··on Why is this site built with C
Sure. Here's viola, a web browser from the early 90s, with a replacement makefile (GNU make) that's a bit more sane:

    CC      = gcc -std=c99 -Wall -Wextra -pedantic
    CFLAGS  = -g
    LDFLAGS = -g
    LDLIBS  = -L/usr/X11R6/lib -lICE -lSM -lXpm -lX11 -lXext -lXmu -lXt -lm

    VIOLA_PATH := $(shell pwd)/resources

    override CFLAGS += -DPOSIX_C_SOURCE=199309L         \
                    -D_POSIX_SOURCE -D_XOPEN_SOURCE     \
                    -D_BSD_SOURCE -D_SVID_SOURCE        \
                    -DDEFAULT_VIOLA_PATH='"$(VIOLA_PATH)"'\
                    -DVIOLA

    %.a:
            $(AR) $(ARFLAGS) $@ $?

    viola/viola: $(patsubst %.c,%.o,$(wildcard viola/*.c)) \
                    libIMG/libIMG.a     \
                    libXPA/src/libxpa.a \
                    libStyle/libStyle.a \
                    libWWW/libWWW.a     \
                    parmcheck.o

    libIMG/libIMG.a     : $(patsubst %.c,%.o,$(wildcard libIMG/*.c))
    libXPA/src/libxpa.a : $(patsubst %.c,%.o,$(wildcard libXPA/src/*.c))
    libStyle/libStyle.a : $(patsubst %.c,%.o,$(wildcard libStyle/*.c))
    libWWW/libWWW.a     : $(patsubst %.c,%.o,$(wildcard libWWW/*.c))

It's 155,000 lines of C code across 361 files. Not shown are the nearly 900 lines that make up the dependencies, but using `makedepend` (which came with my system) makes short work of that. I have a more complicated project that compiles an application written in Lua into a Linux executable. It wasn't hard to write, given that you can always add new rules to `make`, such as converting a `.lua` file to a `.o` file:

    %.o : %.lua
            $(BIN2C) $(B2CFLAGS) -o $*.l.c $<
            $(CC) $(CFLAGS) -c -o $@ $*.l.c
            $(RM) $*.l.c
Okay, that requires a custom tool (`bin2c`) but can other build systems do this? I honestly don't know.
spc476··on The Lost Art of Logarithms
There is Mathematics for the Million by Lancelot Hogben, which not only covers math, but the history of math and why it was developed over the centuries. It starts with numbers, then geometry, arithmetic, trig, algebra, logarithms and calculus, in that order. It's a very cool book.
spc476··on War Rooms vs. Deep Investigations
Unless "platform engineers" includes "deveopers", they're not the only ones who can diagnose an issue. Once at my previous job (providing a name based on a phone number to the Oligarchic Cell Phone companies), our service just stopped. I wasn't there during the outage, only heard about it after the fact. The servers were fine (they were not out of memory, nor did they have an outrageous load). The network was fine. The program just wasn't serving up data. There had been no recent updates to the code [1] so it shouldn't have been the software. It took the main developer, who knew the code, to know that a "this should not happen" situation, did---that is, the name query we used for a health check had been removed, and thus our software took that to mean the name service was out of commission, thus shutting down.

Now, it could be argued that was the wrong thing for our software to do, but it was what it was, and no amount of SREs or "platform engineers" would have solved the issue (in my opinion).

[1] The Oligarchic Cell Phone companies do not move fast, and they had veto power over any updates to production.

spc476··on Software development topics I've changed my mind on
If I didn't want to have opinions, I would join a cult.
spc476··on Software development topics I've changed my mind on
At $PREVIOUS_JOB, the team I was on worked the best when we had no manager. Or rather, we had a director (who should not have been managing us directly) meet with us once a week to tell us "here's what we're headed ... good?" and let us go work in quiet until the next meeting (or meet with us sooner if something really important cropped up).
spc476··on Advice for a friend who wants to start a blog
The non-blog parts of my site [1] are in XML and I use xsltproc to generate HTML. It's technically a static-site generator. It works, but my God, is XSLT a verbose (functional) language.

[1] https://www.conman.org/

spc476··on Advice for a friend who wants to start a blog
I started writing my blogging engine [1] in late 1999, and spent almost the next two years trying to get it perfect, while at the same time using it for blogging (locally at first). I finally got fed up with trying to perfect the software and just went public with it. I still use it after 25 years. Granted, there hasn't been a line of code that hasn't changed in that time, but it still feels the same to me, as it still works the same from a user perspective (entries can be added via a web interface, email, file (that was true even 25 years ago) and the PUT method (added last year); the storage system hasn't changed either and is backward compatible such that the code in 2001 (when I first went public) could still work on the data today). And yes, it is still a CGI script. I saw no need to change that over the years.

[1] https://github.com/spc476/mod_blog

spc476··on Morse Code in Tubular Bells (2021)
And it's only the first minute or so of the album was used in the movie. In context the entire track (all 25m30s of it) is not scary at all. Clever use of editing.
← PreviousPage 2 of 34Next →