January 28, 2019
Posted 2019-01-28
Blog
Articles- terminal.d gets clipboard functions, ldc 1.20 out.
- DConf keynote speaker announced: Lua architect Roberto Ierusalimschy, Named args DIP discussed
- February 3, 2020
- Adam's terminal suite explained
- Understanding mixin templates, terminal.d improvements
- My attribute-by-default proposal. Also dmd 2.090 came out.
- DConf 2020 announced: June 17-20 in London. @safe by default debated. Adam did: Android, JNI, WebSocket in arsd libs
- tar.xz, --DRT tip, dom bug fixes, more Android and JNI, link to old phobos docs
- LDC 1.19 - Android, AVR. My rant on tests, update on JNI and COM.
- Walter's string interpolation proposal is OK but not great. My Android thing nearing beta release. dub downtime explained.
- Android project update, introduction to arsd.jni
- New pattern about interface contracts
- Adam shares Windows console secrets - DO NOT USE chcp!!
- Adam's rant on benchmarks
- Socket tutorial
- November 4, 2019
- October 28, 2019
- arsd package updates, forum nonsense
- Update on Android
- Adam does iOS "goodbye world"
- September 30, 2019
- D turns 20, Adam rants on software freedom
- Named arg DIPs and my thoughts on code organization
- September 9, 2019
- I wrote about mixin templates vs string mixins on Stack Overflow
- August 26, 2019
- Bug bounty in D again - my hot take, on reusing code, a fun picture, my tentative plan for the next month
- Time invested is worth a lot
- cgi.d's new scheduler, static this tricks
- July 29, 2019
- July 22, 2019
- Solving vs managing problems
- A big week in the arsd repo
- July 1, 2019
- June 24, 2019
- June 17, 2019
- CRTP thoughts, named arguments DIP review, DConf videos now on youtube
- musings on hybrid CT/RT tests, some more progress on new web framework
- a little more webassembly
- May 20, 2019
- Adam's string interpolation proposal
- DMD 2.086 live, GCC 9 with D support formally released, DConf coming soon, links to posts on builder pattern and disallowing implicit conversions with templates, and 2d array op overloads
- template constraint error improvements coming?
- dmd 2.086 beta, dstep 1.0 released, Adam works on memory usage
- obj-c and webassembly report, tips on is expressions linked.
- new ldc, new dmd, dpp on the blog
- D's future discussed in forums
- LDC beta, DConf blog link, Adam introduces gamehelpers.d
- March 18, 2019
- LDC 1.15.0-beta1, responsive design rant
- dmd 2.085.0 released
- Obj-C interop and D without druntime code to copy/paste
- dmd beta, more info coming next time, demo of new web framework initial prototype
- automatic web interface discussion, reflection tips and tricks
- Adam busy with weather and a move, lots of community announcements
- January 28, 2019
- Working on official blog 2018 retro, C++ new wrapped, dmd reading zips?
- dmd obj-c growing, Adam static foreaches an interface to RPC
- dmd 2.084, hope for future, but busy non-D week for me
- IDE tools released, my cgi.d gets new features
- DConf announced, tip, Adam rants: mouse trap
- This Week in D is back!
GtkD blog, forum fundraiser, ref accept rvalue DIP argument, and more. Adam rants about libraries.
Core D Development Statistics
In the community
Community announcements
See more at the announce forum.
What Adam is working on
The week was pretty crazy again, lots of bad weather here this week, and some day job work. I wrote some oauth2 client code in D (which is pretty trivial) after seeing a hard fail from a third party gem we were using at work.
Which brings me to...
My Rant of the Week
I'm not a fan of the dependency culture common among developers nowadays. We try to make everything into libraries, and try to use libraries for everything, which in turn, use even more libraries, which use even more libraries, and so on.
Creating a library adds quite a bit of cost to the author's development. You are committing to some kind of stability, documenting an interface, and being responsive to the needs of multiple users - which tends to bloat the code and complicate the interface over time. These costs tend to be minimized, meaning the majority of libraries out there are terrible.
Using libraries also adds quite a bit of cost, even if they are one of the rare good libraries. You need to evaluate libraries, manage the recursive dependencies (which is my pet peeve), and figure out that interface. These costs also tend to be minimized - you just pick the first one a search brings up, let the package manager pick whatever version it wants and grab all the dependencies without evaluation, and write whatever code that can use the interface with minimal regard to how it fits into the bigger picture you are trying to solve. Your codebase may even take on an architecture centered around your use of the library! (Of course, you can then rebrand it to a "framework" lol)
But the worst case is when these two cost-cutters combine. You use a library, and it looks OK at first... then it turns out it is awful.
That's my story this time: we had to access a Google API from Ruby and grabbed a gem that seemed suitable. We created relevant credentials, populated a configuration file and wrote some glue code. It looked like a win for libraries, yay.
A year later, that function suddenly stopped working. Looking into it, the authentication token was being rejected. OK, maybe it just expired, easy fix. But no, the process described in the documentation no longer worked. Well, it is a Google service, and they break stuff all the time, maybe I will try the new version.
Of course, this "minor" release broke half the API - this is why I don't trust SemVer, it is a nice idea but depends on everyone actually doing it right - but no big deal, I'll make the glue code use the new functions. But, it still didn't work. Maybe I need to do something like enable new access on the account.
Well, I log into it and add the access... but nothing changed. Yada, yada, yada, out of desperation, I find the client id from the credentials file doesn't match that account and google it, kinda hoping it might tie it to one of the other company accounts.
Instead, it returns hits on github. Hardcoded in the source code of one of the library's dependencies. uuuuuuhhhhhh what?!
I now take a closer look at the library's source code. Oh, it passed the app info - client id and secret - to the inner library, but then the inner library completely ignored those parameters in favor of its own hardcoded thing. (And a fail on my part when I authorized it the first time, I must not have paid any attention to the app name. I wasn't really scrutinizing it since it is a strictly internal use application and I assumed it was my own account since I passed my own app id to the function.)
I don't think this was nefarious on the part of the dependency author; it looked to me like their debugging or convenience code they forgot to remove when committing, and there's no evidence they actually got the generated access tokens or anything. But wow, how many other people got bit by this too? Did the first library's author even notice their dependency was totally wrong?
They have since put out another major version release that fixes this, but still, wow. And Google's documentation says it is hard to implement OAuth correctly, use a library instead. L-O-freaking-L.
Well, after fighting with that for several hours, I just wrote my own code to do it from "scratch". About twenty minutes later, I had a working implementation - and I was confident it was ACTUALLY working, since I understood what it was doing on all layers.
I say "scratch" with scare quotes because I actually did use millions of lines of library code - the operating system. I didn't actually write a TCP/IP stack, a TLS implementation, or graphics device driver. I didn't actually write a filesystem or virtual memory manager. Those things are legitimately reusable, and actually pretty well debugged through use. I did happen to write the http implementation, but meh.
After all that foundation, a few redirects and HTTP posts and file writes - about 50 lines of code - is barely from scratch! So I'm not against code reuse per se, I just want smart reuse.
This story is a bit of an extreme case, but I see it as confirmation of my preconceived biases ( ;) ) - package managers bring a net negative effect on software quality because they encourage this corner-cutting on both sides of the library equation.
I propose an experiment: write your own implementation, but publish it to a public package manager under a pen name and then import it as a dependency instead of committing it directly to your own code as a private function. Would that make it pass code review it would have otherwise failed?
If yes, are you sure you are actually coming out ahead with library/package use in other cases too?