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

Nice article.

I miss one of the most important points for me:

C is a very easy to learn programming language (I explicitly do not claim that it is easy to write correct/bug free programs in C) and for me even more important: The mental model of a computer/abstract machine that C exemplifies (memory, pointers, pointer arithmetic, functions) is unbelievably useful for understanding and coming to terms with nearly all kind of programming languages/computer programs. Of course the mental model is wrong, but boy is it useful.

Would I start a new project in C if I can help it? Never. Would I use any other language than C if I want to implement a small part of a program which benefits from a C like low level language? I would not say never, but I do not see any candidate language at this moment. Especially because small programs in C IMHO are manageable for a reasonable experienced programmer.

I would love to life in an alternate reality where something like LISP/Scheme would be the basic model of computation (lambda calculus) and everything else would build on this as a useful mental model, though! :-)


By now I stopped counting the attempts to replace SQL.

There is a lot of valid critic for SQL and I would be very happy if some things would have been designed different.

OTOH the architecture and mathematics behind relational databases are simple, composable and stood the test of time more than most other designs, methodologies or approaches to software development.

Though SQL can be improved, even with my average SQL skills I never had trouble getting information out of a database and fancy stuff like window functions make to my understanding even standard SQL Turing complete.

SQL has the native database support, for most companies the data and the database will outlive any specific application or even the whole ecosystem of a programming language/platform (Visual Basic, Visual FoxPro, Python 2, ...)

Further, we have fantastic books, knowledge, ORMs, query builders and a gigantic ecosystem in tools for SQL and SQL databases.

Acadia might be brilliant from a technological point of view, but it does not matter, because it does not look like a big enough improvement compared to SQL that it seems worth to invest in it. I will rather improve my knowledge of standard SQL or my knowledge for a specific relational database.

Finally Acadia does not really seem to raise the bar compared to other ORMs/Query builder. I get that from a FP point of view map/filter are nicer than a SELECT ... WHERE, but at some point in the projects I participated one would end up interacting directly with the database anyway, and at that moment I am back at SQL, so what did I gain?


SQL has one flaw: The verb should come last. So, "FROM users WHERE id = 1 DELETE" or "FROM users WHERE email = '[email protected]' SELECT id". That'd cut back on some accidental "oops I dropped the whole table" because I submitted a delete query before writing the where clause.

Other than that, it's perfect, no notes.


The part that has stood the test of time and genuinely seems to carve reality at the seams is the query part. The data definition and data manipulation parts are just ok.


Even so, "FROM t SELECT t.foo, …" has an ergonomic advantage over "SELECT t.foo, … FROM t" in that editors can autocomplete column names without needing to backtrack while editing.

IIRC, this is why C# query syntax uses the former.


The problem with the query part is that query fragments aren't composable.


CTEs are how you compose SQL.

I don't quite like how the same CTE lives in 60 different places in my codebase, but at least the WITH clause changed things for me.

Also really liked Snowflake's result_scan for composing chains, mostly because I don't rerun expensive parts again and again. You can use ->> as a shortcut, but I don't think it uses results caching internally to skip waiting for them to all re-run & actually optimizes the whole thing.


you create one view and have the ctes query that, to deduplicate the implementation


Agreed, however it gets easier when using SQL plugins on IDEs, instead of raw cmdline admin tooling.


SQL is based on the relational model but doesn't really conform to the mathematics e.g. doesn't exhibit set semantics.


Sets and bags are trivially interconvertible so it's really not a big deal: https://h2.jaguarpaw.co.uk/posts/set-bag-irrelevance/


The point is if you're doing relational algebra you want to work with relations. The key reason why set semantics are nice is because the operations are guaranteed to return relations, so you don't have to check or make accountings of which return values are sets and which are bags, or worry about machinery to convert between the two.

It's like how you can store numbers internally as floating points or rationals and trivially convert between the two. But if all you ever do is floating point math, you might prefer to store the numbers as floating points rather than rationals and then convert to floating point.


I don't think that's actually what one wants in practice from an RDBMS, but if it really is then one can add UNIQUE to all your SQL queries and get it. SQL is not somehow lacking in that regard.


Can you elaborate?

It can't express every mathematical set operation, but it does have UNION, EXCEPT, and INTERSECT.


A result in SQL can contain duplicate items unless you tell it explicitly to deduplicate, so uses multiset/bag semantics. The relational model is built on set semantics, where every item is unique. Just because it can express those operations doesn't mean the idea is baked into the language semantics. e.g. the difference between Haskell and Python + first class functions; you can do functional programming in Python but it's not a functional language.


What they're saying is: The relational data model and algebra are based on set semantics. Relations (equivalent of SQL's "tables") are sets of sets (tuples), not bags of "rows". There's no such thing or possibility as duplicate tuples ("rows" of "columns").

This has a number of elegant properties (and also improves the kinds of optimizations a query planner / execution stage can apply.)

A similar divergence is that the relational model has no concept of nulls. Presence/absence is expressed through "item not in set" in various ways, and by properly normalizing the data.

SQL also isn't properly expression oriented or composable at all. A relational algebraic language absolutely can be, and can lend itself to much more elegant data handling.

In many ways SQL is to "relational" like Java or C++ are to "object oriented" -- it got in very early to market, got mainstream success, and dominated the field, and in so doing it mangled people's perceptions of what a database is, and also made people either define "relational" as "SQL" (sigh), and even worse because they misunderstand what relational is while also hating SQL, they try to throw the baby out with the bathwater with their successors.


Relations also have no concept of ordering. But bag semantics is both closer to efficient implementations and closer to user expectations than set semantics. Using set semantics everywhere also makes queries harder to optimize, because you have to selectively "de-deduplicate" for efficiency, instead of just sticking DISTINCT operators where they're needed.


> In many ways SQL is to "relational" like Java or C++ are to "object oriented"

Very cogent.


I disagree.

LLMs fail to produce bug free concurrent code even for very simple cases.

Golang lacks the ability to build descent abstractions, not even mentioning the wild west of additional tools and libraries needed for non trivial micro services.

For me it is a red flag, that LLMs allow people to produce more bad Golang code faster. This is only optimization for companies which can afford enough software developers to review the excessive amounts of code needed to solve trivial problems in Golang, which are builtin in every descent programming language and/or framework.

Use LMMs and use the right programming language. This might be Golang, but most probably it is C#, Java, Python, Ruby or even PHP. (Or Rust, C, D, ...)


Broadly agreed, the concurrent Go code I've gotten out of them has been absolutely riddled with issues, and they're even worse at writing tests for it. They can get tutorial-level code on the first shot almost always... but tutorial-level Go code is often rather unusable in production due to missing error handling or observability.

Go's generics are getting a fairly important improvement soon though! Generic methods, finally! It should help open up some more ergonomic patterns: https://tip.golang.org/doc/go1.27


This has not been my experience at all with gpt sol on ultra/max. Some concurrent code is just really really hard to write and even in those cases LLMs can help, the barrier for extensive thorough testing and writing your own custom simulator, liveness and correctness tests is simply so much lower now.


Ask them to debug. LLMs are acceptable at writing code, but they're really good at spotting bugs in code that's already been written. What kind of results do you get if you tell them to look for bugs with a clean context subagent?

In my experience, LLMs are excellent at finding concurency bugs.


Debugging concurrency issues isn't a syntactic process so they have to resort to println debugging. This works but isn't exhaustive and burns a lot of tokens.


They do a fantastic job just by inspecting the source. It's obviously not exhaustive, but it's quite good.

Test it on your last concurrency bug. Point fable at the rough symptoms and ask to find where the issue is by inspection. It'll probably do just fine.


Thanks, we (Linux/BSD) users cannot bring up this topic often enough.

I totally understand, that it cannot work unless money is there, which simply is not, in the Linux desktop world. Compatibility is expensive, hard work and not much fun.

I do not think, this will ever change, in the end, the web/Electron has won, desktop operating systems are less important compared to mobile, so who should invest in a stable GUI platform for Linux?

By now, basically all applications I rely on are CLI programs (posix), web or Electron and a few simple GUI tools (PDF viewer, ...) which can easily replaced.

How is the saying: If you want a portable GUI application for Linux, target Win32 and run it via Wine.


Amen.

It is so frustrating... in tech circles, it is widely known/understood for at least 2 decades, that an open file/data format is much more important than open source software.

Just make ODF the mandatory file format and be done with it. (Yes, I know, old documents and the work of transforming ... but if we do not start right now, when would be a better time?)


Mandatory where? it is already the preferred format of the British government, and I think I have read about other adoption, and as well as some governments adopting open source office suites which would push them towards ODF.

Other governments could follow, but the private sector is reluctant. Even Airbus which is a high profile move away from MS has gone to Google Docs.



For the record: I have a terminal open at all times, my life is automated trough Bash scripts and I am a VIM / TMUX user.

With that background, most TUIs are really two steps back compared to a decent GUI. (Wild west navigation/hotekeys, broken copy and paste, lack of integration with the environment, just to name a few.)

The core of the problem is IMHO, that we really lack a decent cross platform GUI platform, which is really integrated into a programming language or part of the standard library.

Outside of Swing (which lacks access to a native browser element), we have Tk (no browser component, no drag'n'drop, at least from Tkinter), wxWidgets (seems that the community is very small and especially its bindings needed to be resurrected at least once), Qt with the ever looming possibility that it will get deshittified to make more money (... and no, KDE is not that important and I doubt the KDE community could take care of a fork long term).

Which leaves us with Electron or the other variants of 'browser component + JavaScript/CSS and callbacks to a local server, which is a really bad programming model (ignoring the memory/runtime overhead for even trivial applications).

The problem is, to build a decent cross platform gui toolkit, one needs a lot of funding and a lot of people (usability, accessibility, design, documentation, testing...). The open source community didn't manage to pull this off (GTK is by now for all practical purposes Linux only) and there is no modern contender for Qt or Swing (with their own problems).

TUIs are no solution to the core problem (and it would be absolutely possible to have a GUI toolkit with a TUI renderer for perhaps 80% of GUI needs), but I understand every developer who chooses TUIs for cross platform UIs given the alternatives.


> which is really integrated into a programming language or part of the standard library.

Not a programming language, but the programming language: C. The toolkit needs to be available as a C API because that lets it a) provide stable API and ABI and b) provide bindings for multiple other languages without having to jump through hoops, especially for other compiled languages (binding Qt to Python might be easy, but bindings to something like, e.g. Free Pascal requires an intermediate C++ library that exposes a C API that itself can be used from Free Pascal - and applications need to distribute it that library too).

Unfortunately the vast majority of GUI toolkits are not writtne in C but in C++ or some other language that makes using them from anything than the developers' favorite language a pain. And really the only mainstream that is written in C is GTK which has a complete disregard for proper backwards compatibility.

(you may think that a library only needs to expose a C API but it can be written in any language, however for something that doesn't have any widespread availability, you may want to link to it statically - however that can be an issue with anything outside C/C++ - as an example i recently tried to make a FLTK backend[0] for Lazarus since FLTK is a C++ library that the devs encourage to link it statically and it would allow creating GUI programs that are self-contained binaries... but statically linking a C++ library -for which i had to first make a C wrapper- in a non-C/C++ turns out to be a PITA under Linux if you are not g++ as that does passes a bunch of magic flags to the linker and impossible under Windows - or at least msys2, so i gave up).

[0] https://i.imgur.com/W6XbLkr.png


Nicely written and I totally agree with you.

I like, that you also added backwards compatibility and ABI stability, two very important and valid points. There is to this day the joke, that the best way to write a binary GUI app for Linux is to target the Win32 API and run it via Wine, if you care for a stable platform. ;-)


I think you are right and completely agree with most of your points.

> wxWidgets (seems that the community is very small and especially its bindings needed to be resurrected at least once)

Which is a damn shame because they are very close to native appearances on both macOS and Windows and are much easier to program than anything Qt. I think it’s the solution I prefer for multi platform GUIs, both as a user and as an occasional programmer.

> Electron or the other variants of 'browser component + JavaScript/CSS and callbacks to a local server

On the other hand, I absolutely hate this as a user. I would lose features and go back to the command line rather than having to deal with this. Everything is wrong in these applications, they don’t support standard keyboard shortcuts, they look weird and out of place and lag where you least expect it.

> TUIs are no solution to the core problem (and it would be absolutely possible to have a GUI toolkit with a TUI renderer for perhaps 80% of GUI needs)

There are a couple of TUI framework that are almost there already. I like the fact that they are useable without fuss over ssh and stuff but I think they are solving the wrong problem. I would rather use something like tmux but that sucks less for the windowing and persistence bits and get more focused and composable CLI. Make a simple REPL with readline so it has a standard and expected behaviour instead of trying to make everything look or behave like an IDE.

OTOH, I really like how this is driving improvement in terminal emulators.


Thank you very much, and I also agree with your points: Electron Apps simply never feel right, even if I work within them all day (VS Code for example).

I also agree, wxWidgets is quite great, although I have to also agree with the comment above, that C++ for a GUI library is just a PITA when used from any other language. AFAIK the consumers from wxWidget (wxPython, wxErlang?, ...) are using a C wrapper around the C++ wrapper to use it.


What really annoys me about Python, is that a lot of problems that the language/infrastructure/community has can easily be tracked back to well understood problems that have been solved for decades in other communities. Some of these problems have been fixed with breaking changes, some others probably never will be fixed.

Just a list of bad/wrong decisions IMHO:

- Reference counting instead of using a real garbage collector

- The pyproject.toml format is under-specified, comes decades too late for a problem that has been solved good enough by Apache Maven more than 2 decades ago

- The absolutely weak support for functional programming, which then was patched by list comprehensions and co later

- venv and other solutions to isolate dependencies for a project

Python is successful because of the community support and a binding to almost everything, and this sadly outweighs a lot of poor choices from the language designers and the implementation. I just always feel frustrated, that during the great breakup from 2-3, they didn't try to fix more of the known issues (which again, have been solved by other communities decades before) instead of breaking the world and still managing to half ass it.


> I just always feel frustrated, that during the great breakup from 2-3, they didn't try to fix more of the known issues

Absolutely agreed. I would rather they left 2.x in someone else's hands entirely. Instead they were ultimately forced to produce 2.7, wheedle and bargain to not have to produce 2.8, and give 2.7 an extended support window instead; and they still got complaints and abuse from people upset about making changes that were generally quite easy to make.

I would still have completely switched to 3.x (at least when it appeared ready) simply based on it coming from the same team and advertising the main features and fixes that it ended up with.

> Reference counting instead of using a real garbage collector

This is not explicitly part of the design. You are free to use other implementations.

But before the `with` block was added (in 2.5), reference counting was useful for deterministic cleanup.

> The absolutely weak support for functional programming, which then was patched by list comprehensions and co later

I'll give you this one. GvR actually didn't like this stuff very much, which is how `reduce` lost its builtin status. The basics can take you really far, though. The important thing is that functions are first-class objects.

> venv and other solutions to isolate dependencies for a project

There is nothing fundamentally wrong with venvs. 99% of the complaints I hear about venvs are not actually the venv's fault. (They're usually pip's fault. Pip is bad.)

A venv is literally just a place to put packages (organized roughly the same way the system packages are) and a simple scheme for enabling Python to understand where that place is (so that `sys.path` can be modified at startup). Every other possibility has the same problem: either you have to learn one or more options for telling Python to use that package location, or it works by magic (which means eventually you have to understand the magic, and anyway "Explicit is better than implicit").

> The pyproject.toml format is under-specified, comes decades too late for a problem that has been solved good enough by Apache Maven more than 2 decades ago

pom.xml is not at all "good enough". The pyproject.toml format is actually quite detailed (https://packaging.python.org/en/latest/specifications/pyproj...). It also has explicit design goals of a) allowing arbitrary tools to store their config and b) being human-readable and -writable.

More importantly, Python didn't have something like Maven in 2004 alongside Maven because Maven only has to worry about Java code; the Python packaging system has to worry about potentially every programming language, and very commonly C, C++, FORTRAN and now Rust. In 2003 (with Python 2.2) it got `distutils`. That was designed (and Setuptools picked up the torch) to use code in `setup.py` for everything, because nobody had any concept of a real "ecosystem" yet (see if you can find some archives of the Cheeseshop from its first year, if you dare) and it was simple and seemed Pythonic at the time.

And now we're in a thread where OP is upset that Python code doesn't work for 30 years, which seems like a pretty common take. It turns out that when you accommodate backwards compatibility, it gets in the way of actually fixing old problems quite a bit. There are still projects out there that are just Python code that could be perfectly well built using Flit, that are using (slow!) legacy setup.py-based build setups. Not because there's anything wrong with pyproject.toml for their purposes (there absolutely isn't), but because nobody is forcing them.

People don't even keep their setup.py contents up to date, let alone pay attention to any kind of deprecation warnings. Literally the only thing that gets anyone to do anything is to break their setup, and then for most of them their action is to complain and make the Setuptools team put things back how they were.

I'm not just talking about random developers on tiny forgettable projects, either. I'm talking about PSF-managed projects like Requests that:

* are pure Python code

* are among the most popular packages on PyPI (Requests is top ten)

* had their "source builds" break this year (https://github.com/psf/requests/issues/6775) because of a removed import in setup.py for something that nobody has actually used for years (a legacy testing setup that has been completely abandoned since the project uses tox)

* already had a `pyproject.toml` file but weren't actually using it to store even basic build configuration (still in `setup.cfg`, so they had all three files for really no reason).

(Thankfully, something is actually getting done in Requests. Supposedly. The work for this was apparently "already done" in May 2024 and is supposed to appear "in the next minor version release". The last release as a patch release this August. The main branch of the repo doesn't reflect this work.)


Does anyone know, how this compares to [autojump](https://github.com/wting/autojump)?

Could not imagine using regular cd for navigating file systems anymore.


The creator is actually in this thread now [0] and said that they passed ownership and it now unmaintained and recommends using zoxide instead.

[0]: https://news.ycombinator.com/item?id=45346715


Programmed over the years in almost all mainstream programming languages at one time or another.

Saying this, Java was and is in many ways one of the best ecosystems to write software out there, if not the best (when it comes to server side software).

Maven is my favorite build systems so far: Default directory layout means everything has its place, IDEs can easily open any kind of Maven project, and being declarative, one can easily analyze pom.xml files. (I hate writing XML and I still like Maven.)

The next thing is Javas standard library. Well documented and big. Has it better and worse parts? Sure! But what people which never used a language with a good standard library don't get, is that even a bad standard library which is widely used is far better, than the npm-of-the-week clusterfuck, which means that nobody can read three lines of code and really understand, what is happening.

The IDEs are top notch, and you get even free ones (NetBeans, Eclipse) which can rival JetBrains and Visual Studio easily.

... and finally, Java is the only language that I know of, which has multiple strong companies and initiatives behind it, thanks that nobody trusts Oracle (rightfully).

Finally, Java code also got shorter, DI style is IMHO a very good default in any programming language (OOP, FP, Imperative), the community settled mostly on JUnit, so there are never discussions which of the 23 competing test frameworks to use...

In the end, there is a lot of rightful criticism of Java (historical baggage, too late when it comes to AOT, no modern GUI frameworks and a steep learning curve). Java getting new features with the new JDK releases is kind of double edged sword: Many things are good ideas, but they make the language more complicated at the same time.

The verbosity was IMHO never a big thing, because Java was always meant to be used in an IDE, for bigger projects explicit trumps implicit and finally newer revisions introduced stuff like 'var' statements etc.

It is kind of sad, that the Linux community never really jumped/accepted Java for desktop development (which might be explainable, when looking back at the lack of speed of Java in the 90s and the disastrous Solaris Java apps which were simply to slow to be usable).

Anyway, for work I am now using Golang, and it is hilarious how many lessons Golang did not learn from Java, when it comes to language design, although the tooling is top notch and the standard library has at least almost everything needed for writing backend services.

I don't see Java making a comeback, and I don't see anything modern going to replace java at the same time.


IMHO there are a lot of problems with the advice from Eskil.

His ideas about abstraction of the platform made a lot of sense in the past decades, but IMHO are not that applicable nowadays: It is well understood to separate domain logic from UI and storage, and a desktop application has a very different UI from a mobile app or even a web app.

My next critic point is, that Eskil assumes all domain knowledge is there from the beginning and will not change over time (his idea of having perfect APIs from the beginning).

No mention about error handling, reliability, response times, atomic operations etc.

To make it very clear: I believe Eskil gives his advice in good faith and his advice served him well in his own projects. In my opinion most of his advice is just not good advice in general.

(Besides having modules as black box building blocks if possible).


Yeah, I think the first mistake is thinking 'large software project' is specific enough to have any good advice at all.

Large software projects could include AAA console videogame, or banking mobile app, or embedded vehicle entertainment system, or airport baggage handling system, or hundreds of other totally different domains.

The only good advice I can think of is given a large software project try to hire someone (or a whole team) that have built something pretty similar before.


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

Search: