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

In C# the closest analogue to a C++ destructor would probably be a `using` block. You’d have to remember to write `using` in front of it, but there are static analysers for this. It gets translated to a `try`–`finally` block under the hood, which calls `Dispose` in `finally`.

    using (var foo = new Foo())
    {
    }
    // foo.Dispose() gets called here, even if there is an exception
Or, to avoid nesting:

    using var foo = new Foo(); // same but scoped to closest current scope
These also is `await using` in case the cleanup is async (`await foo.DisposeAsync()`)

I think Java has something similar called try with resources.


Java's is

    try (var foo = new Foo()) {
    }
    // foo.close() is called here.
I like the Java method for things like files because if the there's an exception during the close of a file, the regular `IOException` block handles that error the same as it handles a read or write error.

What do you do if you wanna return the file (or an object containing the file) in the happy path but close it in the error path?

You'd write it like this

    void bar() {
      try (var f = foo()) {
        doMoreHappyPath(f);
      }
      catch(IOException ex) {
        handleErrors();
      }
    }

    File foo() throws IOException {
      File f = openFile();
      doHappyPath(f);
      if (badThing) {
        throw new IOException("Bad thing");
      }
      return f;
    }
That said, I think this is a bad practice (IMO). Generally speaking I think the opening and closing of a resource should happen at the same scope.

Making it non-local is a recipe for an accident.

*EDIT* I've made a mistake while writing this, but I'll leave it up there because it demonstrates my point. The file is left open if a bad thing happens.


In Java, I agree with you that the opening and closing of a resource should happen at the same scope. This is a reasonable rule in Java, and not following it in Java is a recipe for errors because Java isn't RAII.

In C++ and Rust, that rule doesn't make sense. You can't make the mistake of forgetting to close the file.

That's why I say that Java, Python and C#'s context managers aren't remotely the same. They're useful tools for resource management in their respective languages, just like defer is a useful tool for resource management in Go. They aren't "basically RAII".


> You can't make the mistake of forgetting to close the file.

But you can make a few mistakes that can be hard to see. For example, if you put a mutex in an object you can accidentally hold it open for longer than you expect since you've now bound the life of the mutex to the life of the object you attached it to. Or you can hold a connection to a DB or a file open for longer than you expected by merely leaking out the file handle and not promptly closing it when you are finished with it.

Trying to keep resource open and close in the same scope is an ownership thing. Even for C++ or Rust, I'd consider it not great to leak out RAII resources from out of the scope that acquired them. When you spread that sort of ownership throughout the code it becomes hard to conceptualize what the state of a program would be at any given location.

The exception is memory.


That approach doesn't allow you to move the file into some long lived object or return it in the happy path though, does it?

As someone coming from RAII to C#, you get used to it, I'd say. You "just" have to think differently. Lean into records and immutable objects whenever you can and IDisposable interface ("using") when you can't. It's not perfect but neither is RAII. I'm on a learning path but I'd say I'm more productive in C# than I ever was in C++.

I agree with this. I don't dislike non-RAII languages (even though I do prefer RAII). I was mostly asking a rhetorical question to point out that it really isn't the same at all. As you say, it's not a RAII language, and you have to think differently than when using a RAII language with proper destructors.

Pondering - is there a language similar to C++ (whatever that means, it's huge, but I guess a sprinkle of don't pay for what you don't use and being compiled) which has no raw pointers and such (sacrificing C compatibility) but which is otherwise pretty similar to C++?

Rust is the only one I really know of. It's many things to many people, but to me as a C++ developer, it's a C++ with a better template model, better object lifetime semantics (destructive moves <3) and without all the cruft stemming from C compat and from the 40 years of evolution.

The biggest essential differences between Rust and C++ are probably the borrow checker (sometimes nice, sometimes just annoying, IMO) and the lack of class inheritance hierarchies. But both are RAII languages which compile to native code with a minimal runtime, both have a heavy emphasis on generic programming through templates, both have a "C-style syntax" with braces which makes Rust feel relatively familiar despite its ML influence.


You can move the burden of disposing to the caller (return the disposable object and let the caller put it in a using statement).

In addition, if the caller itself is a long-lived object it can remember the object and implement dispose itself by delegating. Then the user of the long-lived object can manage it.


> You can move the burden of disposing to the caller (return the disposable object and let the caller put it in a using statement).

That doesn't help. Not if the function that wants to return the disposable object in the happy path also wants to destroy the disposable object in the error path.


You have to write a disposable wrapper to return. Return it in error case too.

    readonly record struct Result<TResult, TDisposable>(TResult? IfHappy, TDisposable? Disposable): IDisposable where TDisposable : IDisposable
    {
        public void Dispose() => Disposable?.Dispose();
    }

Usage at call site:

    using (var result = foo.GetSomethingIfLucky())
    {
        if (result.IfHappy is {} success)
        {
            // do something
        }
    }

  Location: Germany (UTC +1/+2), EU citizen
  Remote: preferred
  Willing to relocate: possibly
  Technologies: C# and previously C++ and Java, prefer functional style and privately dabble with F# and Haskell. I know SQL, Azure, Docker, high performance computing (Monte Carlo simulations), see also CV
  CV: https://stash.ldr.name/wwtbh/rcv-202512-e5ce.pdf
  Email: whoshiring-e5ce /-\T ldr D()T name
I work in mathematical finance so a lot of domain knowledge in that area (derivatives, pricing, probability theory).

I am looking for work in other domains as well.

Happy to provide you with a full CV personally.


I guess most people mean NAPT/PAT when they say NAT


What if extension headers made it better? We could come up with a protocol consisting solely of a larger Next Header field and chain this pseudo header with the actual payload whenever the protocol number is > 255. The same idea could also be used in IPv4.


I didn't mean to imply otherwise. But, as you say, this is equally applicable to IPv4 and IPv6. There were a lot of issues solved by IPv6, but "have even more room for non-TCP/UDP transports" wasn't one of them (and didn't need to be, tbqh).


I agree, although I am a bit surprised to see that we’ve used more than half of the protocol numbers already


Interesting that they went with a custom MIME type and a custom version header. I would have expected the version to be in the MIME type, but I feel like there is a reason behind this.


Are L1 switches like hubs or repeaters then? Sorry for my confusion.


They're more like digital patch panels. You can connect any pair of ports together in both directions (TX/RX), just like moving a patch cable around. You can also connect an incoming RX lane to multiple TX lanes (think optical splitter but electrical). You cannot merge signals together. Some products have FPGAs that add L2+ or multiplexing functionality with packet buffers, but that's not part of the 2-5ns path.


So, if I know the destination addresses on each port in advance I can program it to behave like an L2 switch (with proper multicast even), and I can use code to reprogram it whenever the traffic pattern changes?


The L1 path can't do any address matching and you can't overlap sources - like Ghostbusters, no crossing the streams. You can source port 1 to ports 2-4 (multicast, but static and unidirectional) and you can change a bidir connection between pairs of ports. The signal gets replicated regardless of what's in the frame. It wouldn't be practical to make it behave quite like an L2 switch.


Apologies, my post was not precise enough, but I think I got it.

> It wouldn't be practical to make it behave quite like an L2 switch.

What are typical configuration? If you’re allowed to talk about it.


Maybe surprising for days (could also happen with minutes because of leap seconds technically :-) but for months and years this is more apparent due to month ends and leap years.


I have very limited Python experience but I remember using pymssql in the past. Are there any problems with it?


We used it heavily 10 years ago. It was okay, but it had a rocky history. For a long time it seemed abandoned, then Python 3 happened and we had to patch our own version for a while. Then a new maintainer took over and stuff would just break or APIs rewritten between versions. We ran our own pypi instance to deal with pymssql specifically.

In the later years it became rather good though and with Python 3 many of the issues with character encoding went away.


I use it on Windows (and Linux) but can't get it to work on M1 chips.


iirc it had problems with named instances - only on some newer version of sql server


I have the same phone but to be fair some websites stopped working (GitHub is among them) and some of my banking apps stopped getting updates as well.

No huge deal breakers _personally_ as I don’t need banking on my phone anyway (I have an iPad at home, and also checked that the banks offer authentication devices like TAN generators if I really need to get out of the iOS/Android ecosystem).

Apple Pay still works fine.

I hope that small phone has a long life ahead of it still :)


I don’t think it’s a metric for 0 < p < 1 though.


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

Search: