Live data from Hacker News

The Grug Brained Developer (2022)

grugbrain.dev

151–160 of 603 posts

Re: The Grug Brained Developer (2022)

#151
post #118

So many gems in here but this one about microservices is my favorite: grug wonder why big brain take hardest problem, factoring system correctly, and introduce network call too

I have a conspiracy theory that it’s a pattern pushed by cloud to get people to build applications that: - Cannot be run without an orchestrator like K8S, which is a bear to install and maintain, which helps sell managed cloud. - Uses more network bandwidth, which they bill for, and CPU, which they bill for. - Makes it hard to share and maintain complex or large state within the application, encouraging the use of mo…

It's 100% this; you're right on the money (pun intended).

Don't forget various pipelines, IaC, pipelines for deploying IaC, test/dev/staging/whatever environments, organization permissions strategies etc etc...

When I worked at a large, uh, cloud company as a consultant, solutions were often tailored towards "best practices"--this meant, in reality, large complex serverless/containerized things with all sorts of integrations for monitoring, logging, NoSQL, queues etc, often for dinky little things that an RPI running RoR or NodeJS could serve without breaking a sweat.

With rare exceptions, we'd never be able to say, deploy a simple go server on a VM with server-side rendered templates behind a load balancer with some auto-scaling and a managed database. Far too pedestrian.

Sure, it's "best practices" for "high-availability" but was almost always overkill and a nightmare to troubleshoot.

Re: The Grug Brained Developer (2022)

#152

Earlier quoted context omitted.

We've solved this problem by making the modules in the monolith only able to call each other from well-defined APIs, otherwise CI fails.

In the Java world both Spring and Guice are meant to do this, and if you have an ISomething you've got the possibility of making an ILocalSomething and a IDistributedSomething and swap one for the other.

This is generally a bad idea imo. You fundamentally will have a hard time if your api is opaquely network-dependent or not. I suppose, you’ll be ok if you assume there is a network call, but that means your client will need to pay that cost every time, even if using the ILocal.

Re: The Grug Brained Developer (2022)

#153
post #116

Earlier quoted context omitted.

Being at a firm where the decision to use C++ was made, the thought process went something like this: "We're going to need to fit parts of this into very constrained architectures." "Right, so we need a language that compiles directly to machine code with no runtime interpretation." "Which one should we use?" "What about Rust?" "I know zero Rust developers." "What about C++?" "I know twenty C++ developers and am conf…

And none of those 20 C++ developers can learn rust? What’s wrong with them?

Personally I think Rust is better thought out than C++ but that I've got better things to do than fight with the borrow checker and I appreciate that the garbage collector in Java can handle complexity so I don't have to.

I think it's still little appreciated how revolutionary garbage collection is. You don't have maven or cargo for C because you can't really smack together arbitrary C libraries together unless the libraries have an impoverished API when it comes to memory management. In general if you care about performance you would want to pass a library a buffer from the application in some cases, or you might want to pass the library custom malloc and free functions. If your API is not impoverished the library can never really know if the application is done with the buffer and the application can't know if the library is done. But the garbage collector knows!

It is painful to see Rustifarians pushing bubbles around under the rug when the real message the borrow checker is trying to tell them is that their application has a garbage-collector shaped hole in it. "RC all the things" is an answer to reuse but if you are going to do that why not just "GC all the things?" There's nothing more painful than watching people struggle with async Rust because async is all about going off the stack and onto the heap and once you do that you go from a borrowing model that is simple and correct to one that is fraught and structurally unstable -- but people are so proud of their ability to fight complexity they can't see it.

Re: The Grug Brained Developer (2022)

#154

“Good debugger worth weight in shiny rocks, in fact also more” I’ve spent time at small startups and on “elite” big tech teams, and I’m usually the only one on my team using a debugger. Almost everyone in the real world (at least in web tech) seems to do print statement debugging. I have tried and failed to get others interested in using my workflow. I generally agree that it’s the best way to start understanding a s…

I am also in the camp that has very little use for debuggers. A point that may be pedantic: I don't add (and then remove) "print" statements. I add logging code, that stays forever. For a major interface, I'll usually start with INFO level debugging, to document function entry/exit, with param values. I add more detailed logging as I start to use the system and find out what needs extra scrutiny. This approach is ver…

A log is very different than a debugger though, one tells you what happened, one shows you the entire state and doesn't make you assemble it in your head.

Re: The Grug Brained Developer (2022)

#155
post #154

Earlier quoted context omitted.

I am also in the camp that has very little use for debuggers. A point that may be pedantic: I don't add (and then remove) "print" statements. I add logging code, that stays forever. For a major interface, I'll usually start with INFO level debugging, to document function entry/exit, with param values. I add more detailed logging as I start to use the system and find out what needs extra scrutiny. This approach is ver…

A log is very different than a debugger though, one tells you what happened, one shows you the entire state and doesn't make you assemble it in your head.

Your framing makes it sound like the log is worse in some way, but what the log gives you that the debugger makes you assemble in your head is a timeline of when things happen. Being able to see time is a pretty big benefit for most types of software.

I can always drop an entire state object into the log if I need it, but the only way for a debugger to approximate what a log can give me is for me to step through a bunch of break points and hold the time stream in my head.

The one place where a debugger is straight up better is if I know exactly which unit of code is failing and that unit has complicated logic that is worth stepping through line by line. That's what they were designed for, and they're very useful for that, but it's also not the most common kind of troubleshooting I run into.

Re: The Grug Brained Developer (2022)

#156

“Good debugger worth weight in shiny rocks, in fact also more” I’ve spent time at small startups and on “elite” big tech teams, and I’m usually the only one on my team using a debugger. Almost everyone in the real world (at least in web tech) seems to do print statement debugging. I have tried and failed to get others interested in using my workflow. I generally agree that it’s the best way to start understanding a s…

I would tend to say that printf debugging is widespread in the Linux-adjacent world because you can't trust a visual debugger to actually be working there because of the general brokenness of GUIs in the Linux world. I didn't really get into debuggers until (1) I was firmly in Windows, where you expect the GUI to work and the LI to be busted, and (2) I'd been burned too many times by adding debugging printfs() that g…

Why would you want a GUI debugger?

Re: The Grug Brained Developer (2022)

#157

“Good debugger worth weight in shiny rocks, in fact also more” I’ve spent time at small startups and on “elite” big tech teams, and I’m usually the only one on my team using a debugger. Almost everyone in the real world (at least in web tech) seems to do print statement debugging. I have tried and failed to get others interested in using my workflow. I generally agree that it’s the best way to start understanding a s…

I'd love to use a real debugger but as someone who has only ever worked at large companies, this was just never an option. In a microservices mesh architecture, you can't really run anything locally at all, and the test environment is often not configured to allow hooking up a stepping debugger. Print debugging is all you have. If there's a problem with the logging system itself or something that crashes the program…

At my company our system is composed of 2 dozen different services and all of them can run locally in minikube and easily be debugged in jetbrains.

Re: The Grug Brained Developer (2022)

#158
post #154

Earlier quoted context omitted.

A log is very different than a debugger though, one tells you what happened, one shows you the entire state and doesn't make you assemble it in your head.

Your framing makes it sound like the log is worse in some way, but what the log gives you that the debugger makes you assemble in your head is a timeline of when things happen. Being able to see time is a pretty big benefit for most types of software. I can always drop an entire state object into the log if I need it, but the only way for a debugger to approximate what a log can give me is for me to step through a bu…

It's not worse or better, but its not really comparable is all I am really saying, I would not use them for the same things.

Re: The Grug Brained Developer (2022)

#159
post #152

Earlier quoted context omitted.

In the Java world both Spring and Guice are meant to do this, and if you have an ISomething you've got the possibility of making an ILocalSomething and a IDistributedSomething and swap one for the other.

This is generally a bad idea imo. You fundamentally will have a hard time if your api is opaquely network-dependent or not. I suppose, you’ll be ok if you assume there is a network call, but that means your client will need to pay that cost every time, even if using the ILocal.

It depends on what the API is. For instance you might use something like JDBC or SQLAlchemy to access either a sqlite database or a postgres database.

But you are right that the remote procedure call is a fraught concept for more reasons than one. On one hand there is the fundamental difference between a local procedure call that takes a few ns and a remote call which might take 1,000,000 longer. There's also the fact that most RPC mechanisms that call themselves RPC mechanisms are terribly complicated, like DCOM or the old Sun RPC. In some sense RPC became mainstream once people started pretending it was REST. People say it is not RPC but often you have a function in your front end Javascript like fetch_data(75) and that becomes GET /data/75 and your back end JAXB looks like

    @GET
    @Path("/{id}")
    public List fetchData(@PathParam("id") int id) { ... }

Re: The Grug Brained Developer (2022)

#160

Earlier quoted context omitted.

I would tend to say that printf debugging is widespread in the Linux-adjacent world because you can't trust a visual debugger to actually be working there because of the general brokenness of GUIs in the Linux world. I didn't really get into debuggers until (1) I was firmly in Windows, where you expect the GUI to work and the LI to be busted, and (2) I'd been burned too many times by adding debugging printfs() that g…

Why would you want a GUI debugger?

Can see all your source code while you're debugging. And it's not like emacs where your termcap is 99.99% right which means it is 0.01% wrong. (Mac-ers get made when something is 1px out of place, in Linux culture they'll close a bug report if the window is 15000 px to the left of the screen and invisible because it's just some little fit and finish thing)
Post reply on HN