Cursed Knowledge
Cursed knowledge I have learned over time that I wish I never knew. Inspired by Immich’s Cursed Knowledge. The knowledge is ordered from most to least recently learned.
C# JsonElement
’s TryGet
methods are cursed
JsonElement
’s TryGet
methods are cursedJsonElement
has GetByte
/TryGetByte
, GetDateTime
/TryGetDateTime
, GetDouble
/TryGetDouble
, etc. However, GetBoolean
and GetString
have no corresponding TryGet
methods. What gives?
You’d expect Get
methods to throw exceptions and TryGet
methods to gracefully handle type mismatches, but that’s only half true. For example, the TryGetByte
method:
- Returns
true
for JSON numbers that fit in aByte
- Returns
false
for JSON numbers that don’t fit in aByte
- Throws an exception for non-number JSON values (e.g. arrays and strings)
The TryGet
methods are only graceful after confirming the JsonValueKind
matches. This means that TryGetBoolean
and TryGetString
would behave identically to GetBoolean
and GetString
, respectively, because they have nothing to validate after the JsonValueKind
. The methods don’t exist because they’d be pointless.
This behavior makes the TryGet
methods almost always useless. You’re better off wrapping the Get
methods in a try-catch
.
TypeScript readonly
properties are cursed
readonly
properties are cursedMarking a property as readonly
tells TypeScript to disallow writing to it during type-checking.
However, it’s a nearly meaningless guardrail because TypeScript allows assigning a type with a readonly
property to a type with a writable property.
type Person = {
name: string
}
type ReadonlyPerson = {
readonly name: string
}
const readonlyPerson: ReadonlyPerson = { name: `Tomer` }
// Cannot assign to 'name' because it is a read-only property.
readonlyPerson.name = `Tumor`
// Typechecks! 😱
const writablePerson: Person = readonlyPerson
writablePerson.name = `Tumor`
Hopefully one day readonly
properties are properly enforced.
Maven dependency mediation is cursed
When multiples versions of a dependency appear in the dependency tree, Maven chooses the version closest to the project root; not the highest version.
This behavior caused a bug in the OpenAI Java SDK.
JavaScript Date
’s setMonth
method is cursed
Date
’s setMonth
method is cursedCalling setMonth(month)
) doesn’t always update the date to the given month
. For example, if the date is August 31, then setting the month to September will actually update the date to October 1. September only has 30 days, so the 31st day “overflows” to the next month.
This behavior caused a bug in Google Docs.
Python default parameter values are cursed
A function’s default parameter values are evaluated once; not on each function call.
This means you shouldn’t use mutable values for a parameter’s default value:
def append_fun(list=[]):
list.append('fun')
return list
print(append_fun())
#=> ['fun']
print(append_fun())
#=> ['fun', 'fun']
print(append_fun())
#=> ['fun', 'fun', 'fun']
You have to apply the default in the function body instead:
def append_fun(list=None):
if list is None:
list = []
list.append('fun')
return list
print(append_fun())
#=> ['fun']
print(append_fun())
#=> ['fun']
print(append_fun())
#=> ['fun']