MacBook, defective by design banner

title:
Put the knife down and take a green herb, dude.


descrip:

One feller's views on the state of everyday computer science & its application (and now, OTHER STUFF) who isn't rich enough to shell out for www.myfreakinfirst-andlast-name.com

Using 89% of the same design the blog had in 2001.

FOR ENTERTAINMENT PURPOSES ONLY!!!
Back-up your data and, when you bike, always wear white.

As an Amazon Associate, I earn from qualifying purchases. Affiliate links in green.

x

MarkUpDown is the best Markdown editor for professionals on Windows 10.

It includes two-pane live preview, in-app uploads to imgur for image hosting, and MultiMarkdown table support.

Features you won't find anywhere else include...

You've wasted more than $15 of your time looking for a great Markdown editor.

Stop looking. MarkUpDown is the app you're looking for.

Learn more or head over to the 'Store now!

Thursday, April 30, 2026

Claude Sonnet 4.6 is so much better than GPT-5 mini that I figured I'd look up how much it'd cost to swap. Right now, for $10 a month, GitHub Copilot will let you use GPT-5 mini forever, no limit. Sonnet, however, was sucking down my monthly allocation of "premium requests" so fast (it's the end of the month, so I usually splurge on the model) I was scared to look at what it'd cost.

Well be even more scared. Come June 1st, everyone gets to pay no matter which model you use. No more infinite GPT mini. And Sonnet's multiplier is jumping from 1x to 9x!!

Look, there's also something on the page about going "from request-based billing to usage-based billing". I don't think this model multiplier multiplier [sic] is effected by that distinction, however. Maybe? I think it's the same charges as now, just 9x as quick. Looks like I get 300 credits now and could get five times as many for $40. That's still not much, and I just use Copilot to pair program sometimes. Well, daily, but not agentic. Five times more and nine times as fast equals lots more than $40 a month.

I'd predicted prices for AI assisted coding would go waaaaay up soon. Well, I was right, though now, wondering how long this page about charges changing has existed, I might should've know a month ago it wasn't really a prediction.


Starting April 20, 2026, new sign-ups for Copilot Pro, Copilot Pro+, and student plans are temporarily paused.

Oh. Oh wow. We're in trouble.

Labels: , , ,


posted by Jalindrine at 4/30/2026 11:58:00 AM
Monday, May 26, 2025

Sometimes, I surprise myself:

@Cthutu I wish "It's like the difference of [declaring] an address vsย [commanding] directions. The address is useful no matter you are. Whereas directions are invalid if you start somewhere else," was the selected answer all by itself.ย ;^)ย 

Labels: ,


posted by Jalindrine at 5/26/2025 03:32:00 PM
Saturday, May 17, 2025

From Hacker News' Malicious npm Packages Infect 3,200+ Cursor Users With Backdoor, Steal Credentials:

Cybersecurity researchers have flagged three malicious npm packages that are designed to target the Apple macOS version of Cursor, a popular artificial intelligence (AI)-powered source code editor.

"Disguised as developer tools offering 'the cheapest Cursor API,' these packages steal user credentials, fetch an encrypted payload from threat actor-controlled infrastructure, overwrite Cursor's main.js file, and disable auto-updates to maintain persistence," Socket researcher Kirill Boychenko said.

...

"The threat actor's use of the tagline 'the cheapest Cursor API' likely targets this group, luring users with the promise of discounted access while quietly deploying a backdoor," [Socket researcher Kirill Boychenko] added.

None of this is amazing or rocket science, which is exactly why it's important. It's not hard to social engineer humans.

It does make me wonder about the almost unthinking preference devs can have for "[I don't care if it's] NIH". Not that it started with npm. Using brew on macOS or apt-get on Linux are essentially the same thing, but literally anything that auto-updates can be an attack vector.

But if you want to reduce your proverbial footprint, there are ways. Knowing open-source libraries you use well enough to have contributed is one. Not writing an in-house version of something insanely trivial is another.

And, as much as Apple's getting slammed for arguing for its own nanny state right now, using IDEs from fairly reputable sources and not believing deals that are proverbially too good to be true are all probably decent ideas too.

I do wonder about, say, browser extensions. I have one from the EFF on one box that I haven't looked into for a while -- is it still be updated? What do adblock extensions really do? Luckily these are all in JavaScript so, even if obfuscated, you can still sniff through most of them fairly easily. Somebody should know, eventually, if the most popular get wacky. Right?

Though heaven help me if the right vim plugins for IDEs get compromised. I'm toast. (Told ya it was easy.)

Labels: , ,


posted by ruffin at 5/17/2025 02:08:00 PM
Friday, May 03, 2024

This SO comment links to the best demonstration of off-by-one errors for laypeople I think I've ever run into.

(Though, admittedly, the "coming second" and "coming first" terminology was new to me...)

Here's the video that comment linked to:

Labels: , ,


posted by ruffin at 5/03/2024 10:08:00 AM
Monday, December 18, 2023

Amazingly accurate comic from xkcd is amazingly accurate:

Some day I'll blog about the time a lib maintainer deciding to [literally] say [well, "post"] "Ho hum" about just such a dependency temporarily crashed a reasonably large company's deployment script, but that day is not today.

(Luckily it was reasonably easy to fix, but it certainly cemented my usual claim that, "If you adopt a third-party dependency, you should also be routinely submitting pull requests to it.")

Labels: , ,


posted by ruffin at 12/18/2023 09:54:00 PM
Friday, June 16, 2023

Implementing a graceful TypeScript is hard.

In theory, theory and practice are the same. In practice, they're different.

(Nothing major there, but something as simple as iterating over keys & and their values can be a challenge to do elegantly.)

Labels: ,


posted by ruffin at 6/16/2023 08:29:00 PM
Wednesday, January 11, 2023

Remember when I said this?

but if I want something quick that can run anywhere [someone's on Windows], I use a batch file, and over the years, kinda like VIm, I've slowly become if not proficient then at least competent.

What a naรฏve time that was.


Take this seemingly innocuous question on SO:

How can you you insert a newline from your batch file output?

And then check this answer:

Here you go, create a .bat file with the following in it :

@echo off
REM Creating a Newline variable (the two blank lines are required!)
set NLM=^


set NL=^^^%NLM%%NLM%^%NLM%%NLM%
REM Example Usage:
echo There should be a newline%NL%inserted here.

echo.
pause

Wha? set NL=^^^%NLM%%NLM%^%NLM%%NLM%??? What in the world? Huh?

Luckily (?) one of the commenters asked the same question.

Here's part of the answer:

The caret is an escape character for the next character, or at the line end it is used as multiline character, but this is nearly the same.

At the line end it simply escapes the next character, in this case theย <Linefeed>, but there is a hidden feature, so if the escaped character is aย <LF>ย it is ignored and the next character is read and escaped, but this charater will be always escaped, even if it is also aย <LF>.

...

So you need to add an escaped linefeed into the line and that is the NL-Variable. The NL-Variable consists of only three characters.
NL=^<LF><LF>ย And if this is expanded, it creates only one escapedย <LF>ย as the firstย <LF>ย after the caret will be ignored.

I mean, um, that requires Inception level cognition to understand. ๐Ÿ˜ (Okay, actually it's pretty straightforward, but talk about a lack of discoverability.)

What's even more interesting is that dev's answer to the original question, which is this:

Like the answer of Ken, but with the use of the delayed expansion.

setlocal EnableDelayedExpansion
(set \n=^
%=Do not remove this line=%
)

echo Line1!\n!Line2
echo Works also with quotes "!\n!line2"

Aside

Okay, before I point out what I want to point out, note that %=_____=% is an inline comment format for batch.

From ss64.com, a common domain when I'm in batchland:

Batch variableย namesย can contain spaces and punctuation, we can take advantage of this fact by typing our comment as a non-existent variable. Because it doesnโ€™t exist, this variable will expand to nothing and so will have no effect when the script is run.

n.b. This only works in batch files, not directly at the command prompt.

To be sure that we donโ€™t accidently choose a name which is in fact a real variable, start and end the comment with "="

@Echo off
Echo This is an example of an %= Inline Comment =% in the middle of a line.

(Variable names starting with "=" are reserved for undocumented dynamicย variables. Those dynamic variables never end with "=", so by using an "=" at both the start and end of our comment, there isย noย possibility of a name clash.)


And we're back

Okay, now what I'd like to point out here is the setlocal EnableDelayedExpansion, something I think I had to use recently in a script I wrote. It's a bizarre new world.

Here's some explanation from ss64.com:

EnableDelayedExpansion

Delayed Expansion will cause variables within a batch file to be expanded at execution time rather than at parse time[;] this option is turned on with the SETLOCAL EnableDelayedExpansionย command.

Variable expansion means replacing a variable (e.g.ย %windir%)ย with its valueย C:\WINDOWS

  • By default expansion will happen just once, before each line is executed.
    In this case, a "line" includes bracketed expressions even if they are formatted to run over several lines.

  • Whenย !delayed!ย expansion is turned on, the variables will be expanded each time the line is executed, or for each loop in a FOR looping command.

And here's a decent example from that page showing how it works in practice.

@echo off
SETLOCALย EnableDelayedExpansion
Set "_var=first"
Set "_var=second"ย & Echo %_var% !_var!

The output is

first second

Note that the above example has to be in a batch file to work properly.

Anyhow, it's an insane rabbit hole that I didn't schedule for this sprint and fell into anyhow. I'm going to cut my losses now that I've warned others who may have been as naรฏve about batch scripts as I was, oh so long (less than three weeks ๐Ÿ˜‰) ago.


Oh good heavens. I guess this makes sense. The first example can be taken by itself as a brain teaser, I think.

From ss64.com, again on EnableDelayedExpansion:

@echo off
Setlocal
Set _html=Hello^>World
Echo %_html%

In the above, the Echo command will create a text file called 'world' - not quite what we wanted!

Got that figured out? If not, sit and think about it for a second before reading more.

Got it? Good. Clever, huh?

This is because the variable is expanded at parse time, so the last line is executing Echo Hello > World and the > character is interpreted as a redirection operator.

If we now try the same thing with EnableDelayedExpansion:

Setlocal EnableDelayedExpansion
Set _html=Hello^>World
Echo !_html!

With delayed expansion, the variable (including the > ) is only expanded at execution time so the > character is never interpreted as a redirection operator.

This makes it possible to work with HTML and XML formatted strings in a variable.

Labels: , , ,


posted by ruffin at 1/11/2023 12:27:00 PM
Wednesday, December 21, 2022

Usually, the holidays are some of my most productive days developing. There's no overhead. So many fewer people around means fewer meetings, fewer obstacles, fewer interruptions.

Now admittedly part of this is because I can usually pick what I want to do over the holidays, and I'll pick things that don't require a lot of feedback or things that take a really heavy mental lift to complete. That is, I pick things to do over the holidays that require a holiday environment to do well. Win-win.

And this week or two of mostly heads-down time is usually incredibly enjoyable. I take a few days off, sure, but going to work when everyone else is away is a vacation -- of a sort -- in itself. This is not [simply] the anti-social position: Long swathes of time uninterrupted is where development gets done.

But this year is starting to make clear for me that there's a holiday anti-pattern here with remote work: When the family is home, they don't give a rat's behind about minimizing interruptions. 

Now, holidays are the worst time to get things done. I'm holed up in the home office, no chance to walk around and clear my head thinking seriously about an issue I need to consider. Folks tromp near or even through the office without any regard for work going on. Dishwashers, loud pipes, clothes washers, winter cleaning, food prep -- everything's much louder than you'd have at an in-person office even during non-holidays times. 

It's not surprising, and it's essentially ontological, but there's simply no professionalism at home when everyone but you is on break. It makes you appreciate office design a heck of a lot more -- bathrooms away from desks, kitchen areas behind reasonably thick walls...

Ugh. Sad first-world problem rant over. I leave you with this (printable):

I don't blame them, but it does harsh my working holiday. Might have to actually take some days off this year. ;^)

Labels: , ,


posted by ruffin at 12/21/2022 10:42:00 AM
Friday, December 09, 2022

From Ben Thompson's stratechery (hat tip to Dave Verwer at iOS Dev Weekely):

It happened to be Wednesday night when my daughter, in the midst of preparing for โ€œThe Trial of Napoleonโ€ for her European history class, asked for help in her role as Thomas Hobbes, witness for the defense. I put the question to ChatGPT, which had just been announced by OpenAI a few hours earlier:

[The chatbot's answer to "Did Thomas Hobbes believe in separation of powers" removed]...

This is a confident answer, complete with supporting evidence and a citation to Hobbes work, and it is completely wrong. Hobbes was a proponent of absolutism, the belief that the only workable alternative to anarchy โ€” the natural state of human affairs โ€” was to vest absolute power in a monarch; checks and balances was the argument put forth by Hobbesโ€™ younger contemporary John Locke, who believed that power should be split between an executive and legislative branch. James Madison, while writing the U.S. Constitution, adopted an evolved proposal from Charles Montesquieu that added a judicial branch as a check on the other two.

Good timing, Dave and Ben. I'd just seen StackOverflow's header chyron say they don't allow ChatGPT answers, which, if you understand society's use of language well, means...

We almost accept ChatGPT style answers, but not yet, dang it! But you know we're close because it's not so obvious we don't have to say it.

It's the door handle that says "Push" because it looks like a pull. That is, the StackOverflow warning tells us that AI answers are so convincing at this point you'd naturally assume those answers are okay to post [for internet points! Points!]. You have to be told to push the door to open. It looks like a pull.

door with handles towards you saying push

And that, of course, got me googling, and seeing that AI is finally getting close enough to what we thought the Eliza chatbot was nearly doing years ago.

As Dave mentions:

I remember chatting with Kim Silverman in the WWDC labs in 2008 about speech synthesis and recognition. He talked about the early days of speech synthesis in the late 1970s and how developers quickly progressed to 90% of the way there and then spent the next 30 years getting to 95%.

We really have been at 90% for a while. But now AI is at 90% for news stories and apparently close enough to start wondering when it'll come for us coders, too.

I'm far enough into my career that if it was at 100% tomorrow I would take the pink slip and relax at home, watching some chatbot do my job for me. Realizing I'm still biased, however, I was suspicious of my first take:

There's no way the code is going to be good at first. It'll need PRs like crazy for years.

My job has, for the last several years, becoming increasingly concentrated on PRs. I think it's mostly about tooling and scrum culture. Tooling makes PRing not just possible but easy now. We can all drop comments on specific parts of code, create PRs to PRs to show how we might do something small differently, and swap branches without having to reset our setup to run them.

Scrum culture says we need self-contained but non-specialist teams (give or take) which means we're all expected to have an opinion on someone else's code. It's a full stack developer's world today in a way it wasn't so much in 2000. I could digress for a while on bikeshedding, but, with a high-functioning team, that's mostly good.

But when the AIs start crapping out code like a new dev, good heavens, can you imagine? We'll need to train these things for a while. Maybe they'll get good enough that they take to the training really quickly, but -- and not just because of anecdotes like Thompson's post, above -- I think we've got a few more years of heavy PR work before that happens.

Labels: , , ,


posted by ruffin at 12/09/2022 07:41:00 PM
Thursday, July 14, 2022

fast-glob vs globby vs minimatch vs node-glob at npm trends:




Why did globby & fast-glob crash this year? Why is minimatch going bonkers?

I mean, the answers to each question are in the other question, but that doesn't really tell us why. Why are both happening?

I picked minimatch for a node project recently without doing much research -- I'm in "mvp mode" -- and it seems... fine. But more recently I've started trying to figure out how different each package is, one from another, and there's nothing about minimatch that seemed obviously superior. 

Guess it's like language. Not always easy to know why one turn of phrase beats out another, but once it does, it's like wildfire.

EDIT: Here are some sites that explain glob format. I think I found a few of them interesting earlier. (It's another browser tab clean-up day.)

Labels: , , ,


posted by ruffin at 7/14/2022 04:01:00 PM
Monday, July 04, 2022

From today's post to Baldur Bjarnason's blog:

We might have a project that has a limited budget and resources but also a user-base that isn’t demanding the Single-Page-App ‘experience’. In which case, the logical approach is to make a multi-page web service instead of a Single Page App. It’ll cost less both in the short term and the long term. And you’re much more likely to be able to deliver it on time.

But you almost never get to do that these days because only a Single-Page-App is a ‘proper’ website. An intimation that it wouldn’t be the right solution for this particular problem is taken as an admission of incompetence. I must be arguing against an Single-Page-App because I don’t know how to make one.

Framework authors... frequently make this situation worse. ... They argue that a ‘properly’ made Single-Page-App won’t have the accessibility and correctness bugs that frequently plague many of the Single-Page-Apps you see in the wild.

The problem is that doing a Single-Page-App ‘properly’ is even more expensive than doing a mediocre Single-Page-App, which in turn is considerably more expensive than an old-style multi-page web service. If a lack of resources is the limiting factor for the project, any suggestion that involves more work or more resources makes the problem worse.

What we end up with is an industry plagued with cost and time overruns. ... Because everybody wants to do ‘proper’ web development and nobody wants to adjust their expectations of what can be accomplished with their resources to something more realistic.

Long quote, sorry. 100% accurate.

I keep wondering why teams can't hit the old, Classic ASP scheduling rule of thumb we had back in the 20th century: One dev, one data entry page (with QA & dbms access!), two days.

Today, with the groups I've worked with on SPAs, we're nowhere close.

Part of it is quality of developers -- it's the Michael Jordan syndrome. While a GM, Jordan seemed to think players would unlock as much of their potential as he did his, so that's the way he drafted or traded, for potential. Didn't work out that well. 

Too many architects and technical decision makers think, "I can understand it," or "The internet suggests a dev should be able to do this." Both are followed by, "If you can't, it's your problem. We need better devs." Better devs would be great! Of course, the cost, even the simple feasibility, of finding, recruiting, hiring, training, and retaining those devs gets ignored. Worse, a stack that fits their devs better than a SPA never enters their minds. Or, when you suggest it, you get the same response Baldur describes.

And that's the contributor to slow development: We're using the wrong tools for our current devs.

If you've got all championship coders (which, I should add, are usually much different folks than championship NBA players, but there is some overlap -- well paid, trusted), make a great SPA.

If you've got bog standard devs from outside the Valley, it might be time to do something simpler as long as your use case says you can.

Labels: ,


posted by Jalindrine at 7/04/2022 12:55:00 PM
Saturday, June 25, 2022

Can StackOverflow leave nothing untouched? ๐Ÿ™„๐Ÿ˜‰

Maybe some UXer can explain why arrows with circles around them are better than the old vote buttons with just arrows.


Has this been around for a while and I just missed them? 

Well, at least I now know it happened between now and 2020.

I worry that some UI changes are made just to keep people employed and busy. I'm sure there's a good argument or 15 to change it. I'm not sure they're always good reasons.

I still use a version of SourceTree on Windows from 2015 when I'm on Windows. There's nothing wrong with it. I prefer it. I had a coworker see it on a screenshare and say, "Where can I get that theme?" 

What if your redesign resources had been spent on anything else? How many sprints saved? How awesome would your app be? 

Again, not that a redesign is bad. In many markets, simply refreshing the page will drive sales. Just keep in mind the opportunity cost. I realize SourceTree's users are probably more "aged UI tolerant" than most (see my previous post where I admint to using kdiff3), but... 

How much better has SourceTree's core UX experience really gotten in the last six and a half years? What percentage of their storypoints went to it? Worth it? Idk. (But my guess is heck no. Also note that they've worked through several UI iterations since then. Remember when they used a diamond ring for Commit? And people liked it? /cringe twice. Brah culture much?)

In other SO news, I did hit 15k and can protect questions now. I expected to be more impressed when I hit it the way I was with 10k, but... not so much. It's cool, and I'm happy some answers continue to help folks, but I really need to find another semi-obscure but useful tag to sit on.


EDIT: Here's some description. There is a comment that this makes the page more accessible for the visually impaired. I'd like to know how. Does that mean I don't see the improvement? (no pun intended) Yeah, but that's the point of asking. Honestly, what's the improvement?

Maybe down/up/votes are clearer?

There's also a comment that the design doesn't really meet WCAG compliance after all. Apparently they didn't QA dark mode. ๐Ÿคฆ

Labels: , , , , ,


posted by ruffin at 6/25/2022 12:59:00 PM
Thursday, June 02, 2022

As a corollary to yesterday's post about how to measure a poorly performing work culture, here's a well-put warning against getting used to a bad situation.
 

Unlike getting used to a smelly room, there are some large costs to becoming too habituated on a software project. First is “death by a thousand needles”. A number of small annoyances compound and can greatly decrease developer productivity. It may seem small at first but over time the team’s ability to deliver new customer value can grind to a halt.

Secondly, habitually poor engineering systems can drive engineers off of teams. I have seen several engineers become frustrated with the time it takes to build, deploy, test (the developer inner loop) and decide to leave the group. Making sure the development experience is enjoyable and smooth is a table-stakes item for retaining talent.

Okay, "grind to a halt" is too strong, but what if we say "half as fast as you could be moving". That's enough to matter, isn't it? And I think, honestly, that's possible.

It is too easy to get used to the status quo, even when you know it's inefficent or wrong. Habituation is a coping mechanism, and often a useful one! The problem is identifying when you're using it and remembering that you need to fix it soon too.

Don't let the perfect get in the way of the good enough, but don't let the good enough get in the way of doing your best either.

Labels: , ,


posted by Jalindrine at 6/02/2022 07:49:00 AM
Wednesday, June 01, 2022

This is a well worded blog post:

  • Youโ€™re learning coping mechanisms rather than skills.

Every organization has their quirks that people find their way to work around. ... Over time, we learn to cope with these things โ€“ we set aside extra time for the reports, make sure we take the time to sell the political person on our ideas, or learn how to argue.

The trap: Sometimes organizations are (or become) sufficiently toxic that weโ€™re investing more time in developing and refining the coping mechanisms than the actual skills. If your list of things to develop is really a list of things that you wonโ€™t have to do in a more functional environment, none of which will make you more employable elsewhereโ€ฆ itโ€™s time to walk away. [emph mine -mfn]

Everything we do that doesn't make us "more employable" could be wasted time. I mean, having effort, eg, helps because you get better at estimating stories, and knowing what you need to know to get those high-quality estimates and "ready-ready" stories. That's not wasted time (even if I don't always love those meetings).

But if we're coping just to cope -- and when it's safe to say a decent amount of it won't translate to a "more functional" workplace -- that's a workplace smell.

Nothing earth-shattering, but I liked the "does this problem make me/us/whoever more employable?" and "do I spend more time coping than learning?" metrics.

Labels: , ,


posted by ruffin at 6/01/2022 07:12:00 PM
Thursday, August 26, 2021

From microsoft.com:

Notice that the controller class depends onย ProductRepository, and we are letting the controller create theย ProductRepositoryย instance. However, it's a bad idea to hard code the dependency in this way, for several reasons.

  • If you want to replaceย ProductRepositoryย with a different implementation, you also need to modify the controller class.
  • If theย ProductRepositoryย has dependencies, you must configure these inside the controller. For a large project with multiple controllers, your configuration code becomes scattered across your project.
  • It is hard to unit test, because the controller is hard-coded to query the database. For a unit test, you should use a mock or stub repository, which is not possible with the current design.
[emphasis mine - mfn]

You know, I've often wondered why dependency injection is so popular. It truly is just an inversion of control. The control concerns themselves don't change. It's another variation of "it's all zeroes and ones" where you rearrange some deck chairs to make things look new again.

That's not all bad. Cargo culting is much too popular a development mentality. At least rearranging deck chairs makes people look at their architecture closely with fresh eyes, though I fear the result is often trading one cult for another that has better marketing or community buy-in when the decision to join is made.

And I often get the answer highlighted in green when the discussion comes up: "But we have to have interfaces so that we can test it!" Um... not always true. There are other equivalent options. And because there are good ways to test that existed before DI, that's really not a good explaination for its adoption.

DI isn't free; it has a significant cost. It requires a good head rethread and a ton of boilerplate. Easier testing doesn't (again imo) explain its explosive popularity. (Though I'm very happy it's become the industry's party line to proclaim we value testing so much.)

But this line (highlighted in yellow earlier) from Microsoft actually explains the DI advantage:

If the ProductRepository has dependencies, you must configure these inside the controller. For a large project with multiple controllers, your configuration code becomes scattered across your project.

I really think that's it -- put another way, DI helps enable clean encapsulation that, in turn, fosters anonymous collaboration between coding teams.

If I have to learn how to spin up Foo and pass in all of its dependencies, I'm having to schlep around a lot of objects I may have never used before, much less contributed to. If I'm a single-person indie shop, the advantages of Dependency Injection are slim. But if I want to access Foo.NeatMethod without bothering to open the Foo box, well, I'd rather you put all of its dependencies in a row for me.

That's what DI does. It's a decent amount of extra work up front to save everyone down the line from being nickel and dimed -- or, when they're protected from having to learn a whole new domain, dollar and pounded.

This shows that DI's advantages clearly appeal to enterprises; DI is literally an enterprise architecture strategy, not to improve system load or because it's an inherently superior -- again, for a small team, the DI boilerplate might ultimately slow them down -- but because it can help enable a specific type of work, which is work by multiple teams and workers with very little knowledge transfer overlap.

Enterprise development is really a pretty fascinating study in cultural evolution.

Labels: ,


posted by ruffin at 8/26/2021 06:43:00 PM
Wednesday, February 03, 2021

See previous post about too many bad devs running around. It's not brand new. They are and have been everywhere.

From newscientist.com:

Parking meters, cash registers and a professional wrestling video game have fallen foul of a computer glitch related to the Y2K bug.

โ€ฆ

Programmers wanting to avoid the Y2K bug had two broad options: entirely rewrite their code, or adopt a quick fix called โ€œwindowingโ€, which would treat all dates from 00 to 20, as from the 2000s, rather than the 1900s. Anย estimated 80 per centย of computers fixed in 1999 used the quicker, cheaper option.

โ€œWindowing, even during Y2K, was the worst of all possible solutions because it kicked the problem down the road,โ€ says Dylan Mulvin at the London School of Economics.

Because of course they did.

Utility company billsย have reportedly been producedย with the erroneous date 1920, while tens of thousands of parking meters in New York City have declined credit card transactions because of the date glitch.

Would non-windowing require a deeper refactor? Yes. Should they have done that then? Maybe?

The real question is if the developers let their management know the limitations of the fix, and if the managers told the customers.

Because if there's one thing that's lacking as much as good developer instincts in software development, it's managers who can spell "success".


From the same article:

โ€œFixing bugs in old legacy systems is a nightmare: itโ€™s spaghetti and nobody who wrote it is still around,โ€ says Paul Lomax, who handled the Y2K bug for Vodafone.

"Old legacy systems" you say? That's where code is spaghetti? Lolls.

What you should say is, "any mature codebase". There are always stupid edge conditions captured in that code, which makes it look less like a useless textbook example that faints at the first site of The Real World (c) MTV and more like something that's doing its job.

There is no clean code in production. I mean, there is, and if you handle your method signatures correctly, there's more in your code than elsewhere, but, um, there's not much idealistically pure, ivory tower type sample code making people money. And if there is, it's about to let them down in some serious-yet-unexpected way.


Related..., if you wrote the preceding blog entry in Markdown:

Adding support for a strikethrough syntax is a longstanding request for Markdown, but I omitted it by design. For one thing, there is no good punctuation to represent strikethrough. Tildes donโ€™t look like strikethrough at all โ€” tildes are squiggly, but a strike is a straight line.ย 

You know what doesn't look like a strikethrough at all, John? <strike></strike> ;^D

Labels: , , ,


posted by ruffin at 2/03/2021 11:44:00 AM

StackOverflow flashback... Not sure who wrote this comment, and it's a little strongly worded, but man, they're on the money. ;^)

  • @samhocevar I can't believe you Little Bobby Tabled me. ;) If you're running text processed by client-side JavaScript on your database server without any safety checks, heaven help us all. ;^) Look, there shouldn't beย anythingย any user can send from a client (eg, Postman) that gets past your server's security. And youย shouldย assume anything dangerous that could be sent from a clientย willย be. That is, if you require 100% safetyย from client-side JavaScript codeย which isย alwaysย user editable, and you think this function could open a security risk, you're playing in the wrong game.ย โ€“ย ruffinย Feb 19 '18 at 18:57ย ย 

I hope that makes sense. Sure, it's not bad to include some safety checks client-side, but they really are just niceties. Maybe you check a few things for your user's user input without a round trip to the server, but only after you've already put those same rules into your server's code.

(This, btw, is why Node is so intriguing. Write once with both sides in mind and you get client-side niceties for "free". Otherwise, if you push me to shoving, I'd say an mvp should only have input validation on the server [in ways that make it easy to return error packages to the client to display]. (And thus the * in the title... you can have it on the client, but it's not worth anything from the point of view of security.))

Honestly, this dev taking me to task by saying people can get formatUnicorn (read: client-side JavaScript code) to inject strings into (again) client-side variables... I mean, I can't even. WHY NOT JUST INPUT THE WACKY STRING TO BEGIN WITH? And to think that anything in JavaScript protects your server... Ugh. So many bad programmers loose these days. I'd like to think they're junior, but imagine that's a senior dev that forces juniors to protect against string injection in client code, maybe client code only. /shiver

Labels: , , , ,


posted by ruffin at 2/03/2021 10:25:00 AM
Thursday, January 09, 2020

I don't recall when I signed up for it, but I routinely get a newsletter from Baldur Bjarnason about software development with a focus on web development.

His new year's email includes some points on JavaScript frameworks that I'm suspicious I like because they so closely match mine.

But what they so clearly indicate is that web development has become a field whose outward appearance and, all too often, local practice, has been completely co-opted by the needs of the largest of enterprise corporations.

(Words in bullets are his. All emphasis is mine.)

  • Once you step outside of the social media bubble, however, vanilla JS and more โ€˜modestโ€™ approaches like Svelte or Stimulus/TurboLinks seem to have reached critical mass in terms of sustainability.Irrespective of those newer trends, jQuery and PHP-driven, un-hydrated, old-fashioned server-side rendering still utterly dominate the web that people use.
  • Web dev driven by npm packages, frameworks, and bundling is to the field of web design what Java and C# in 2010s was to web servers. If you work in enterprise software [npm, framework, and bundling-through-transpilation driven patterns are] all you can see. Web developers working on CMS themes (or on Rails-based projects) using jQuery and plain old JSโ€”maybe with a couple of libraries imported directly via a script tagโ€”are the unseen dark matter of the web dev community.
  • What should worry you is that npm- and framework-driven web development feels just as painful as enterprise software dev because it is enterprise development.

He continues by comparing TypeScript -- and I think he means more specifically "enterprise TypeScript development", because there's lots to enjoy about TypeScript the language, nothing inherently evil about it -- to enterprise Java of 20 years ago.

  • TypeScript smells like Java.
  • The complexity of npm packages harkens back to painful Java packaging monstrosities.
  • JavaScript build systems are about as much fun as Java build systems, even though they are doing very different things.
  • Deployment, as implemented in the Kubernetes and Docker ecosystems, is exactly as hard to understand and use as its Java predecessors because those are their predecessors.

Then he has a few points that serve as a sort of manifesto for the non-enterprise developer.

  • Some of use work exclusively with SMBs (Small-/Medium-sized Businesses) and shouldnโ€™t need to run the enterprise anti-productivity gauntlet. Our needs in terms of frameworks, bundling, and packages are very different from those working in enterprises with hundreds or thousands of employees.
  • It is not rational to expect [developers for small and medium-sized businesses] to be using enterprise-oriented tools and environments or to demand that we be happy about being saddled with your need for complexity.

I'd also ask people to take a close look at how they define what's an SMB project and what's an enterprise project. That is, defining projects by the size of the corporation that produces them isn't always -- heck, isn't usually -- the best metric.

Where something becomes "enterprise" is when you have hundreds of people working on the same project, in the same codebase. What npm/library-based bundling buys you is the ability to firewall smaller projects from each other. If someone writes a horribly inefficient page that no rendering library could solve without magic...


... your development process already includes a baked-in firewall to ensure that code doesn't adversely impact the rest of your system. You can stitch together completely independent projects easily, iff you really need to do that stitching.

But how big is your day-to-day work, really? How many of the problems "solved" by mass package import could have been solved reasonably well for your uses with a (think what's often derisively called a "NIH syndrome-induced") roll-my-own, homebrew solution?

Put another way, how many developers are really part of your specific product? 

If it's not hundreds, ask yourself how much time you'd save on developer ramp-up, maintenance, and new development if you too used "jQuery and plain old JSโ€”maybe with a couple of libraries imported directly via a script tag". Even in a team of "just" 20-30, the resource savings from going just 25% faster (a conservative cost of doing framework-style development in my experience) are unbelievable.

I'm not sure I know when going "full framework" is the best idea. At a conference, some friends of mine (coworkers) managed to corner a guy who was then working at Google on AngularJS (before Angular 2+). We talked to him a bit about AngularJS' pain points and how they solved problems of large DOMs, as our Knockout.js-based system was getting crushed in our more dynamic, feature-rich UIs.

His basic comment was that you can't fix these issues easily, and there was no silver bullet. Inefficient or complex UIs are trouble no matter where you build them.

The problem here was browser performance, which by definition isn't an SMB or enterprise problem. It's a client-side rendering one. Frameworks don't fix these issues. "Full framework" dev doesn't provide solutions to day-to-day problems, it provides the passive coordination that allows the amalgamation of code from hundreds of developers working at once.

Is that really the state your team finds itself in? Why would you want it to be?

And then here's a final comment from Bjarnason about how the thinkspace of development has been dominated by the enterprises -- he does a good job in the balance of his new year's points discussing how we see so much enterprise-specific information because those enterprises have a vested interest in making that come to be.

  • The divide between what you read in developer social media and what you see on web dev websites, blogs, and actual practice has never in my recollection been this wide. Iโ€™ve never before seen web dev social media and forum discourse so dominated by the US west coast enterprise tech company bubble, and Iโ€™ve been doing this for a couple of decades now. The pre-2000 dot-com bubble comes close although that one came attached to an actual financial bubble and happened before social media had evolved into its current form.

Anyhow, it's a good, thought provoking post, and worth a full read.

Labels: , , , , ,


posted by ruffin at 1/09/2020 10:06:00 AM
Saturday, July 27, 2019

Interesting addition to my “low end apps are cool” posts (Uber, Spotify) from Michael Tsai’s post on Fast Software is the Best Software:

Craig Mod:

Speed in software is probably the most valuable, least valued asset. To me, speedy software is the difference between an application smoothly integrating into your life, and one called upon with great reluctance. Fastness in software is like great margins in a book โ€” makes you smile without necessarily knowing why.

[โ€ฆ]

That said, Sublime Text has โ€” in my experience โ€” only gotten faster. I love software that does this: Software that unbloats over time. This should be the goal of all software. The longer itโ€™s around, the more elegant it should become. Smooth over like a river stone.

I was wondering this morning before seeing this why all software isn’t written like it’s designed to run on low end machines – not literally for the low end, necessarily (though that’s a great, and the most practical, benchmark), but for minimum footprint and maximum performance. Do we create bloat in our apps always in the interest of developing faster? Developing cheaper? My bet is no, we often create bloat simply because nobody is minding the henhouse.1

What happened to craft? What happened to wanting to support the greatest number of users? What happened to wanting to create the smallest, fastest apps?

IE 8 my schedule

This reminds me of a time (I’ve probably recounted this before) when I was on a team developing a schedule for a SaaS. When we were getting close to release, we got a little more serious about testing on IE 8 because, guess what?, a major logo client required it.

But guess what happens when you take a company of devs and you don’t tell them they have to use IE 8? They develop on Chrome (or, back then, Chrome and some Firefox/Firebug).2 And guess how often they use boxes that mirror what the users are going to use? Never. Literally never.

Guess which is a better approximation of end users’ experiences with your app, the phat dev box with Chrome or a four year-old tower with IE 8?

I think this is a lot of why software runs slowly. And it’s not simply that devs use better hardware, it’s that the difference between great hardware and bottom of the line – all the way down to below-TracFone-level Android phones in third world nations – is much greater than we (as devs) ever anticipate as we code and develop.

Unless devs develop and test on representative hardware, they’ll never truly value their app’s performance.

Why don’t we want to write thinner apps? Why isn’t this appreciated? Have you ever heard someone ask why you have and if you need each dependency your repo’s taken on? Have you taken a look yourself?

Sometimes it’s just as simple to create thin apps as thick when you’re starting a greenfield project. Laying down a good, thin foundation and making platform-accessibility a goal from the start creates better software.


1 Also, he’s right about Sublime Text. It’s insanely speedy. So many apps seem to keep pace through the years. It upgrades its version, you upgrade your box, but the app is still about the same speed. Sublime’s performance, on the other hand, screams now.

2 Did we have Safari specific errors on macOS too? Yes, yes we did, for exactly the same reason. Nobody was using the platform.

Labels: ,


posted by ruffin at 7/27/2019 07:51:00 PM
Wednesday, July 01, 2015

As evidenced by the last post, I've been boning up on my JSP & Java Servlet skillz this week as we prepare to migrate an app I prototyped in Node over to a WebLogic host, its eventual home.

I thought it'd be safe to develop against Tomcat, but wasn't absolutely sure, so I started googling around a little. So far, so good. Looks like vanilla Tomcat has, at worst, a subset of the features of every other major servlet container.

One of the most promising articles by title, WebSphere vs. JBoss vs. WebLogic vs. Tomcat รขโ‚ฌโ€œ presentation from the InterConnect 2015 (it's got everything! All the major servlet containers! It's from this year!) turned out to be a painful foray into marketing-by-blog from IBM, but there was one bonus, the slide (which is now above, but will later be) below:

So 90% of TOC for a software system isn't licensing. That's probably true to no-worse-than-trueish.

An interesting exercise, however, would be to put numbers -- okay, okay, first you have to recategorize ("Developer, admin and end-user training cost" falls in the same category? RLY? etc) -- beside each of the other categories.

Though it's worth saying that a 9% savings is significant any way you look at it, especially for garage-companies where developer and admin cost is paid in elbow grease.

Labels: ,


posted by ruffin at 7/01/2015 01:57:00 PM

<< Older | Newer >>


Support freedom
All posts can be accessed here:


Just the last year o' posts:

URLs I want to remember:
* Atari 2600 programming on your Mac
* joel on software (tip pt)
* Professional links: resume, github, paltry StackOverflow * Regular Expression Introduction (copy)
* The hex editor whose name I forget
* JSONLint to pretty-ify JSON
* Using CommonDialog in VB 6 * Free zip utils
* git repo mapped drive setup * Regex Tester
* Read the bits about the zone * Find column in sql server db by name
* Giant ASCII Textifier in Stick Figures (in Ivrit) * Quick intro to Javascript
* Don't [over-]sweat "micro-optimization" * Parsing str's in VB6
* .ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); (src) * Break on a Lenovo T430: Fn+Alt+B
email if ya gotta, RSS if ya wanna RSS, (?_?), ยข, & ? if you're keypadless


Powered by Blogger etree.org Curmudgeon Gamer badge
The postings on this site are [usually] my own and do not necessarily reflect the views of any employer, past or present, or other entity.