I am aware that NAT is often used in corporate networks, but it does not automatically make any more sense there - the isolation is achieved by the firewall, not by NAT.
NAT (address or port translation) and a firewall (allowing traffic from/to those addresses or ports) are orthogonal concepts.
You can do NAT on IPv6, if you so desire.
It _should_ make no difference whether any adversary knows "what's behind a NAT", because it is your firewalls job to block any unwanted traffic.
Relying on "nobody knows what is inside our network so it can't be attacked" is not a viable strategy.
NAT is a crutch to circumvent the problem of "there are not enough addresses for each device".
I _assume_ you are referring to a default deny inbound firewall (so that devices are not reachable from the outside), but these are very different, completely orthogonal concerns (and independent of the IP version in use).
I am not sure this approach can take you very far.
In my experience, CC makes it very very easy to _add_ things, resulting in much more code / features.
CC can obviously read/understand a codebase much faster than we do, but this also has a limit (how much context we can feed into it) - I think your approch is in essence a bet that future models' ability to read/understand code (size of context) improves as fast or faster than the current models' ability to create new code.
OTOH, consider that in the "pick the majority from 3 CPUs" approach that seems to have been used in earlier missions (as mentioned in the article) would fail the same way if two CPUs compute the same erroneous result.
> `NonZeroU32::saturating_add(self, other: u32)` is able to return `NonZeroU32` though!
I was confused at first how that could work, but then I realized that of course, with _unsigned_ integers this works fine because you cannot add a negative number...
Would have to be F32, no?
I cannot think of any way to enforce "non-zero-ness" of the result without making it return an optional Result<NonZeroF32>, and at that point we are basically back to square one...
Agree that "splitting for splittings' sake" (only to stay below an arbitrary line count) does indeed not make sense.
On the other hand I often see functions like you describe - something has to be executed step-by-step (and the functionality is only used there) - where I _whish_ it was split up into separate functions, so we could have meaningful tests for each step, not only for the "whole thing".
I ran into some code recently where this pattern caused me so much headache - class A has an attribute which is an instance of class B, and class B has a "parent" attribute (which points to the instance of class A that class B is an attribute of):
class Foo:
def __init__(self, bar):
self.bar = bar
class Bar:
def __init__(self, foo):
self.foo = foo
Obviously both called into each other to do $THINGS... Pure madness.
So my suggestion: Try not to have interdependent classes :D
On the other hand, I tend to take it as a hint that I should look at my module structure, and see if I can avoid the cyclic import (even if before adding type hints there was no error, there still already was a "semantic dependency"...)
I am aware that NAT is often used in corporate networks, but it does not automatically make any more sense there - the isolation is achieved by the firewall, not by NAT.
NAT (address or port translation) and a firewall (allowing traffic from/to those addresses or ports) are orthogonal concepts.
You can do NAT on IPv6, if you so desire.
It _should_ make no difference whether any adversary knows "what's behind a NAT", because it is your firewalls job to block any unwanted traffic.
Relying on "nobody knows what is inside our network so it can't be attacked" is not a viable strategy.