I think this may have been this issue[0], which was fixed in [1]. Seems like the limit has crept up from 3 to 25 at some point in the last decade-ish, but in theory it should be undoable with 25X (or by mashing X to undo as many x commands as required).
[0]: https://github.com/philc/vimium/issues/1126
[1]: https://github.com/philc/vimium/pull/1128
The UK's ICO took a different stance[0] when the Washington Post tried to do this a few years back. For companies that want to do business in the UK, it probably makes sense to follow that more conservative decision.
The decision that you link also seems very much at-odds with the text of the GDPR (in both the German and English versions):
> (42) Consent should not be regarded as freely given if the data subject has no genuine or free choice or is unable to refuse or withdraw consent without detriment.
Interestingly, the decision that you linked prefers to rely on the case law of the data protection authority when interpreting the question of consent, in particular referring to rulings that predate the GDPR, despite its refinement of the concept of consent. It also focuses upon 'wesentlicher Nachteil' (significant detriment) where the original text of the GDPR prohibits just 'Nachteil' detriment. I find these choices rather suspicious, and wouldn't be comfortable with relying on them holding if challenged in other EU states.
Indeed, I overlooked that the ICO took a different stance. I have to admit that I did not research this myself, I just took the word of the (top-tier) law firm back then.
> The decision that you link also seems very much at-odds with the text of the GDPR (in both the German and English versions):
>> (42) Consent should not be regarded as freely given if the data subject has no genuine or free choice or is unable to refuse or withdraw consent without detriment.*
I don't see why they should be at odds with the decision? Quoting:
"Gibt eine betroffene Person keine Einwilligung ab, so besteht die erste Konsequenz darin, dass diese ein O*-Abo abschließen kann. Dieses O*-Abo ist – wie festgestellt – frei von Werbung, frei von Daten-Tracking und frei von der Setzung von Fremdcookies. Das O*-Abo ist mit einem Preis von 6 Euro monatlich ab dem zweiten Monat auch keine unverhältnismäßig teure Alternative."
It's obviously without question that one can charge something for a service rendered -- the newspaper does not have to offer this for free.
And in the above text, the authority then opined that charging 6 Euro for a monthly subscription to read a newspaper is not unreasonable, hence the decision to opt into tracking is a free one, because the alternative is simply to pay 6 Euro for a month's access.
Indeed, that is what they decided. However, I still find the interpretation very surprising.
The GDPR reads as if its authors had a different understanding. For example, the 'data minimisation' principle indicates that you should not be collecting personal data unless doing so would prevent the desired activity; serving an article, or even serving an article with adverts, can both be achieved without this data. There's also a question over whether the services are the same: a subscription appears to be materially different to one-shot access to an article, a question which is entirely overlooked in their analysis.
Beyond the weakening of 'detriment' to 'significant detriment' by reference to their pre-GDPR decisions, I also find the result unusual. The practical interpretation is that, if a user wishes to read 100 articles from 100 service providers all using this scheme, the cost of privacy is a significant detriment at €600. I am not confident that other data protection authorities will be as eager to jump to this same weakened interpretation.
There is probably a safer middle ground: giving the user the option to pay for either the article or the subscription, and allowing for either direct payment or payment by proxy through an advertising broker. In the latter context, the user's relationship and data-flow is controlled by the advertising broker, and the service provider needs no data relationship with the user. Of course, this shifts the controller liability into the advertisers -- something that they would probably prefer to avoid -- and I'm not aware of any services offering this or concrete decision on it yet.
> The GDPR reads as if its authors had a different understanding. For example, the 'data minimisation' principle indicates that you should not be collecting personal data unless doing so would prevent the desired activity
Indeed. It could reasonably be assumed that this is the main reason why the paid version does not use any tracking.
> There's also a question over whether the services are the same: a subscription appears to be materially different to one-shot access to an article, a question which is entirely overlooked in their analysis.
Well, the service is being offered on a monthly basis alone. The customer may only desire a one-shot access, but that offer is simply not on the table.
I may only be interested one-shot access to [some-Netflix-movie], but the smallest access unit Netflix is willing to sell me is a month. Same goes for certain gym memberships. etc.
> The practical interpretation is that, if a user wishes to read 100 articles from 100 service providers all using this scheme, the cost of privacy is a significant detriment at €600.
Accessing a 100 difference service providers is on the customer, though?
Same example as above. Say the customer wants to watch just one movie on Netflix, Disney+, and 98 other providers, all charging $10/month. $1000 per month sounds a lot but that's entirely on the customer; they could also just spend only $10 and watch 100 movies on Netflix.
Where possible, I prefer making the syntax opt-in, and explicitly so. For example, stealing OCaml's syntax:
let check_exp (g : Elliptic_curve_pt.t) (x : int) (y : int) =
let xy = x * y in
let open Elliptic_curve_pt.Num_syntax in
(g ^ x) ^ y = g ^ xy
This lets you avoid making hard decisions about what can be added/multiplied/etc. at the language level -- can a list of numbers representing the coefficients of a polynomial be added? -- without jumping to the extreme of allowing anything implicitly. This also lets the typechecker catch more of your mistakes by having stricter types, and means you know exactly where to go to find out what the syntax is encoding.
I think that exceptions are a problem and cause this developer burden only because they are invisible. If they appeared in the type signature, for example as
() -[DatabaseReadError]-> ()
then they would be part of a function's 'contract'.
With this, consumers of your function are making an active decision about whether to handle or bubble an exception without examining your implementation, and the type of the main function tells you which errors will end up being fatal.
Disclaimer: this is not a new idea. There are proposals for OCaml to add 'algebraic effects', which have similar annotations on arrows, and I believe there have been discussions around using the syntax to track exceptions.
At least, this is one of the major limitation of Java's Checked Exceptions idea, one which often forces you to use Unchecked Exceptions.
Another common problem is handling exceptions which occur while handling another exception. D has the best default I've seen in that area (it will automatically collect all of the errors, instead of panic()-ing like C++ or discarding the old exception like Java and C#).
There've been a few times I've used checked exceptions very locally in Java where I did use a type parameter successfully for this—though it's not really threaded through the type signatures in the standard libraries, so interop can be a problem. Almost like what you wrote, of course more verbosely, something like:
and it definitely worked the way I expected—if the correct exceptions weren't caught in processOurThings, it wouldn't compile, and processThingsSomehow did not have to catch them. It even worked in at least some cases with multiple throws on the concrete SomeProcessor, though I think the different exceptions involved had an upper type bound within the package; I don't know how well that's handled in the general case.
Nice, I never actually tried to do this (my problem was more that I needed to use built-in functions that don't throw, for example sorting a list with a Comparator which can throw).
> To fix that, you need to start supporting error polymorphism.
> map :: List a -> (a -> b -[err]) -> List b -[err]
FWIW, Haskell has this already; it's called[0] Traversable:
ghci> :t mapA
mapA :: (Traversable t,Applicative f) => (a -> f b) -> t a -> f (t b)
ghci> :t mapA @(Error ||) @[]
mapA :: (a -> Error || b) -> [a] -> Error || [b]
0: The default prelude calls it `traverse` instead of `mapA` (which is terrible for reasons that should be obvious[1]) and `Either Error a` instead of `Error || a` (which is a matter of taste).
1: Especially if you rename the method of Functor from `fmap` to:
map :: Functor t => (a -> b) -> t a -> t b
-- for comparison:
mapA :: ... => (a -> f b) -> t a -> f (t b)
And if the function can throw different kinds of exceptions, you need a way to express the union of unrelated exceptions (without defining a new variant type), a bit like Polymorphic Variants I guess.
Ideally also a way of saying "... except for X Y Z" while remaining appropriately polymorphic. I've remarked before that while checked exceptions help make sure you consider every possible situation, imprecision forces you to consider many (too many?) impossible situations as well.
This is exactly Java's checked exceptions, which I'd call a failed experiment in language design.
The problem is that it makes the most common case (letting the exception bubble up) very inconvenient and clutter-y. Signatures with 5 different declared exceptions are worse than useless.
It doesn't always make sense to plan the types ahead of time; letting the compiler do the work while you code and then creating a nice interface after is a reasonable way to work.
> Potentially dumb question here, but would it be generally possible to create a permissions system for browser extensions that can distinguish between an extension that is actually sending information based on sensitive sources like page content and browser history and an extension that only sends harmless stuff over the network like e.g. asking for updated ad block lists?
An invasive but effective strategy would be Javascript string/object tagging, where objects and strings derived from identifying API accesses are marked as dirty, and attempting to serialise these into requests or URLs triggers a permissions check. This would also give the option of replacing numbers and strings with junk data if the permission is denied, which seems pretty attractive.
Given the massive scope of a change like this, I don't expect it to happen, but it's nice to think of a world where any website or extension that attempts to exfiltrate data will be noticed by default.
The current position is "sorry for breaking your trust, please trust us". It's hard to find it compelling.
> Given the prevalence of comments like this, I wonder why any company would ever bother offering an apology or retraction.
To project my own opinion onto others: these comments are warranted because an apology has no actual value. The fact remains that Triplebytes can still do this if they wish to, and they are constrained only by what they can manage to slip past their users.
There's a stark asymmetry in the digital space, where service providers are protected by the legal language in their TOS or EULA, but the users have to trust that the service provider will not act outside their interests, and with no recourse. By contrast, in a normal contract negotiation, there will be an opportunity for both sides to ammend the contract to better serve their interests.
If Triplebytes wanted to show that they will not attempt to do this again, they could break this asymmetry and constrain themselves in their user contract, accepting all resulting liability or specifying concrete penalties if they do persue this route in the future. An apology is just a meaningless PR exercise.
> Why is this a hard thing to do? It’s literally what everyone who ever messes something up is asking you to do.
Because you're treating a service-client relationship as an interpersonal relationship. They are not, and the same norms do not apply. That apology, and its implicit premise(s) and promise, is rooted in the norms of intimate, interpersonal relationships. Those do not apply.
When you screw up and ask your spouse's forgiveness, the psychosocial interaction is quite different from when a CEO fucks up, writes a mea culpa to the faceless masses, gets his draft looked over by a PR flack and a couple board members, and then sends it out to the highest-impact social media circles for his service and waits to see what his KPIs do.
> Just because someone once committed a broken build, doesn’t mean I’ll never again trust them with access.
I don't think this analogy is useful. An error in execution can be quite different in an error in judgement.
To offer an alternative example: a contractor decides to publish the source code to a company's closed-source software, so that they can use it as evidence of their work for their next job application.
> It’s argubly more like “sorry for being a moron, but I hear you. Please give us another chance”?
When these kinds of bad judgement happen, the person normally loses some decision-making power to stop it from happening again. This is in noticeable contrast to Triplebyte here: an apology as a PR exercise, and no material change to prevent it in future.
It's more like your best friend telling someone the secrets you told them, and then expecting you to immediately trust them again with some more.
However much you'd like to, you can't just flip that trust back on - and in a lot of cases, it'll never fully go back to the way it was.
Not that we should personify company-customer relations - this was a decision that would have been taken by a lot of people expending serious effort to get it out the door. It's not a single lapse in judgement, but a continued expression of different values.
You make it sound like an innocent mistake, but they must have discussed this issue and decided that violating their user‘s privacy is acceptable. It’s not like they made a typo, it shows malintent.
Break the build, okay we give you a second chance, delete the database and all backups when you were hired as the DBA? You're probably going to be looking for another job.
I guess what's missing is the corrective steps they are taking to make sure a mistake like this doesn't happen in the future. I think even a short statement like "In the future, all feature plans will undergo a thorough review by an independent or in-house privacy expert before being greenlit." would give me more confidence that they understand that this was a privacy incident and not a PR issue.
Not a comment on the article, but it seems like the GDPR compliance overlay for securitymagazine.com isn't GDPR compliant.
To quote the GDPR at (4)(11):
> ‘consent’ of the data subject means any freely given, specific, informed and unambiguous indication of the data
subject's wishes by which he or she, by a statement or by a clear affirmative action, signifies agreement to the
processing of personal data relating to him or her;
and (7)(4):
> When assessing whether consent is freely given, utmost account shall be taken of whether, inter alia, the
performance of a contract, including the provision of a service, is conditional on consent to the processing of personal
data that is not necessary for the performance of that contract.
If there's an alternative link that sits better with EU law on this, I think it might be better to switch to that instead.
> > 8. You must not use or make derivative use of Facebook icons, or use terms for Facebook features and functionality, if such use could confuse users into thinking that the reference is to Facebook features or functionality.
As written, if the reference is to Facebook features or functionality, then there can be no confusion and this clause does not apply. This would seem to be the case here.
Facebook's stance doesn't really matter in the end though. It all depends on how this will be interpreted by a judge, and I have a hard time believing that a European judge would rule in favor of Facebook, since there's no possiblity of confusion for the end user. Also, it is done to protect end-user privacy, which European judges tend to like.
I'm adding European, because that's what the article is about and that's where I'm from. Not sure what would happen in a US court.
IMHO to be complete the law should require web widget providers to serve what it says on the tin.
AND NOTHING ELSE
If it is a button so that users can bookmark articles on the facebook website then it shall only do that, nothing else. And so on: the webmaster must host the image himself. If the functionality can be accomplished with html there shall be no javascript. If there is a need for javascript it will be hosted by the webmaster and shall require consent before calling home to the mothership.
For example, visiting a store doesn't give the store owner the right to search your bag.
Then lets not stop there and include all advertisement???
The advertiser knows the topic of the website he is advertising on, he knows what kind of audience is attracted by a specific article. He can place his advertisement at the top or the bottom to further filter down.
This gives him everything he need to advertise his product on that website. The web master can host the images. A neutral 3rd party, preferably a government agency, can track impressions and provide the advertiser with a crude estimate of traffic by region.
I think it shouldn't stop at having other people do all kinds of things and pay for it. The EU could easily fund its own technologies.
THE EU could give you [say] a Facebook like button in html and require you use it. That they have their own TOS is just irrelevant. Or worse, Facebook shouldn't have to invest in terms of service. We should have detailed laws removing the need for a TOS. Standard laws for social networks should apply.
A restaurant owner doesn't have to clutter up his place with 100 no smoking signs. There is no contract to sign before you can eat.
=== wasn't introduced until ECMAScript 3 in 1999, originally there was only == when the language was created in '95.
The accepted wisdom is to prefer the newer === in the interest of clarity and consistency. With ==, it's easy to forget about one of the types it overloads (e.g. string vs. number) when making changes to existing code, and correct-looking code may behave unexpectedly for one of these types.