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

I think Gothic II did this really well. While there are some clear borders a lot of the transitions between the three categories are gradual and organic. You're mostly safe in the secondary settlements but go too far into someone's backyard and you might suddenly find yourself fighting for your life. It also managed to make the place feel expansive without any place feeling like repetitive filler content.

Came here to comment on Gothic, too. I'd have picked the original Gothic even more as an example, though -- there, you are in a prisoner colony, even if you are in a settlement. Anger the wrong people and you won't survive the experience for most of the game.

Also the swamp camp is really close to some rather deadly creatures if you're not careful in the early game.


Centralized infrastructure is fragile and to the extent that the internet has become centralized unscheduled Internet shutdowns are bound to happen. The benefit of scheduled Internet shutdown is that people can prepare for it while at the same time gaining experience which helps with dealing with an unscheduled Internet shutdown.


On the other hand, if we force all systems to be resilient to an internet shutdown then we'd end up regressing society by a lot. Think about how much more work a single doctor is able to handle more efficiently by having internet access (eg. charts, patient history, access to all the world's libraries) that would be lost without the internet.

If we don't force critical systems to be resilient to an internet shutdown, we'll be doing the meme. Specifically:

Weinberg’s 2nd Law:

If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.


The reason you're not hearing any difference between the words in those pairs is because they are pronounced the same. At least according to Wiktionary and my own subjective judgement as a German native speaker.


I've actually messed with Audacity once, extracting the vowels, lengthening them and overlaying, and there is definitely a difference in quality (the length is pretty much the same), it's just that it's very minor to my ear. But native English speakers apparently can pick them up with little trouble.

The difference is much easier to spot in pairs like "bead"/"bid", but that's mainly because before the voiced consonants the long vowel is actually longer than the short one, and the speakers usually add a small glide of "y" at the end of it, so it's more like "beeyd".


I had a native English coworker who used to pronounce it Ü-Bahn and when corrected he insisted that it sounded exactly the same then when I said U-Bahn.

He was perfectly capable of making the same (German) u sound when saying other English words. Apparently it is very subtle, sometimes even for specific things like start of the word and length of the vowel. I just don't know.


There has been open source before Linux and there will be open source after Linux. Yes Linux is a flagship project but the whole culture of open source is much broader than it.


> prevent this scenario from ever happening again.

Every additional nine of not getting hacked takes effort. Getting to 100% takes infinite effort i.e. is impossible. Trying to achieve the impossible will make you spin on the spot chasing ever more obscure solutions.

As soon as you understand a potential solution enough to implement it you also understand that it cannot achieve the impossible. If you keep insisting on achieving the impossible you have to abandon this potential solution and pin your hope on something you don't understand yet. And so the cycle repeats.

It is good to hold people accountable but only demand the impossible from those you want to go crazy.


While I'm always ready to throw away code when I realize that there is a better way to do things I found it quite difficult to write code with the intent to throw it away. However I often do write code with intent of modifying it once I have a better idea of what is needed. It might be because I'm comparatively better at refactoring than at starting from scratch.


The paradox isn't that as a good becomes cheaper we're using more of it. The paradox is that as a good becomes cheaper we're spending more on it.


While STM was a big selling point when Clojure in practice it's actually very rarely used. The persistent data structures are indeed the heart of Clojure.

While for many applications Clojure's performance is good enough it's not anywhere near what you can achieve with Rust. I once did a small game in Clojure trying to be very clever to eke out every last bit of performance and still didn't hit an acceptable frame rate. Made a very naive reimplementation in Rust that involved copying the entire state every frame and it run buttery smooth.

If there is a task for wish persistent data structures are the most performant solution it should be easy enough to implement and use them in rust too. Probably someone already did that.

Clojure is my default programming language but if I want performance (or static types) I reach for Rust.


Maybe the result of NaN === NaN should be neither true nor false but NaB (not a bool).


NaN is, by definition, not equal to NaN because they’re not comparable, it does have a definitive Boolean representation - false is correct


The concept of NaN long predates the language that uses ===, and is part of a language-agnostic standard that doesn't consider other data types. Any language choosing to treat the equality (regardless of the operator symbol) of NaN differently would be deviating from the spec.


Julia evaluates NaN === NaN to true, as long as the underlying bit representations are the same. Eg NaN === -NaN evaluates to false, as happens also with NaNs where for some reason you tinker with their bytes. I think it makes sense that it is so though, regardless that I cannot think of any actual use cases out of doing weird stuff.


In R, NA (which is almost, but not quite like NaN) actually has separate types for each result, so you can have NA_boolean, NA_integer etc. Its super confusing.


It is a minor nuisance, but I think there's ultimately a pretty good reason for it.

Old-school base R is less type-sensitive and more "do what I mean", but that leads to slowness and bugs. Now we have the tidyverse, which among many other things provides a new generation of much faster functions with vectorized C implementations under the hood, but this requires them to be more rigid and type-sensitive.

When I want to stick a NA into one of these, I often have to give it the right type of NA, or it'll default to NA_boolean and I'll get type errors.


> When I want to stick a NA into one of these, I often have to give it the right type of NA, or it'll default to NA_boolean and I'll get type errors.

Yeah, I know. I hit this when I was building S4 classes, which are similarly type-strict.

Again, I think this was the right decision (pandas's decision was definitely not), but it was pretty confusing the first time.


What would an `if (NaB) ... else ...` block do?

Either you throw an exception (and imo it is better to just throw an exception before that already, then) or else what you do determines what NaN === NaN actually evaluates to.


Apparently NaN (not a number) becomes false when type-cast to boolean.

  Boolean(NaN)
  ===> false
For a hypothetical NaB (not a boolean), the same behavior seems logical.

  Boolean(NaB)
  ===> false
So the condition `if (NaB)` is false and will fall through to the `else` branch. But..

> what you do determines what NaN === NaN actually evaluates to

I think I disagree with this because it's not about casting to boolean, it's a totally different question of self-identity, or comparing two instances (?) of a value (?!).

From the article:

  typeof NaN
  ===> "number"
For symmetry and consistency:

  typeof NaB
  ===> "boolean"
> NaN is the only value in the whole of JavaScript that isn’t equal to itself .. the concept of NaN is meant to represent a breakdown of calculation

Similarly, NaB would represent a breakdown of true/false condition (somehow) as an exceptional case. Whether it equals itself is a matter of convention or language design, not logic - since it's beyond logic just as NaN is beyond numbers. I would say:

  NaN === NaN
  ===> false

  NaB === NaB
  ===> false
> you throw an exception (and imo it is better..

I agree throwing an exception is better design for such exceptional cases - but we know JavaScript as a cowboy language would rather plow through such ambiguities with idiosyncratic dynamic typing, and let the user figure out the implicit logic (if any).


I don't necessarily think about JS in particular. A lot of languages have similar design and prob most have to deal with this issue in general.

In your examples, it does not make sense to have both

  typeof NaB
  ===> "boolean"
and

  Boolean(NaB)
  ===> false
But maybe if you had NaB it would make sense to evaluate

  Boolean(NaN)
  ===> NaB
And maybe also evaluate `NaN === 1` to NaB?

I am not too fond of NaB because boolean is supposed to encode binary logic. There exists ternary logic and other concepts that could be used if you do not want strictly two values. Or if you want to encode exceptional values, no reason not to use int8 directly, instead of calling it boolean but actually using sth that could be represented as int8 (NaB has to be represented by some byte anwyay). In general, tbh, I think often it is not useful to encode your logic with booleans because many times you will need to encode exceptional values one way or another. But NaB will not solve that, as it will just function as another way to encode false at best, throwing exceptions around at worst.

> Similarly, NaB would represent a breakdown of true/false condition (somehow) as an exceptional case.

Still, in JS `NaN || true` evaluates to `true` hence I assume `NaB || true` should evaluate to true too. It is not quite the same as NaN + 1 evaluating to NaN. And as NaN (and hence NaB) functions as false when logical operations are involved for all intents and purposes, except if you exactly inquire for it with some isNaB() or sth, to me NaB is another way to encode false, which is probably fine depending what you want it for.


Reminds me of something I saw recently, a tri-value boolean, a "trilean" or "tribool".

  true, false, unknown
  yes, no, maybe
  nullable boolean
They all feel "risky" in terms of language design, like null itself. But I suppose there are languages with Maybe or Optional.

> The tribool class acts like the built-in bool type, but for 3-state boolean logic

https://www.boost.org/doc/libs/1_48_0/doc/html/tribool/tutor...

Apparently this is also called "three-valued logic".

> In logic, a three-valued logic (also trinary logic, trivalent, ternary, or trilean, sometimes abbreviated 3VL) is any of several many-valued logic systems in which there are three truth values indicating true, false, and some third value.

> the primary motivation for research of three-valued logic is to represent the truth value of a statement that cannot be represented as true or false.

https://en.wikipedia.org/wiki/Three-valued_logic

Personally I think I'd prefer a language to instead support multiple return values, like result and optional error. Or a union of result and error types.

> no reason not to use int8 directly

Hm, so it gets into the territory of flags, bit fields, packed structs.

  const BitField = packed struct {
      a: u3,
      b: u3,
      c: u2,
  };
https://andrewkelley.me/post/a-better-way-to-implement-bit-f...


It should throw a compile-time error. Anything like this which allows an invalid or unmeaningful operation to evaluate at compile-time is rife for carrying uncaught errors at run-time.


Or a 3rd option is it should not be allowed similar to dividing by 0.


What do you mean "not allowed"? Throwing a compile or runtime error? Many languages allow division by zero, and x/0 typically gives inf unless x is 0, then x/0 gives nan. If x is negative then x/0 gives -inf. Of course this all can get tricky with floats, but mathematically it makes sense to divide by zero (interpreted as a limit).

For NaNs, maybe in some domains it could make sense, but eg I would find it impractical when wanting to select rows based on values in a column and stuff like that.


Typed nulls are good


I've found that when I'm listening to recordings of me my accent really sticks out to me in a way that's completely inaudible when listening to myself live. This happens with both English and my native German.


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

Search: