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

They are, but a REST API likely isn’t a good alternative because few RDBMSes speak REST. More likely they meant creating a database interface library in whatever programming language the application uses. And then have it talk to the DB through that library instead of scattering a fine mist of ad-hoc querying (or, shudder, active records) throughout your application.

The client of the REST API is not an RDBMS. The REST API serves application clients - may be browsers, may be other services. The REST API alone talks to the database.

An API that serves only backend applications could be implemented in stored procedures instead of REST or GRPC. It could also be implemented in SOAP, CORBA, DCOM and other fossils, but no one is doing that for new applications.


For one example, I might choose against stored procedures when I’m at an organization with internal policies or a devops setup that makes schema migrations costly and I expect the table and indexing structure to change less frequently than the queries.

That does not mean I’d let the queries devolve into chaos. Just that I’d do the query management and change control in a way that’s more pragmatic in light of other realities.


I used to be pro-sproc, but I agree that making queries part of the database schema can be burdensome and creates some development friction that I’d rather avoid.

I’ve mostly moved on to storing queries as *.sql files in the application’s repository. You still get the good query caching and predictable plans. But you also get some other nice perks, like queries and the code that uses it being versioned together, and making it easy for developers to test queries in a SQL console. Most editors even have plugins that give you autocompletion and basic error checking in exchange for a connection string to the dev database.

That latter bit is why I don’t love inline SQL in string literals or ORMs’ querying DSLs. Both discourage tinkering with queries to observe how they work. I believe that’s a major reason why it’s so common for developers to commit awful performance sins like computing aggregations on the client side. It’s hard to expect people to get comfortable with SQL window functions when the project’s database interaction is set up in a way that actively discourages doing so.


Way back in the aughties I saw an interesting analysis (on a now defunct blog) indicating that under typical usage C# implementations tend to outperform C++ implementations in long-running business applications. The supposed reason was that C#’s compacting GC keeps the cost of new allocations fairly constant. By contrast, in C++ under typical use every new allocation requires probing for a sufficiently large block of free memory in an increasingly fragmented heap.

I haven’t tried to replicate this for myself. And, even assuming for the sake of argument that it was definitely true back then, a lot can happen in 20 years. But still, it does speak to wanting options when performance really is critical.


Zig is aiming to be lower level than Rust. As the project homepage prominently advertises, it has no hidden memory allocation or control flow. It also gives more control over how memory is allocated, which is potentially useful in applications with particularly tight performance requirements.

Kelley first created Zig when hr was working on a digital audio workstation and found most existing languages to be awkward for working with particularly hard real time requirements, but still wanted something more modern than C. Im speculating here, but I believe its advantage over Rust for that specific application is that you have tighter control over exactly when memory is allocated and deallocated, and how data is laid out in it. Rust wants to tie allocation lifetimes to scope in a very fine grained way that I would guess is beneficial the vast majority of the time, but does still make it harder to reason about when you’re about to stall out the CPU while the allocator does its thing.


> it has no hidden memory allocation or control flow

Rust had like 3 allocating types total. If you aren't working with extremely deeply nested 3rd party types it's trivial to identify when allocations happen. Hell you could throw a lint rule together in like 5 minutes to warn on it if you're really worried. Besides Drop (excluding async) is there even any hidden control flow?

> Im speculating here, but I believe its advantage over Rust for that specific application is that you have tighter control over exactly when memory is allocated and deallocated, and how data is laid out in it.

Rust has almost exactly the same semantics for controlling allocations and deallocations, it just prevents you from screwing it up and not freeing something or using the allocation after freeing it. You still have to pass around your reference in your call stack until you no longer need it.

> Rust wants to tie allocation lifetimes to scope in a very fine grained way that I would guess is beneficial the vast majority of the time, but does still make it harder to reason about when you’re about to stall out the CPU while the allocator does its thing.

It's really not substantially different. You allocate ahead of time or don't allocate at all. The only real difference is you might want to use an Option instead of an uninitialized pointer because it's semantically more correct and harder to screw up.


But here I feel like we’re at risk of heading down the same old doom spiral that plagues any conversation about programming languages when people try to treat it as a competition: getting pedantic about what’s technically possible in a language. It’s much more interesting to talk about how a language wants to be used.

So, in the case of Zig, every function that wants to be able to allocate or deallocate heap memory needs an explicit reference to an allocator. That means that you can tell whether a function might allocate memory from its signature. It also means that changing a function so that it can allocate is explicitly a breaking change.

That’s a really interesting design decision. And the reasons why someone would or would not want something like that baked directly into the language are so much more interesting than bickering about how technically with proper discipline you can have that kind of control in any non-GC language.


> That means that you can tell whether a function might allocate memory from its signature.

In practice that's not the case, as many objects own a reference to their allocator. It's still explicit, but it might be hidden in the signature, especially if you have some sort of interface that can take an allocating and a nonallocating data structure alike.


I agree with you, but it’s not baked directly into the language? It’s just a convention and a shared trait?

Not original commenter but the reality with zig is a little in between being simply convention vs. a language requirement. Is it a language requirement? no.

However, there's no global allocator in zig. You simply cannot call the language's equivalent of malloc() because it doesn't exist - at least not as a global symbol. That leaves you with three choices: 1) Define a global allocator; is a valid choice and would make a zig program more like C, C++ or Rust in terms of not having to think about scope-level allocation patterns 2) Pass an allocator into that scope (this is the community convention) 3) Create/instantiate an allocator itself inside that scope

(1) would be valid, though may not be idiomatic; global allocator like malloc becomes an opt-in

(2) Expensive and inefficient for most scopes, though not all.

(3) cheap, idiomatic but potential for noise/boilerplate


> However, there's no global allocator in zig. You simply cannot call the language's equivalent of malloc() because it doesn't exist - at least not as a global symbol.

I mean std.heap.page_allocator is global, and there's only the one, and you can call it from wherever (just as you can malloc). Same with std.heap. c_allocator, which is... malloc! you can also create your own global allocator.

Don't do this in libraries ofc or the ghost of Andrew Kelly will haunt you in hour sleep.


I think you switched 2 and 3.

I wish people would stop inventing new languages for nostd when we have nostd

> Rust had like 3 allocating types total.

Seriously? Categories of types maybe, but literal types it's more than that.

Even closures allocate if they need to capture their environment.


It’s actually the opposite: the language has zero allocations in it. Allocation is entirely a library concern.

When you want to have a closure allocate an environment, the closure itself does not: the Box you wrap it in, which is a stdlib type, does.


> Zig is aiming to be lower level than Rust.

Zig and Rust are equivalently "low level". Zig isn't any closer to the hardware than Rust is.

> but I believe its advantage over Rust for that specific application is that you have tighter control over exactly when memory is allocated and deallocated, and how data is laid out in it.

Rust gives you all this, too.

Zig's primary (possibly only) advantage over Rust is that it has much faster compilation times.


.map is definitely not low-level

Comptime is a big one too. You can achieve similar things in Rust with generics and macros, but comptime makes certain things easier (and other things harder).

Further up he discusses that using a functional paradigm is possible, but concludes that it doesn’t feel like a practical choice because of how Zig does memory management:

> But the language quickly forces you to diverge from the functional style, mostly because you’re now dealing with allocators directly, and a genuinely pure functional approach means constantly constructing new structures. That’s either expensive in memory or expensive in the manual bookkeeping needed to avoid it.

So I don’t think he’s trying to say that it’s literally impossible. It felt more like the result of a good faith attempt to understand how Zig itself actually wants to be used, and to compare that to how he’s used to using Rust.

I actually liked that he did it. So many other comparisons want to evaluate one language against the other language’s values. But I don’t want to know how well Zig can do Rust; I want to know how well Zig accomplishes its own goals, and what those goals are.


As someone who mostly only applies math, that strikes me as a peculiarly academic take. Intuition is more important for me because it’s what enables me to know what methods are most applicable to whatever practical problem I’m trying to solve. The proof’s purpose is to verify my intuition. It’s just a means to an end. I only take the time to do my own when I can’t confirm what I need from a textbook or paper.

> As someone who mostly only applies math, that strikes me as a peculiarly academic take.

Yeah I was talking strictly about preparing students to become pure mathematicians. No opinion here on other goals.


If what you teach is proofs, then wheat you will filter for are students who live proofs.

And if your job is to train people to become mathematicians, that is absolutely what you should be doing.

The idea the proofs are the heart and soul of mathematics is an unfortunate unforced error, and will lead to the death of the professions now that machines are better at making proofs.

or memorize a few

Love is more important than breathing. It is and it isn't.

What good is an end you can't reach, or worse, you can reach but it's wrong?


Your unstated major premise here is that their intent was to make a universal statement about how proofs work and not just talking to humans about how they teach humans.

That premise seems unlikely to be correct.


Why? The entire subject of conversation is triggered by things which are not humans producing proofs.

If it's possible for a machine to produce a proof without intuition then clearly a human could also do it too. (And in fact I'd argue I've seen many people like that, simply very good at pattern matching over memorised items).


Because regardless of the point TFA is making, that interpretation makes less sense for the specific comment. It doesn’t fit with the immediate context, which was a response to a thoughtful comment about how humans do math. And it requires assuming a math professor doesn’t understand a very basic and obvious thing about their area of expertise.

That doesn’t really read as good faith engagement in the discussion. At best, it reads as being so AI pilled that you can’t even fathom that others might want to have a little side discussion about something other than AI.


You realize the commenter has now confirmed my interpretation was right?

What is up with this whole sub thread of obvious hole digging?


That math prof was talking about his stance in discussion between mathematicians long before AI.

Plus, I studied math, I am from that environment. His description matches how math is done by people.

People who are good at pattern matching and memorize are, frankly, shit mathematicians. They are find in fun culture around math, but rarely in actual math. They cant really do it as science.


Network effects were also nowhere near as strong as they are now.

BSD is a killer example of that point, too. Using a BSD Unix got to be pretty difficult after Linux containers became hegemonic.


It was a bit challenging long before that. I ran webhosting on FreeBSD in the early 2000s - remember finding a tool you needed and hoping it was in ports?

You would have a heck of a job convincing a court that 60% domestic market share in a two competitor market constitutes a monopoly.

Then how is Google a monopoly at 40%?

It isn’t, and nobody said it is. The ruling in question did not find that Google had a mobile OS monopoly. It found that they had monopolies in both the ad server and ad exchange markets, and was using them to reinforce each other in an anticompetitive way.

That’s not the metric under which Google is seen as a monopoly, and you know it.

It’s search. And ads.


No I don't know it. Is that what echelon meant when saying Google needs to be broken up?

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

Search: