News for hackers. Stuff that matters.

alurm

Re:Ask HN: Who wants to be hired? (September 2026) on Tuesday September 01, 2026 @08:29PM (#49530244)

  Location: Tbilisi, Georgia
  Remote: Yes
  Willing to relocate: Yes
  Technologies: Rust, Nix
  Résumé/CV: https://alurm.github.io/cv.pdf
  Email: [email protected]
Software engineer, open source maintainer. Systems programming, developer tools, Unix.
Yeah, I've added macros `vec_len` and `vec_ptr` (or, enums, actually), which help somewhat.

`arr[3]` should be flagged by the compiler it is known to the compiler that you're operating on an array.

You can pass `arr` as `&arr` to functions, then compiler will know the length of the array since the type would be `T ()[2]`.

And you can then use it like this:

  void f(int *(*ints)[2]) {
      for (size_t i = 0; i < (size_t)vec_len[*ints]; i++) printf("f: %d\n", vec_ptr[*ints][i]);
  }
Curiously, this is a rare case where the "inverted" `a[b]` requires less typing compared to `(b)[a]`.

A compiler will not be able to flag `vec_len[ints]` though, which is unfortunate.

Thank you! I implemented this pattern initially about a year ago, but decided to write about it now. Since you liked it, it wasn't for nothing. :)
You're right, I added some more clarity in the README.

Interestingly, I think my approach will work fine on CHERI, since the pointer is never dereferenced, but I didn't test this. But yeah, there are some architectures where it would fail.

Good point! Added `vec_ptr[vec]` and `vec_len[vec]` helpers to mitigate this somewhat.
Thanks for mentioning it, I've heard about stb, but this time around I actually looked at the code. Their approach is very nice.
Re:Solod: Go can be a better C on Sunday March 22, 2026 @03:37AM (#47475301)
Making a strict subset of some existing language (Go) be a "better C" is quite an interesting idea compared to others (D, Zig, Hare, C3, D, ...), haven't seen it elsewhere. No new syntax. And Go seems to be a pretty good choice for this. Not sure if it's gonna fly though.
Yes, but you can generate JSON with other tools easily. home.md describes how you can do it with Nix, but just as easily you can use Cue or something else.

Edit: mentioned this in the README explicitly. Thanks!

Yeah, in general (a bit of a tangent), ideas from Plan 9 are really powerful. For example, the Acme text editor exposes it's API as a file system (it's represented via Unix sockets in plan9port, but FUSE is available as well there). It's easy to write scripts to manipulate the editor, and quite fun.
Well, if you're generating JSON with Nix, you don't have to put everything inside of one file. It would be a better idea to split it up into multiple. You can also use builtins.readFile for reading config files which don't have to be generated in a complex manner. It's up to you to choose, I just kept everything inside of one file since it makes for a simpler example.

Edit: I have updated the documentation to mention this explicitly, thanks!

Re:More shell tricks: first class lists and jq on Thursday August 07, 2025 @03:48PM (#44829461)
YSH looks very nice here, thanks. I thought to mention YSH, but have no experience with it, so I hoped you would comment.

(I guess we're duplicating threads at this point :D)

Re:More shell tricks: first class lists and jq on Thursday August 07, 2025 @02:00PM (#44828052)
Sure.

I have tried Bash namerefs. I found them to be kinda awkward, since you need to name them uniquely. So, you have to pretend that they are global variables, even though they are declared inside a function, which makes their usage verbose.

Here, this could look like:

  split_by_double_dash() {
    declare -n split_by_double_dash_before=$1
    declare -n split_by_double_dash_after=$2
    
    split_by_double_dash_before=()
    split_by_double_dash_after=()

    ...
  }
Re:More shell tricks: first class lists and jq on Thursday August 07, 2025 @01:33PM (#44827587)
Yeah, PowerShell and nushell are pretty cool, I hope they gain more adoption.
Re:Ask HN: Who wants to be hired? (August 2025) on Friday August 01, 2025 @02:29PM (#44760581)
Location: Yerevan, Armenia.

Remote: yes.

Willing to relocate: yes.

Technologies: Rust, C/C++, Bash, Go, Linux, Nix.

Résumé/CV: https://alurm.github.io/resume/alan-urmancheev.html (or .pdf for a PDF).

Email: [email protected].

A systems programmer. Prefer US opportunities.

Re:I made a tiny library for switches and sum types in Lua on Wednesday January 01, 2025 @08:18PM (#42570776)
I like your approach.

(Implicitly) using [1] instead of [false] as a default is less typing for sure (but maybe a bit more confusing?).

Also, objects being switched on really have to be tables in my version anyway (since overriding __call for builtin types seems harsh to me), so having a tag field right in them as opposed to creating a metatable should be more efficient.

For my version I'll add a value-weak map of metatables to dedup them, should work as well.

In terms of functions, yeah, I don't think you can get rid of them, but (in the example) you can avoid (r) and (s) params if you assume that the functions lexically close over shape.

Re:I made a tiny library for switches and sum types in Lua on Tuesday December 31, 2024 @01:41AM (#42556931)
Honestly, not much.

I found it nice how it's possible to emulate switches in Lua with so little code, without the result looking too ugly. You may find this pattern useful. That's it.

The catch is that, unlike with normal switches or with a series of "if"s, there's a whole bunch of indirection added via functions, so it's not very efficient.

Perhaps LuaJIT can inline these functions, but I haven't tested it.

Re:I made a tiny library for switches and sum types in Lua on Monday December 30, 2024 @09:30PM (#42555801)
Thanks, fixed.
Re:OCaml Syntax Sucks on Thursday December 05, 2024 @10:01PM (#42335822)
https doesn't make content trust worthy.
Re:Hcreate(3) on Wednesday August 21, 2024 @05:25AM (#41308407)
In this case it doesn't matter much I think. I suppose the api existed for ages.

But I prefer openbsd or man7 pages, sure.

Re:Desktop Linux is an Untapped Gold Mine on Friday June 07, 2024 @04:37AM (#40606600)
Pretty sure it's fake.
As I understand, Bittorrent is not a persistent data structure. Git and IPFS are. Radicle is another interesting approach. They used IPFS but switched to a custom protocol, as I understand, for performance.
Re:I used to not worry about climate change. Now I do on Sunday January 28, 2024 @09:21AM (#39166032)
This is very funny.
Click bait hacker news title.
Re:Modern Pascal is still in the race (2022) on Wednesday October 11, 2023 @10:43PM (#37852924)
Here's how I understand it.

One important (and beautiful) thing to understand about C is that declarations and use in C mirror each other.

Consider the same type written in Go and C: array of ten pointers to functions from int to int.

Go: var funcs [10]*func(int) int

C: int (*funcs[10])(int)

Go's version reads left to right, clearly. C version is ugly.

But beautiful thing about C version is that it mirrors how funcs can be used:

(*funcs[0])(5)

See how it's just like the declaration.

Go's version doesn't have this property.

So, now about the *.

Usage of * doesn't require spaces.

If p is a pointer to int, you use it like this: *p

And not like this: * p

And since type declarations follow usage, therefore "int *p" makes more sense.

There is also a good argument about "int *p, i". In the end, these usages follow from how the C grammar works.

There are many more musings about that on the web, but here is one of my favourites: https://go.dev/blog/declaration-syntax.

Edit: HN formatting.