Hacker News new | past | comments | ask | show | jobs | submit | MawKKe's comments login

There's also `std.fmt.allocPrint()` which functions similarly to `format!()`. Although I'd argue its rather poorly named, like many of the functions in the stdlib...

For wanting to avoid fiddling with multiple repeated alloc/defer-free, it's often convenient to use the arena allocators that allow you to release everything with a single `defer arena.deinit()`


I would (coming from a C background) guess that `allocPrint()` owes its name from the C standard library function(s) `as(n)printf()`[1]. At least that would make sense, the naming is modernized by being made longer, to gain clarity.

[1]: https://man7.org/linux/man-pages/man3/asprintf.3.html


Was the need for optimization work something that was on your mind the whole time? Like a nagging feeling in the back of the head that the code is not working as well as it _should_ be working? i.e. stress.

And when you finally "fixed" the issue through optimization, your mind allowed itself to let go of these open loops (borrowing the GTD terminology), leading to relaxation?


Isn't the new one also horribly type-unsafe? Since you can put (parent) objects of any kind into the list without any mechanism to detect which is which?


Zig builds a statically linked library called "cgo_static_linking" from Zig sources. Zig places the artifact into "./zig-out/lib/cgo_static_linking.a" (or maybe some other extension). The library is exported with C ABI, which Go (cgo) compiler supports.

The #cgo line tells the Go compiler to add custom compilation flags: -l flag tells the compiler that you wish to link to a library called "cgo_static_linking" in to the binary. However, the cgo compiler can't find it since it is not in the default search paths for libraries. The -L option extends the library search path to "./zig-out/lib/", allowing "cgo_static_linking" to be found.

The "#include" line inserts the header file contents as-is into the source file (main.go), bringing the definition of the function available to the compiler. The compiler is then able to compile the Go source, and later link it with the other build artifacts to produce the final executable.

The key here is the "C ABI" which acts as common ground for both languages. The rest is just scaffolding to let the compilers find and connect appropriate files together.


numpy as well. and tensorflow


Quick glance of zstd github repo shows they do provide CMake build scripts?


Last I touched it they only had glitchy make files and I don't like cmake particularly, I was just like "bespoke make files are fine if they're posix compliant, but these aren't"


I mean, it's possible that at some point evolution produced such nuclear reactored individual, but who got "naturally selected" rather quickly for obvious reasons


If you read some of the Dune supplementary materials, the sandworms are biological nuclear reactors. It's kinda handwavey but it's a cool concept - how do you keep a creature the size of a freight train moving constantly in a very thick medium... how about harvesting fissionables?


See the Isaac Asimov story "Pâté de Foie Gras" from the September 1956 issue of Astounding Science Fiction, available here [1] on the Internet Archive.

[1] https://archive.org/details/sim_astounding-science-fiction_1...


VScode devcontainer can build from existing Dockerfile. You can develop the project image as usual, and then reference the Dockerfile from devcontainer.json. This means you can build and run from the command line via `docker` command if needed. The VScode extension just makes this slightly easier.

Not sure how GP's company does it, but that is how I would configure it.

Caveat: the default devcontainer initialization workflow does _not_ create the Dockerfile, only the .json.

At $work we don't use devcontainer.json, but we can launch the development environment image such that you can SSH into it as if it was a regular VM.


If you think about it, a CLI argument parser takes in a sequence of tokens and transforms the information into some kind of internal repsentation, which is then later interpreted. Just like what a compiler/interpreter does, except now the input is already tokenized. So there does not seem to be a practical way to "standardize" this interface any more than you can standardize a compiler for all languages.

It's kinda whacky to think about that every sufficiently complicated CLI app out there implements its own ad-hoc, informally-specified, bug-ridden, slow implementation of half of common lisp _just_ to prepare running the actual program payload...


IMO that's the typical experience with many of the features in modern C++ standards. You read about a really neat useful thing they added, something that seems to provide a safe and practical way to overcome a shortcoming in the language. You may even get a little excited...until you try to actually use it and realize its full of new footguns and weird limitations


Yes, you read about std::variant on a blog and think that it is a sum type. Then you try it out and realize that it's a thin (type-safe) wrapper over tagged unions that is at least three times slower and has about 5 unreadable alternatives that replace simple switch statements.

Then you find out that members of a "variant" are not really variant members but just the individual types that can be assigned to a union. For example, assigning to a non-const reference does not work (and obviously cannot work once you realize that std::variant is just syntax sugar over a tagged union).

Most of these new additions since C++11 are just leaky abstractions and wrappers.


> and obviously cannot work once you realize that std::variant is just syntax sugar over a tagged union

It would be easy to make it work, there isn't necessarily a strict relation between the template parameter and the actual stored object. Not having reference variant members was a conscious decision, same as optional<T&>. Hopefully this will be fixed in the future.


A few code snippets of what you see as weaknesses of std::variant may be appropriate, as I couldn't figure out your complaint. Assigning to a variant taken by non-const& works fine for me.

I personally would have liked to see recursive variant types and multi-visitation (as supported by boost::variant).


std::variant is not a true algebraic data type, since the individual element constructors do not construct the variant type automatically. Compare to OCaml, written in a verbose and unidiomatic way that is similar to C++:

  # type foo = Int of { n : int } | Float of { f : float };;
  type foo = Int of { n : int; } | Float of { f : float; }
  # Int { n = 10 };;
  - : foo = Int {n = 10}
  # let r = ref (Int { n = 10 });;
  val r : foo ref = {contents = Int {n = 10}}
Notice that the constructor Int { n = 10 } automatically produces a foo type and assigning to a mutable ref works.

The same in C++, using assignment to a pointer to avoid the lvalue ref error that is irrelevant to this discussion:

  #include <variant>
  
  struct myint {
    int n;
    myint(int n) : n(n) {}
  };

  struct myfloat {
    float f;
    myfloat(float f) : f(f) {}
  };

  using foo = std::variant<myint, myfloat>;

  int
  main()  
  {
    const foo& x = myint{10}; // works
    foo *z = new myint{10}; // error: cannot convert ‘myint*’ to ‘foo*
  }

As stated above, this obviously cannot work since C++ has no way of specifying a myint constructor that -- like in OCaml -- automatically produces the variant type foo.

C++ would need true algebraic data types with compiler support (that would hopefully be as fast as switch statements). To be useful, they would need a nice syntax and not some hypothetical abomination like:

  using foo = std::variant<myint, myfloat> where
  struct myint of foo { ... };


I think the comment means:

    std::variant<int&, etc>
does not work well.


Just use

    std::variant<int*, ...>
References in C++ are just sugary pointers.


References have one important property over pointers. They cannot be null.


Reference_wrapper then.


const ref lifetime extension is important to, or operator overloading wouldn't be workable.


they easily can :)

void test(int& y){}

int main() { int* x = nullptr; test(*x); }


There is a difference between an API promissing that a value wont be null and a buggy program setting a null where it should not. A reference is only null if someone fucked up. As a programmer you can usually rely on a reference not being null and you couldn't do anything about it if it was anyway within the constraints of the language.


In the same way, an `enum class` variable's value being outside of the set defined in the `enum class` is also a fuckup.


no, deferencing a null ptr is UB. An enum class outside the declared values is perfectly valid.

You could design a language feature where integer to enum is checked, but that's not enum.

Enum classes already add scoping, forbid implicit conversions and allow explicit underlying types. Those are pure extensions. Making undeclared values invalid or UB would be very surprising to people used to normal enums.


And you can also open /proc/self/mem in a Rust program and overwrite whatever you want, including pointers. So?


One of those cases happens accidentally all the time (in more complex variants than the motivating example you responded to), the other never happens except on purpose. It's like complaining guard rails are pointless because people being launched with catapults might still fly over them and plunge to their deaths.


I've never seen a nullptr somehow sneak into a reference. Never.

What I have seen is automatic variables escaping their scope as a reference, which rust protects against. And is also much more dangerous, because dereferencing a nullptr is defined behavior on most platforms


They most certainly can be null as can “this”.


Only after dereferencing a null pointer, which would be the actual problem, not the fact that some reference or this is null.


You cannot have a null reference unless you invoke undefined behavior first.


Ohh, and to make the use of a variant to look like pattern match over type you need to copy paste some template magic.

https://schneide.blog/2018/01/11/c17-the-two-line-visitor-ex...

variants are a such disappointment at every step of trying to use them


Consider applying for YC's Summer 2025 batch! Applications are open till May 13

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

Search: