Hacker Newsnew | past | comments | ask | show | jobs | submit | cjfd's commentslogin

So what would be a good architecture? How would I recognize it if I stumbled against it?

My own inclinations here are that it would be good to have as few different technologies as possible. To run things on as few different machines as possible and to have automated tests for everything. The thing is that as soon as there are multiple technologies you get to have different people specializing in them and it is always the communications between those that becomes painful. The automated tests are there to prevent fear of change setting in. I think I am kind of advocating what is called a 'big ball of mud' but that I want it to be a transparent ball of mud because of automated testing. I guess what I am saying is that I distrust most developments in so-called application architecture of the last few decades except automated tests. In particular, I think frameworks and microservices are mostly just bad.


In an existing system some combination of these attributes:

- High quality (e.g. low number of issues hit by customers, resilient to failures, efficient, secure etc.)

- Easy to maintain (well organized, broken down in a sensible way into components or layers)

- Easy to extend/adapt to future requirements (i.e. the designer was able to anticipate the likely direction of the system and account for that in the design)

Automated testing feels a bit orthogonal to me but a system that is easy to test is likely one with a better architecture. It's not strictly part of what I'd call architecture.

Less different technologies - YES!

Runs on fewer machines is a sign of an efficient/performant design. Less well designed systems exhibit bloat that is often made up for by running on more machines.


I like to ask this question: "Can I make this system do what I need it to do while being able to stay with the existing architecture or do I need to become a special case?"

There is a lot buried in this question but it can help sus out if the rules in place allow the challenges the system faces today or if it is antiquated in how it views the world it operates in. Good and bad can be related to time and context but like many things in software, it needs to be able to change and sometimes that change requires the willingness to start from scratch with new assumptions.

Attributes like mix of languages, system/task ownership, specialization are symptoms that an architecture may want to enable or discourage but are symptoms, not measures of quality. Automated testing and how much that influences your software design is more aligned with the culture of the organization and how it treats code than it is the arrangement of subsystems it is built on.


I've been doing this stuff for about 15 years now. Longer than many, not as long as some.

In my opinion, good architecture should be easy to extend, easy to scale (up and down), easy to reproduce. Microservice architectures are easy to scale, but usually hard to reproduce (any amount of config per service adds up a lot) and can be very hard to extend too (any changes to one service might ripple to many others, with knock-on effects)

One of my biggest red flags for a bad architecture is if you cannot easily create a (preferably localhost) development environment for it. I think this is where a lot of microservice based projects stumble. It leads to a lot of brittleness and a very siloed development team in my experience. Replacing what should be a library call or DB query with a network request to another service (which then has to query the DB for you) is a certain kind of lunacy.

Frameworks that are very opinionated are also very bad in my opinion. Depending how strict they are if you're doing anything even remotely unexpected you will butt up against the limitations of the framework often. That's annoying to me, I prefer to build my own stuff.


How about not? If an LLM is needed to get set up either the language or the documentation is garbage. Probably both.


If you get deeply excited about config files, sure, go right ahead and set up the dev env without help.


pacman -S git vim gcc make gtest

That is about it. No stinkin' config files needed. Initial Makefile is about 15 lines long, I can type it myself or copy something from another project.


Ah you should have just said you use arch.

But it's a very weak programmer that needs a test suite. Real ones prove the consistency of their programs with goose feather and vellum.


I am not sure about the goose feather and the vellum but you do have a point about proving consistency. Fortunately, I also have a coq/rocq project for that kind of stuff so maybe one day I can be a not-so-very-weak programmer.


Well, the short summary of it all is that the US is the very curious case of a superpower attempting to become a third world country.


"assuming you have a real engineering job" does a lot of work there. You could also do a lot of work the other way by stating "assuming you are getting a real education". I studied physics when I was young and that field is a lot deeper than my current work in programming. Computer science can also be quite deep if one considers things like the halting problem, type theory and proof assistants.


On the other hand, if you store a small integer in a float it is generally reliable to compare to it. E.g., setting a float to zero and comparing whether the float is zero.


This sounds all true to me, but I think there is more. It is not just decisions by management, it is also the wider economic context. Low interest rates and, for the US, having the world reserve currency as your own currency both seem to make many of these changes attractive or even inevitable. Low interest rates lead to 'innovation' which I put in scare quotes because besides real innovation it can also mean something that passes as innovation but in the end just turns out to be a bubble of stuff that was not valuable enough. The 'innovation' then crowds out investments in more boring sectors like manufacturing. This is also not good for the population in general because fewer jobs are left for people who are not suited for working in highly 'innovative' sectors.


From the quotes in the article it sounds pretty simple. These are words that everyone can understand. Of course, the fascist right is attempting to 'inform' the public at a level where even two-syllable words are a bit too complicated. But maybe the general public also should attempt to be at a level a bit higher than cattle.


All kinds of worries are possible. (1) It turns out that all this AI generated stuff is full of bugs and we go back to traditional software development, creating a giant disinvestment and economic downturn. (2) sofware quality going way down. we cannot produce reliable programs anymore. (3) massive energy use makes it impossible to use sustainable energy sources and we wreck the environment every more than we are currently doing. (4) AIs are in the hands of a few big companies that abuse their power. (5) AI becomes smarter than humans and decides that humans are outdated and kills all of us.

It obviously depends on how powerful AI is going to become. These scenarios are mutually exclusive because some assume that AI is actually not very powerful and some assume that it is very powerful. I think one of these things happening is not at all unlikely.


1 and 2 are really only an issue if you vibe code. There's no reason to expect properly reviewed AI assisted code to be any worse than human written code. In fact, in my experience, using LLMs to do a code review is a great asset - of used in addition to human review


When I was a teenager, I read a book about assembly language for the commodore and implemented the game of life in a really simple way. I just used the text screen. To switch on a cell, I would put an asterisk ('*') in it. Then I could run my machine code program and it would evolve according to the rules of the game of life.


And who didn't do that! :)

You could also 4x the resolution by using half- and quarter-block characters from the top half of the ASCII table (or it'd be the PETSCII one i C64 case).


> And who didn't do that! :)

Exactly. It's even how I taught myself extremely basic Pascal -- getting my BASIC Life program running in Pascal. With asterisks.

A taught a friend at uni, who was a much better programmer than me, how the algorithm worked. He did a pixel-by-pixel version in machine code, but it was a bit slow on a ZX Spectrum.

So he did exactly the quarter-character-cell version you describe. I wrote the editor in BASIC, and he wrote a machine-code routine that kicked in when told and ran the generations. For extra fun he emitted some of the intermediate state to the border, so the border flashed stripes of colour as it calculated, so you could see it "thinking". Handy for static patterns -- you could see it hadn't crashed.

I've been considering doing a quarter-cell Mandelbrot for about 30Y now. Never got round to it yet.


The answer to a lot of "wow, how did the 8-bit machine pull that off? it seems like that would eat a lot of RAM" is that the framebuffer is the data storage. You were literally looking at the primary data store itself, because when a full-resolution framebuffer was 1/4th your addressable RAM (and slightly more than that for your actual RAM since you couldn't ever quite use all 64KB no matter how you mapped it), you need to get the most bang for the buck out of that RAM usage as you can.


Ha, I remember doing this with my Apple //. I forget what I was doing, but realized if I could set a pixel and later get what color was drawn at that location I could use it as a big array. Didn't know about peek/poke yet. One of those core "computers are magic" memories.


When I got into retrocomputing a few years ago, I also did this. Works great with TRS-80 semigraphic characters. First, I wrote it in C with a Z80 c compiler. The, I wrote it again in assembly and it was much faster! Amazing!


Well, if you do not need to care about performance everything can be extremely simple indeed. Let me show you some data structure in coq/rocq while switching off notations and diplaying low level content.

Require Import String.

Definition hello: string := "Hello world!".

Print hello.

hello = String (Ascii.Ascii false false false true false false true false) (String (Ascii.Ascii true false true false false true true false) (String (Ascii.Ascii false false true true false true true false) (String (Ascii.Ascii false false true true false true true false) (String (Ascii.Ascii true true true true false true true false) (String (Ascii.Ascii false false false false false true false false) (String (Ascii.Ascii true true true false true true true false) (String (Ascii.Ascii true true true true false true true false) (String (Ascii.Ascii false true false false true true true false) (String (Ascii.Ascii false false true true false true true false) (String (Ascii.Ascii false false true false false true true false) (String (Ascii.Ascii true false false false false true false false) EmptyString))))))))))) : string


You know you could just define the verified specs in lean and if performance is a problem, use the lean spec to extract an interface and tests for a more performant language like rust. You could at least in theory use Lean as an orchestrator of verified interfaces.


In Lean, strings are packed arrays of bytes, encoded as UTF-8. Lean is very careful about performance; after all, a self-hosted system that can't generate fast code would not scale.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: