Live data from Hacker News

Functional programmers need to take a look at Zig

pure-systems.org

41–50 of 163 posts

Re: Functional programmers need to take a look at Zig

#41
> I see http_client as existing in a Reader monad that contains an allocator and an IO interface. This is exactly how the IO monad (and for that matter IO#) works in Haskell. The fact that the Zig people came up with this independantly speaks not just to the universal nature of monads (and the algebraic structures of programming languages)

Honestly this sounds like monad bullshit. That's a struct/class/ADT/whatever you want to call it, they existed since forever. The only idea Zig had was that maybe we shouldn't make them global instances.

Re: Functional programmers need to take a look at Zig

#42

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 G…

I'm in the same boat, I started using go only a year ago, but don't want to really use anything else now for apps or data processing. I wrote an app that loaded a lot of data for reporting into duckdb. I've been doing so much java and JavaScript that I feel like it was just much simpler to deal with overall.

Shell for the scripts. I haven't tried to work through much DSL as I really am not a fan of DSLs. Maybe I'll give haskell a shot again to see if it sticks.

Re: Functional programmers need to take a look at Zig

#43

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.

"slightly different ways to initialise stuff." can you elaborate? theres only what 11 datatypes in elixir?

Perhaps they are referring to the syntactic sugar around keyword lists?

[a: 1, b: 2] == [{:a, 1}, {:b, 2}]

Or maybe atom vs string keys in maps?

%{a: 1} vs %{"b" => 1}

Or keyword lists always needing to come last in lists?

[some: :value, :another] # error

[:another, some: :value] # valid

Or maybe something else entirely. Those are just things I remember having to lookup repeatedly when I was first learning elixir.

Re: Functional programmers need to take a look at Zig

#44

Earlier quoted context omitted.

Sure, but this is an example from the article, and pertains to sum types in general, not just Maybe.

i dont think its generally a good idea to be making complex type generators like this in zig. just write the type out. the annoyingness of the thing you tried to do in zig is a feature. its a "don't do this, you will confuse the reader" signal. as for optional, its a pattern that is so common that it's worth having builtin optimizations, for example @sizeOf(*T) == @sizeOf(usize) but @sizeOf(?*T) != @sizeOf(?usize). i…

> if optional were a general sum type you wouldn't be able to make these optimizations easily without extra information

Rust has these optimizations (called "niche optimizations") for all sum types. If a type has any unused or invalid bit patterns, then those can be used for enum discriminants, e.g.:

- References cannot be null, so the zero value is a niche

- References must be aligned properly for the target type, so a reference to a type with alignment 4 has a niche in the bottom 2 bits

- bool only uses two values of the 256 in a byte, so the other 254 form a niche

There's limitations though, in that you still must be able to create and pass around pointers to values contained within enum, and so the representation of a type cannot change just because it's placed within an enum. So, for example, the following enum is one byte in size:

    enum Foo {
        A(bool),
        B
    }
Variant A uses the valid bool values 0 and 1, whereas variant B uses some other bit pattern (maybe 2).

But this enum must be two bytes in size:

    enum Foo {
        A(bool),
        B(bool)
    }
 
...because bool always has bit patterns 0 and 1, so it's not possible for an invalid value for A's fields to hold a valid value for B's fields.

You also can't stuff niches in padding bytes between struct fields, because code that operates on the struct is allowed to clobber the padding.

Re: Functional programmers need to take a look at Zig

#45

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 G…

Why did you give up on Java and Rust?

Java is a resource hog when you use patterns and libraries popular in Java land. When you are working in the Java ecosystem, you just assume that this much resource is needed by the app! But when you'll code the same thing in Go using the same methods, you'll find resource usage is really very low.

We’ve a 1: 1 copy of the app; on JVM, it's using 2GB RAM using Spring Boot, and on Go, it runs on 512MB RAM and is blazingly fast.

ofc, it's possible to tune java app but why bother? when we get same low resource usage and better performance in Go from get go while still writing naive and dumb code?

Deployment is super simple in Go, upload a single cross compiled binary it's done. Very simple and easy.

Rust needs a lot more effort to write correct code than Go in my experience. We get the same performance out of Go, with much less effort. At some point, it's just cheaper to start one extra instance than perform some low-level optimisation; modern hardware is fast enough that Rust-level optimisation is rarely needed for what we do.

Re: Functional programmers need to take a look at Zig

#46

Earlier quoted context omitted.

I am not even sure if its a general pattern (inject any dependency?) or a specific pattern they added to Zig

idk in elixir we basically do exactly whats happening with io parameters when mocking or swapping implementations that all satisfy the same behaviour. here. i am not the only one that refers to it as dependency injection: https://daily.dev/blog/zig-async-io-io-uring-zig-0-16-rethin... "Zig 0.16 introduces std.Io, a flexible I/O abstraction that uses dependency injection, similar to the Allocator interface"

Sigh. I meant that the zig authors did not make it a general pattern and just slapped on the DI pattern specifically for io, instead of generalising the abstraction so people can DI stuff.

Re: Functional programmers need to take a look at Zig

#47

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 G…

I went the same way but with only using Lisp dialects like Elisp and Clojure and Nix. Although I would ditch Nix too if another Lisp could supplant it too.

Re: Functional programmers need to take a look at Zig

#49

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 G…

I went the same way but with only using Lisp dialects like Elisp and Clojure and Nix. Although I would ditch Nix too if another Lisp could supplant it too.

Obvious follow-up that's begging to be asked -- if you like nix and want a lisp, have you tried guix/guile?

Re: Functional programmers need to take a look at Zig

#50

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 G…

Im with you on Go and SQLite, dropped Postgres for many of my projects, I might add: HTMX instead of a TS frontend, very few apps need a TS/React/... frontend. Doubling development effort with minimal gain (except games etc.)

Dabbled with Rust some years ago, I think it is an excellent choice for sudo-rs and such but for GUI and web apps I (perhaps too stupid) end up with arcmutex soup.

https://www.radicalsimpli.city

Post reply on HN