Functional programmers need to take a look at Zig

xngbuilds 54 points 32 comments April 30, 2026
pure-systems.org · View on Hacker News

Discussion Highlights (12 comments)

dnautics

io is not a monad. theres nothing stopping you from stashing a global io "object" and just passing the global wherever you interface with the stdlib. It's dependency injection . and yes, you can model dependecies like a monad but most people, even in less pure fp langs, don't. i don't really say this to just be a pedant, but if you're an fp enjoyer, you will be disappointed if you get the picture that zig is fp-like, outside of a few squint-and-it-looks-like things

jstanley

> Noise is anything that must be written for the program to function that is not relevant to the domain. > ... > What facilities does the language provide me to create correct-by-construction systems and how easily can I program the type-system. Isn't programming the type-system orthogonal to the program's domain in the same way that manual memory management is?

pyrolistical

I don’t get it Why write: EqPoint.eql(a, c) When you can write: Point.eql(a, c)

continuational

Do you really prefer this: fn Maybe(comptime T: type) type { return union(enum) { value: T, nothing, const Self = @This(); pub fn just(the_val: T) Self { return .{ .value = the_val }; } pub fn nothing() Self { return .nothing; } } } Over this? data Maybe a = Just a | Nothing

voxl

A functional programmer who casts away proper sum types and pattern matching is no functional programmer at all

givemeethekeys

Isn't the whole point of abstraction to not care about whats underneath unless you really have to? But ideally, you don't because the abstraction is "good enough"? I haven't heard anyone writing code in Elixir complain about performance issues.

NordStreamYacht

I'm still fighting with Elixir and losing - for some reason I can't get my head around all the slightly different ways to initialise stuff.

drgiggles

It’s possible (even true in my opinion) that garbage collected functional languages and low level languages like Zig are both great, and serve different purposes. I actually ship stuff in Haskell believe it or not. I also think Zig is very cool and have played around with it quite a bit. Yes, garbage collection hurts performance, but the reality is that the overwhelming majority of all software does not suffer from the performance loss between well written code in a reasonably performant functional gc language and a highly performant language with manual memory management. It’s just not important. But not having to deal with the cognitive overhead of managing memory and being able to deal in domain specific abstractions only is a massive win for developer productivity and code base simplicity and correctness. I think OxCamls approach of opting in to more direct control of performance is interesting. I also think it’s great that many functional patterns are making their way into imperative first languages. Language selection is always about trades offs for your specific use case. My team writes Haskell instead of Rust because Haskell is plenty fast for our use case and we don’t have to write lifetime annotations everywhere and think about borrowing. If we needed more performance we would have no choice but to explore other languages and sacrifice some developer experience and productivity, that’s very reasonable. I’m also not saying performance doesn’t matter (if you’re writing for loops in Python, stop). But this read to me like “because better performance exits with manual memory management, all garbage collectors are bad, so I’ll force zig to be something it’s not in order to gain performance I probably don’t need”. Which to me is an odd take. A more measured way of thinking about this might be, it can be useful to leverage functional patterns where appropriate in low level languages, if you find yourself needing to write code in one.

faangguyindia

These days I just use a few languages: 1. Go, when I first saw code I wrote almost a decade ago still compiles and runs in Go, I decided to use Go for everything. There were some initial troubles when I started using it a decade ago, but now it's painless. 2. Haskell, I use it for DSL and state machines. 3. Bash for all deployment scripts and everything. 4. TypeScript, well for the frontend. Lately, I’ve been using Go and SQLite for nearly everything. I don't think I’ve any motivation to look at any other language. I gave up on Java, Python, Ruby, Rust, C++, and C# long ago. Fun fact: Same thing for cloud, I just don't use managed cloud services anymore. I only use VMs or dedicated servers. I've found when you want to run a service for decades+, you’ve got to run your own service if you want it not to cost a lot in the long run. I manage a few MongoDB, PostgreSQL clusters. Most of the apps like email lists marketer (for marketing, sending thousands of email each day) are simple Go app + SQLite using less than 512MB RAM. Same for SaaS billing, the solution is entirely written in Go and uses Postgres. (I didn’t feel safe here using SQLite for this for a multi-tenant setup.) Our chat/ticketing system is SQLite + Go. Deployment is easy, just upload Go cross-compiled binary + systemd service file, alloy picks up log and drops it graphana which has all alerts there. I don't need to worry about "speed" for anything I do in Go, unlike Ruby/Python. When something has to be correct I define it model it in Haskell as its rich type system helps you write correct code. Though setup is not painless as Go, decent performance. I write good documentation, deployment instructions right into mono repo. For a small team this is more than enough imho. No Docker, no Kubernetes, just using simple scripts + graphana + prometheus + Loki and for alloy/nodeexporter. Life couldn't be any simpler than this.

Antibabelic

> Well, I’ve been radicalized. I’ve learned enough performance-oriented programming to be dissatisfied with the common functional languages (Haskell, OCaml, Common Lisp/Clojure, Scheme) because each of these languages are predicated on the existence of garbage collection and heaps. I would take another look at Common Lisp if I were the author. Manual memory management is very much an option where you need it.

lukaslalinsky

Anyone preferring functional programming will be extremely disappointed with Zig. And I'm saying this as a big user of Zig. It's a language for imperative code. And Io is not a monad, just a bunch of virtual methods doing the actual I/O.

crvdgc

comptime is a restricted form of dependent typing. In addition to the normal value to value, type to type, and type to value functions, in comptime, you can write static value to type functions. In full dependent type, you can in addition write dynamic value to type functions, completing the value to type corner. So in terms of typing strength, plain Haskell < Zig < dependent type languages.

Semantic search powered by Rivestack pgvector
8,303 stories · 78,303 chunks indexed