"Abstracting" means extracting the commnon parts of multiple instances, and making everything else a parameter. The difficulty for software is that developers often start by writing the abstraction, rather than having multiple existing instances and then writing code that collects the common parts of those multiple instances into a single abstraction. I guess that is what "refactoring" is about.
In sciences and humanities abstraction is applied the proper way, studying the instances first then describing multitude of existing phenomena by giving names to their common repeating descriptions.
Software products are about unique competitive value that grows over time. Products have it or not. AI produced software is like open source in a sense, you get something for free. But whose gonna get rich if everybody can just duplicate your product by asking AI to do it, again?
Think of investing in the stock market by asking AI to do all the trading, for you. Great maybe you make some money. But when everybody catches on that it is better to let the AI do the trading, then others's AI is gonna buy the same stocks as yours, and their price goes up. Less value for you.
Spot on. That's why so far all of the supposed solutions to 'the programmer problem' have failed.
Whether this time it will be different I don't know. But originally compilers were supposed to kill off the programmers. Then it was 3G and 4G languages (70's, 80's). Then it was 'no code' which eventually became 'low code' because those pesky edge cases kept cropping up. Now it is AI, the 'dark factory' and other fearmongering. I'll believe it when I see it.
Another HN'er has pointed me into an interesting direction that I think is more realistic: AI will become a tool in the toolbox that will allow experts to do what they did before but faster and hopefully better. It will also be the tool that will generate a ton of really, really bad code that people will indeed not look at because they can not afford to look at it: you can generate more work for a person in a few seconds of compute time than you can cover in a lifetime. So you end up with half baked buggy and insecure solutions that do sort of work on the happy path but that also include a ton of stuff that wasn't supposed to be there in the first place but that wasn't explicitly spelled out in the test set (which is a pretty good reflection of my typical interaction with AI).
The whole thing hinges on whether or not that can be fixed. But I'm looking forward to reading someone's vibe coded solution that is in production at some presumably secure installation.
I'm going to bet that 'I blame the AI' is a pattern what we will be seeing a lot of.
In the long run, it's going to become about specifications.
Code is valuable because it tells computers what you want them to do. If that can be done at a higher level, by writing a great specification that lets some AI dark factory somewhere just write the app for you in an hour, then the code is now worthless but the spec is as valuable as the code ever was. You can just recode the entire app any time you want a change! And even if AI deletes itself from existence or whatever, a detailed specification is still worth a lot.
Whoever figures out how to describe useful software in a way that can get AI agents to reliably rebuild it from human-authored specifications is going to get a lot of attention over the next ~decade.
> Whoever figures out how to describe useful software in a way that can get AI agents to reliably rebuild it from human-authored specifications
Which is why I think there's very little threat to the various tech career paths from AI.
Humans suck at writing specifications or defining requirements for software. It's always been the most difficult and frustrating part of the process, and always will be. And that's just actually articulating the requirements, to say nothing of the process of even agreeing on the requirements in the first place to even start writing the spec.
If a business already cannot clearly define what they need to an internal dev team, with experts that can somewhat translate the messy business logic, then they have a total of zero hope to ever do the same but to an unthinking machine and expect any kind of reliable output.
> Humans suck at writing specifications or defining requirements for software
There’s nearly 10k rfcs and the whole ISO corpus that disagree with you. It’s not that people can’t write requirements. It’s just that they change so much over the lifetime of the business that no one really bothers. Or the actual writings are not properly organized and archived.
One of the unexpected benefits of everyone scrambling to show that they used AI to do their job is that the value of specs and design documents are dawning on people who previously scoffed at them as busywork. Previously, if I wanted to spend a day writing a detailed document containing a spec and discussion of tradeoffs and motivations, I'd have to hide it from my management. Now, I'm writing it for the AI so it's fine.
There was never a zeroth law about being ethical towards all of humanity. I guess any prose text that tries to define that would meander like this constitution.
Could I ask the AI to create me a set of template-files as described by you above? Or if there is an example set of template files somewhere then ask the AI to do its thing based on those? Or ask the AI to create me such a set of template files for it to work on?
I mean why do I need to read from HN what to do, if AI is so knowledgable and even agentic?
Yeah absolutely. But you'll need to modify it until it works better for your use case. It's all still highly flawed, but also highly capable. Like a very fast janitor that occasionally uses chocolate syrup instead of soap to mop the floor.
Certainly, every tool is supposed to make our work easier or more productive, but that doesn't mean that every tool is intuitive or easy to learn to use effectively or even to use it at all.
Certainly, but aren't AI tools supposed to be intuitive and easy to use because we can communicate with them in natural language?
With VIM or Emacs I am supposed to know what Ctrl-X does. But with AI tools (ideally) I should be able to ask AI (in English) to edit the document for me?
Maybe the reason we can't do it that way is that, "We're not there yet"?
Honestly IMO it's more that I ask for A, but don't strongly enough discourage B then I get both A, B and maybe C, generally implemented poorly. The base systems need to have more focus and doubt built in before they'll be truely useful for things aside from a greenfield apps or generating maintainable code.
I think a more interesting extension would be to see objects as functions. An object maps a set of keys to values. In most languages those keys must be strings. But I don't see why they couldn't be anything. For instance a key could be a function, and to access the value of such a key you would need to pass in exactly that function like this:
let v = myObject [ myFunk ];
Like with arrays-as-functions, the domain of the object-as-function would be its existing keys. Or we could say the domain is any possible value, with the assumption that value of keys which are not stored in the object is always null.
Whether new keys could be added at runtime or not is a sepearate question.
It should be easy to extend the syntax so that
myObject (anything) === myObject [anything]
whether myObject is an object, or a 'function' defined with traditional syntax.
Yes, we can look at an object as a function that accepts a key and returns a value (or null). Depends on language, it's called a set, map, or associative list.
type AnObject = {
[key: any]: any
}
type FunkyObject = (key: any) => Maybe<any>
Then we can see arrays as a limited type of object/function that only accepts a number (index) as key.
type FunkyList = (index: number) => Maybe<any>
We can even consider any variable as a function whose key is the name.
type FunkyVariable = (name: string) => Maybe<any>
And any operation as a function whose key is the operator, with arguments, and the return value is the result.
type FunkyOperator = (name: string, ...values: any) => any
FunkyOperator('+', 1, 2) // => 3
Even an `if` statement can be a function, as long as the values are functions that return values instead of the values themselves, to allow for "short-circuiting" (latter values are unevaluated if an earlier value is true).
So we approach some kind of functional language land where all data structures are modeled using functions.
Yes, and as you point out even conditional statements.
In Smalltalk constructs like
b ifTrue: [ ... ]
mean that the boolean value 'b' has its method (-function) ifTrue: called with the argument [...] which is a "closure" meaning it is a free-standing function (as opposed to bound functions which are the methods).
There are similarly library methods in class Boolean for whileTrue: etc. Functions all the way.
What would be the point of implementing conditional statements as methods/functions? It makes it posssible to extend the set of conditional statements to for instance 3-valued logic by adding a method #ifTrue:ifFalse:ifUnknown: . And of course it makes the syntax of the language very simple.
Right.. So not only all data structures and operators, but all kinds of control flow can be described as functions. What an interesting way to look at programs, I'll study more in this direction.
I wonder how languages support this question of "unevaluated arguments", like in the `if` conditional function. I guess in Lisp(s) they're simply quoted expressions, and in the above Smalltalk example, it sounds like the syntax [...] calls a function with lazily evaluated arguments.
I think that's right. The "closure" is a function, it is not called until method #ifTrue: of the boolean value in question gets it as argument. But it is not just "a function", it is a "closure" meaning it carries with it values from its outer scope that were there at the time the #ifTrue: -method was called, which includes arguments to the outer method being called.
I wonder, is the quality of AI answers going up over time or not? Last weekend I spent a lot of time with Preplexity trying to understand why my SeqTrack device didn't do what I wanted it to do and seems Perplexity had a wrong idea of how the buttons on the device are laid out, so it gave me wrong or confusing answers. I spent literally hours trying to feed it different prompts to get an answer that would solve my problem.
If it had given me the right easy to understand answer right away I would have spent 2 minutes of both MY time and ITS time. My point is if AI will improve we will need less of it, to get our questions answered. Or, perhaps AI usage goes up if it improves its answers?
Always worth trying a different model, especially if you’re using a free one. I wouldn’t take one data point to seriously either.
The data is very strongly showing the quality of AI answers is rapidly improving. If you want a good example, check out the sixty symbols video by Brady Haran, where they revisited getting AI to answer a quantum physics exam after trying the same thing 3 years ago. The improvement is IMMENSE and unavoidable.
The problem is it's inability to say "I don't know". As soon as you reach the limits of the models knowledge it will readily start fabricating answers.
Both true. Perplexity knows a lot about SeqTrack, I assume it has read the UserGuide. But some things it gets wrong, seems especially things it should understand by looking at the pictures.
I'm just wondering if there's a clear path for it to improve and on what time-table. The fact that it does not tell you when it is "unsure" of course makes things worse for users. (It is never unsure).
With vision models (SOTA models like Gemini and ChatGPT can do this), you can take a picture/screenshot of the button layout, upload it, and have it work from that. Feeding it current documentation (eg a pdf of a user manual) helps too.
Referencing outdated documentation or straight up hallucinating answers is still an issue. It is getting better with each model release though
The way I would approach writing specs and requirements as code would be to write a set of unit-tests against a set of abstract classes used as arguments of such unit-tests. Then let someone else maybe AI write the implementation as a set of concrete classes and then verify that those unit-tests pass.
I'm not sure how well that would work in practice, nor why such an approach is not used more often than it is. But yes the point is that then some humans would have to write such tests as code to pass to the AI to implement. So we would still need human coders to write those unit-tests/specs. Only humans can tell AI what humans want it to do.
The problem is that a sufficient black box description of a system is way more elaborate then the white box description of the system or even a rigorous description of all acceptable white boxes (a proof). Unit tests contain enough information to distinguish an almost correct system from a more correct one, but there is way more information needed to even arrive at the almost correct system. Also even the knowledge which traits likely separate an almost correct one from the correct one likely requires a lot of white box knowledge.
Unit tests are the correct tool, because going from an almost correct one to a correct one is hard, because it implies the failure rate to be zero and the lower you go the harder it is to reduce the failure rate any further. But when your constraint is not infinitesimal small failure rate, but reaching expressiveness fast, then a naive implementation or a mathematical model are a much denser representation of the information, and thus easier to generate. In practical terms, it is much easier to encode the slightly incorrect preconception you have in your mind, then try to enumerate all the cases in which a statistically generated system might deviate from the preconception you already had in your head.
“write a set of unit-tests against a set of abstract classes used as arguments of such unit-tests.”
An exhaustive set of use cases to confirm vibe AI generated apps would be an app by itself. Experienced developers know what subsets of tests are critical, avoiding much work.
> Experienced developers know what subsets of tests are critical, avoiding much work.
And, they do know this for the programs written by other experienced developers, because they know where to expect "linearity" and were to expect steps in the output function. (Testing 0, 1, 127, 128, 255, is important, 89 and 90 likely not, unless that's part of the domain knowledge) This is not necessarily correct for statistically derived algorithm descriptions.
That depends a bit on whether you view and use unit-tests for
a) Testing that the spec is implemented correctly, OR
b) As the Spec itself, or part of it.
I know people have different views on this, but if unit-tests are not the spec, or part of it, then we must formalize the spec in some other way.
If the Spec is not written in some formal way then I don't think we can automatically verify whether the implementation implements the spec, or not. (that's what the cartoon was about).
> then we must formalize the spec in some other way.
For most projects, the spec is formalized in formal natural language (like any other spec in other professions) and that is mostly fine.
If you want your unit tests to be the spec, as I wrote in https://news.ycombinator.com/item?id=46667964, there would be quite A LOT of them needed. I rather learn to write proofs, then try to exhaustively list all possible combinations of a (near) infinite number of input/output combinations. Unit-tests are simply the wrong tool, because they imply taking excerpts from the library of all possible books. I don't think that is what people mean with e.g. TDD.
What the cartoon is about is that any formal(-enough) way to describe program behaviour will just be yet another programming tool/language. If you have some novel way of program specification, someone will write a compiler and then we might use it, but it will still be programming and LLMs ain't that.
I agree (?) that using AI vibe-coding can be a good way to prooduce a prototype for stakeholders to see if the AI-output is actually something they want.
The problem I see is how to evolve such a prototype to more correct specs, or changed specs in the future, because AI output is non-deterministic -- and "vibes" are ambiguous.
Giving AI more specs or modified specs means it will have to re-interpret the specs and since its output is non-deterministic it can re-interpret viby specs differently and thus diverge in a new direction.
Using unit-tests as (at least part of) the spec would be a way to keep the specs stable and unambiguous. If AI is re-interpreting the viby ambiguous specs, then the specs are unstable which measn the final output has hard-time converging to a stable state.
I've asked this before, not knowing much about AI-sw-development, whether there is an LLM that given a set of unit-tests, will generate an implementation that passes those unit-tests? And is such practice used commonly in the community, and if not why not?
I wonder if the same problem exists with AI based code-development more specifically.
To produce an application you should have some good unit-tests. So AI produces some unit-tests for us. Then we ask it again, and the unit-tests will be different. Where does that leave us? Can we be confident that the generated unit-tests are in some sense "correct"? How can they be correct if they are different every time we ask??
In sciences and humanities abstraction is applied the proper way, studying the instances first then describing multitude of existing phenomena by giving names to their common repeating descriptions.
reply