Funnily enough, viewing 27" at 140ppi from 1 meter, my brain mistook the slashed '0' for a 6 or 8 when looking at the headings.
767 karma · joined August 31, 2011
vaughanhackernews at gmail
Funnily enough, viewing 27" at 140ppi from 1 meter, my brain mistook the slashed '0' for a 6 or 8 when looking at the headings.
It would probably be easier if there was a video or scrubber/slider to see how the code evolved.
So many times you look at something and go: why is this so complex. Could be simpler. And you miss an edge case that causes the need for the complexity/abstraction. There are times too though that after a refactor someone can’t see some redundancy or is hanging onto an abstraction that looks great but is unnecessary.
100%. It could be a lot better! I'm very bullish on https://bun.sh changing this!
This can be done with Python/TypeScript code and it would be much more maintainable and typesafe. I don't know anyone who enjoys writing bash scripts over TypeScript code.
> I'm telling them about `--help`
Auto-complete in a text editor is far superior.
> - it always works. usually the same. and everywhere: on my laptop, on my server, on my phone.
This is a good point.
Every single time I use it I would prefer GUI output, and a proper scripting language like Python or JS.
For output I want datagrids with search, sort, group, filter, and expandable rows. Think about how many times you are looking at massive logs of some build and you just want to view the context of one build stage. Or you want to jump back to an error.
It's clear that the database needs to be more integrated in our applications.
SQL is not a good fit for most apps. The reporting/analytics features are great, but that's not what most of our apps are doing these days. This kind of stuff is moved off into other databases most of the time anyway. The core idea of the "relational model" is not a good fit for most apps. Interactive user interfaces are about listening to changes in single models...we don't really care about "relations". Relations are forced upon us to allow automatically optimizing query execution in the database. But this optimization doesn't take into account what other queries we run, so we have to handle caching ourselves, and completely breaks reactivity. People fight against the query planner all the time.
I think the solution is to have control of the query plan.
Without a database, people write code that is similar to what a database is doing, often without realizing it.
Take: `users.map(user => ({user, posts: postsByUserId[user.id]})`. We have created an index, and we're doing an apparent hash join.
Now this usually turns into a tangled mess because of all these adhoc hashmaps we create and pass around. You will see this kind of spaghetti all through modern web apps. The more of these adhoc transformations you have, the more complexity you have because we don't have good tools to visually trace these transformations throughout your app. Your app becomes hard to change. But it also gives us a lot more flexibility when it comes to caching query results.
What would be nice is if our sql dbs were broken into layers, and we had access to the query planner so we can write reactive and cacheable queries. And also that our sql dbs could be run in the same memory space as our app code...which means running in a web browser.
People forget that higher level languages are only to help _people_ understand and organize code better.
I’m waiting for the first programming language or text editor that visualizes your code from the first line you type.
I think there is a new era yet to come.
> probably too complex to visualize in a usable way
You can always abstract the complexity. A simplification of the control flow graph at the function level.
As an example, I want to understand the Postgres codebase better...there are a lot of very visualizable things going on there. If you look at lecture slides on relational DBMS, there are lots of diagrams...so why can't be view those animating diagrams as the code executes.
I was thinking of instrumenting the code to get a trace of every function call and its arguments, and then filter that and visualize it.
The key to this approach working though is a think ultimately we need to write our code and organize our code such that it can be easily visualizable. The purpose of code is for humans to understand it, otherwise we are writing assembly.
You can think of everything as configuration. Parameters of a function are just configuration for that function.
What we need is traceability of every value in a system, not just configuration. You click on any value and you see a graph/chain of all the transformations this data goes through right back to the source of truth. This is how we should code. Think about how difficult this is to do today with your current IDE/editor.
Every task in software is wanting to change what is displayed in a user interface of some sort. Usually you have to make your way through a labyrinth to figure out what to change where, and also what side-effects will occur.
If this is not smack bang in front of your face when you are coding, then you are just adding more and more tangled data flows and complexity to your system.
const dog = new Dog
dog.woof()
Now you see how simple OO is, let's build banking software.But yeh its probably a too broad statement not worth debating on definitions.
We are in the stone-age of programming at the moment.
I think the solution is visualization.
I want to click on any variable, and see its full data-dependency graph. All the functions it flowed through and all the transformations that occurred all the way back to a single source of truth.
With this in hand, I think it would be much easier to understand how to group methods and state. We should write code such that this data-dependency graph is easily understood by humans.
OO is not a natural way of programming. Everything always starts simply with functions that take arguments. Then you have a function that calls another function with some of the old arguments and some new ones.
Most people go: let's make the shared param an instance var.
const config = {}
foo(config)
function foo(config) { bar('bar', config) }
bar(str, config) { ... }
becomes... class MyClass {
config
constructor(config) { this.config = config }
foo() { this.bar('bar') }
bar(str) { ... }
}
The problem with a class, is that every method of the class potentially depends on every other member of the class. What usually happens is that stuff is added to the class that doesn't make sense. And every class needs a noun to name it. Then you have to think what is the proper name for this abstract thing you don't even know what it is yet. Which leads to all these quirky class names that are unnecessary.If you are explicit about what data dependencies each function has, it becomes easier to see the commonality that should be extracted into classes. Most people just shove everything in a class too soon. And most languages push you to use classes and methods...which usually look very different to how functions are represented.
For scripting its a way better choice. `bun:ffi` also makes it trivial to run C or Zig code when you need to.
https://facebook.github.io/watchman/ is a good workaround for now.
This seems like the most obvious thing yet to be built.
I wonder how hard it would be to take an existing systems language and add TS syntax to it. Seeing as they are all built on LLVM. Or maybe you could transpile TS to Zig.
It wasn't.
I guess it might be good for dynamic apps, but I just love having control over exactly what I a printing out. I'm still looking for a way to write cli apps that also can be accessed from a browser. I always find myself wanting better log viewing functionality - like folding, grouping, search, etc. But there is something so nice about the terminal vs gui. I always avoid gui because the toolchain is horrific and then you have to think about the API layers and everything becomes overly complex and slow.
When I was in school, a lot of teachers did a little tidbit of history at the start of topics, but I never latched onto it and found it boring. It was only after my studies that I started to really love going back to the origin.
It’s interesting - like a mystery revealed, but also provides the why - why things are the way they are.
I was looking into accounting the other day, and you can go back to the first document that mentioned credit and debit and introduced modern accounting. There are so many topics like this that seem confusing and arbitrary but it all began extremely simply and pragmatically. Music theory is another example of a fun topic to study historically. And programming languages and operating systems.
It’s important to use two learning paths though: historical and modern scientific. Historical usually explains terminology and legacy aspects of such topics, but then topics can also be explained by using modern technology to experiment and observe.
Think about unix - it was primarily designed for very low power low memory environments. And databases too. You can learn a lot poking at an existing system, but when you watch the early content on it, you see the why.
I wish people would prioritize this more.
With every new langauge that comes out, sure it brings a few interesting features, but it always takes 5+ years for IDE support, a good debugger, and compile speed (if ever) to arrive.
Good debugging tooling and compiler speed probably outweighs all the other benefits in the long run. Rust is a good example. JavaScript transpiling too. And once it arrives, people will probably be onto the next new language that barely has IDE syntax highlighting ready.
> pythons horrible package management
It really is terrible. The import system is so convoluted, but I guess it's quite old.
Python really needs a good monorepo-friendly package manager like Node's pnpm.
Even though the ESM transition is a clusterfuck, the new module system is actually quite nice and straightforward if you don't need to touch older code.
I dream of an IDE that is one-click, full-stack, local debug.
I dropped some ideas here: https://news.ycombinator.com/item?id=35650253
> What is a (somewhat) pure mapping from the model is the data that is displayed in the UI, but not the entire UI.
This line was interesting to think about.
React added so much complexity and perf issues, and I really don’t know what was so bad about something like Backbone / Backbone.Marionette.
I find that in React I want all component props and data to come from an external store via subscription, instead of being passed down some tree. My UI is stable.
The `/` root dir is quirky. You can’t just do `dirPath.split(‘/‘)`. You have to handle it as a special case. Would be easier if it had a special name. Like `$/dir1/dir2`.
Or am I missing something.
In my ideal world, my database would know about all the queries I want to run, and it would choose query plans based on this knowledge to effectively cache things, and handle streaming changes to queries.
You also want to be able to visualize the full data dependency graph of all your data, i.e. when this value changes, what else changes.
We need to get rid of all these poor-fitting abstractions between the database (REST, GraphQL, etc.). Your client code should work with a model exactly the same as how its stored in the database. In fact, your entire database should be able to run client-side in the browser. This is what is holding us back. This would allow optimisitic updates, and easy local/offline apps. I think people usually avoid this because they like to chose a different language for their backend and the thought of getting this to run in a browser is frightening.
Just think how much easier your life would be if you had direct database access in your browser from your client code, and you didn't have to worry about apis, orms, etc. and that it was secure, and synced automatically.
And now think about your current application you work on, and the difficulty in achieving such a thing.