If you want a company to do something, you do need to ensure that the fine is bigger than the amount of money they made or will make by doing the thing you are trying to discourage. You need there to be a real downside. I don't think any of the fines that have been discussed are anywhere close to the levels that I am talking about.
Don’t corporate fines often come with requirements that the company also discontinue certain activities, start certain other ones, and be able to prove this or that to a regulator?
I think you are talking about an upgrade install. Those have a long history of breaking things. You would have to be crazy to attempt one of those on a critical production system.
What you would do for anything important is build a new separate system and then migrate to that once it is working. You can then migrate back if you discover issues too.
Any chance you would be willing to summarize the research or provide information on some relevant studies? I've always been skeptical about flossing and would like to learn more.
The wikipedia article [1] suggests that there is no strong evidence for flossing being a good thing. However, that might just be because experts have not updated the article.
A 32” monitor should be 4k. If anyone needs glasses, it might be the author of this blog post as that is the typical market for low pixel density displays.
Similar signs were installed near highly contaminated parts of Russia, specifically Chelyabinsk near lake Karachay, one of the most contaminated places on earth.
I have a stupid question (web dev, but also have used Java and C#).
TypeScripts type system is commonly described as implementing "structural types" (not "duck" typed)
And there are a ton of pragmatically sound gotchas around this, such as the importance of whether an object is used as an argument or a parameter, or if it is declared using an object literal.
(focusing on objects here because for primitives I'd assume that TS has almost nominal typing)
So, is there an ELI5 for the difference between structural typing and duck typing?
I'd guess that duck typing is more similar to the callee perspective in TS (give me an object with the properties I need), while structural typing is more similar to the checks performed when initializing an object literal with a declared type?
But I'm not sure if I'd be able to differentiate both terms succinctly.
What is the relationship between duck typing and "type narrowing"? Or is that more of a "structural typing" thing?
> So, is there an ELI5 for the difference between structural typing and duck typing?
Likely just semantics. You could argue that the sliver of difference is just treating something like a particular API shape hence duck typing over structurally matching to an interface. For practical purposes however it does not matter. The runtime vs compile time argument is purely an implementation detail that has no relation to structural matching aka duck typing (heh) otherwise.
In practice, I find this idea rather uncomfortable and C# has been avoiding it except for few very defined cases that are least likely to cause this confusion, like GetEnumerator and Enumerator.MoveNext+Current (it could be used as an enumerable in foreach loops but unless the type implements IEnumerable, you can't coerce it to the type).
For the cases where specialization is needed, it is usually written as
// could also be Handle<T> where T: IDataArg to avoid boxing for structs
// as struct generics in .net are zero-cost via monomorphization
void Handle(IDataArg arg) {
if (arg is IPooledArg pooled) {
var rented = arg.Rent();
// do something with the arg
rented.Return();
}
// slow path
}
No type confusion is possible as whatever is passed to the method has to declare it implements IDataArg. Same applies to 'arg' being 'IPooledArg' - it could have methods with names that would make it match the interface structurally but this is, quite literally, not a type-safe assumption. The authors may have explicitly decided not to expose it, or to provide explicit interface implementation that differs from pre-existing names.
All this is very upfront and you won't be finding yourself having to rename methods or be surprised when your objects or structs are used in a way they are not supposed to because their triangle-shaped type happened to fit in a square-shaped interface hole.
I think I share your perception of ugliness in TS.
It feels like in TS, most if not all of the worries around complex types originate in compromises like this, or in other words, structural/duck typing.
Also feels a bit like functions are an elephant in the room. Function types with structural typing for parameters, arguments and return values are useful.
But then you have to use overloads and "extends" in generics for the first time in order to *describe* something, and if you're like me, you might cry a little from the inside. Especially when you simultaneously chastise yourself for wasting time on ignorable TS issues.
Thanks, this makes sense, TS type narrowing only works with information known at compile-time (even when using runtime constructs for type narrowing).
So I will go on to imagine duck-typing as the classic JS way where functions started with often pretty extensive runtime checks of their parameter values.
I guess this also means that duck-typing is inherently tied to checking primitive types and/or object structures, return values etc at runtime.
I'm using something like this in one of my Go projects and I created explicit functions to allow programmers to use the larger type where the smaller one is required, which is normally disallowed by the language, by employing some cludgy unsafe package use and based on the assumption that the memory layout for the two types looks identical for the common "a" and "b" properties.
So far it hasn't bitten me in the behind, but I wouldn't advise anyone to use that logic for production code.
Go structs are nominally typed, so that is beyond the topic of structural/duck typing. Only the interface is structurally typed.
The difference between structural typing and duck typing is that one is evaluated at compile time, while the other at runtime. Typescript is erased before runtime, so it by itself does not exhibit duck typing features, although Javascript does.
It doesn't support duck typing in the usual sense, but unchecked type casting 'any' to an interface does indeed compile. To any type, as a matter of fact.
It doesn't try to call the method. It never gets there. The value/object is never seen as a Duck. It's not using a value as an arbitrary type. It was cast to any (which always succeeds), and then to something with a specific interface. It panics on the type cast. That's in the language spec: if you type-cast without checking the result, you can get a panic. I don;t consider C a duck typing language too, because you can write ((Bird*) ptr)->swim(), but perhaps you do?
> It doesn't try to call the method. It never gets there.
Sure, same as any other language with duck typing. Consider Ruby, which is famous for its duck typing. `variable.not_a_method` raises NoMethodError. How do you think it knows to do that? That's right, it first performs a type check and, since that check fails, it doesn't try to call the method and instead raises the exception. Exactly the same as Go panicking under the same circumstances.
> and then to something with a specific interface.
That is a type assertion, not a cast (Go doesn't have support for casts anyway). It merely asks the runtime: "Does this value satisfy the given type?" There is no change in type.
Now, let's take this further: It is generally agreed upon that duck typing differs from structural typing only in that it is evaluated dynamically instead of statically. Go's interface is quite clearly a structural type when evaluated statically.
And what do you think the type assertion does in the example given? That's right: It performs a type assertion on a "structural type" at run time. Duck typing, by definition!
> I don;t consider C a duck typing language too, because you can write ((Bird) ptr)->swim(), but perhaps you do?*
No. First and foremost, where would the typing come into play? That will actually try to call the method, whether the pointed memory is suitable or not. There is no type checking to steer you around mistakenly calling something that shouldn't be called. Not at compile time, not at run time.
It is literally called duck typing, not duck valuing. "Type" has significance. Where do you find it here?