JetBrains is and has always been a Czech (and, thus, EU) company, not a Russian one. Yes, the founders are Russian, but that does not make the company so. They did have Russian offices, but closed them after the start of the Ukraine war [1].
The only confirmed link to the SolarWinds attack seems to be that SolarWinds was using TeamCity (JetBrains' CI/CD product) and that this was alledgedly used as a "gateway" to SolarWinds' systems - which doesn't require any cooperation from JetBrains, just an unpatched security issue. In fact, a patch by JetBrains for the exploited issue seems to have been available, but was not installed [2].
So while any company deserves scrutiny, these particular allegations against JetBrains smell like FUD to me.
What you linked to is WASI-libc, which is a C standard library implementation on top of WASI - which itself is more low-level and less POSIX-like. https://github.com/WebAssembly/WASI
This point was recognized quite early. there is an influential article by Jack W. Reeves from 1992 [1] that looks at the manufacturing analogy and argues that "the code is the design" whereas the "manufacturing" is just the compilation and packaging (that is, super cheap and automated). I believe it‘s this line of thinking that inspired Agile practices, where software developers are seen as engineers rather than code monkeys.
To be clear, the difference is that an URI generally only allows you to refer to a resource ("Identifier"), whereas an URL also tells you where to find and access it ("Locator").
For instance, `https://example.com/foo` tells you that the resource can be accessed via the HTTPS protocol, at the server with the hostname example.com (on port 443), by asking it for the path `/foo`. It is hence an URL. On the other hand, `isbn:123456789012` precisely identifies a specific book, but gives you no information about how to locate it. Thus, it is just an URI, not an URL. (Every URL is also an URI, though.)
I started this to share various learnings from my dev work, as well thoughts on software engineering and architecture. The current two posts are on Redux, but I plan to publish posts on other topics (Kafka Streams, architecture, etc.) soon.
I recommend „Capital in the 21st Century“ by Thomas Pikkety, an economist who has deeply studied wealth and income equality using historical data spanning three centuries. This book has all the evidence you need.
Spoiler alert: income from wealth is on its way of becoming close to being as concentrated as it was in the 19th century (especially in the US), and the share of income from work in total national income is decreasing almost anywhere. So yes, increasingly you can only accrue significant wealth by already having significant wealth.
I really enjoyed the comparison of dependency injection with dynamic scoping, and the explanation of how the latter can take over the uses cases of the former with less boilerplate.
But one benefit of dependency injection unacknowledged in this article is that dependency injection is the explicitness of dependencies: the need to pass them in forces the caller to be aware of which dependencies exist, and changes in dependencies cannot be ignored (they lead to compilation errors in statically typed languages, at least).
Managing dependencies with dynamic variables, on the other hand, is implicit. It's impossible to know which parts of the dynamic environment are used by a module without inspecting its source code. And changes to the module's dependencies are not noticed by callers, which may lead to cases where tests fail to stub out particular side effects without anyone noticing.
Given this drawback, dependency injection still seems like the better trade-off to me, despite of its higher amount of required boilerplate. Perhaps it is possible to bring some of the explicitness to the dynamic scoping approach, though.
Yes, that's what I meant. The use of the term "API" for a single public code element is something I have not come across in any other language community, hence the clarification for those who are not familiar.
The crazy high numbers are due to a fairly Microsoft-specific definition of "API" in this context. What they count here is class members; so they ported a class with 15 methods and 3 properties, they'd count this as "18 APIs" (or perhaps 19 - not sure if the class itself counts as an "API" as well).
That being said, I'm sure there was indeed an impressive amount of code that had to be ported.
> Why should I build a model specifically for this one context of usage and have the properties tightly-coupled to their mutators, when I can completely decouple these things and have the models operate with any arbitrary state mutators?
Because otherwise, your domain model is not able to express which states are valid. A core idea behind encapsulation is that by controlling state mutations, it is possible to enforce invariants, thereby making invalid states impossible to construct. This idea is not unique to object orientation; for instance, in the static functional programming community, this is known as "making illegal state unrepresentable" [1].
By creating a "dumb" domain model and allowing business rule modules to do arbitrary mutations, each model is required to know about and enforce the domain model’s invariants itself, which dramatically increases the amount of code that potentially can break these invariants, and thus needs to be debugged if something goes wrong.
> Taking this a step further, you can have a business model project (class library/Nuget) that is shared across multiple projects within an organization.
This can work in some situations, but there are good reasons not to do this. Different teams may have differing and sometimes conflicting meanings for some of the terms of the domain (especially for generic concepts such as "user") as well as different data needs depending on the use case. This is why for instance Eric Evans’ "Domain-Driven Design" [2] argues for limiting domain model unification to "bounded contexts" [3] of which there may be multiple in the organization, and have explicit translation ("anti-corruption“) layers between the boundaries of these contexts.
Consider the Mozilla Public License (MPL) [1]. It is copyleft in the sense that modifications to the library must be MPL-licensed as well, but doesn't impose any restrictions on apps merely using the library. This avoids the LGPL’s complicated re-linking requirements which are very hard to fulfill for iOS apps (as mentioned elsewhere in this thread).
Variables alone are not a reason to use Sass anymore. There are CSS Custom Properties [1] now, which are even more powerful in that you can dynamically override them in specific sub-sections of the DOM. The only downside is that Internet Explorer 11 doesn't support them (if that's important for your target audience).
Looking only at the commit numbers of the `atom/atom` repo is a bit misleading as the Atom source code as the core plugin packages (e.g., the language modes, but also fundamental features like the tree and the fuzzer) are each in their own repo. For instance, the fuzzy-finder repo alone had 15+ commits in the last three weeks.
The only confirmed link to the SolarWinds attack seems to be that SolarWinds was using TeamCity (JetBrains' CI/CD product) and that this was alledgedly used as a "gateway" to SolarWinds' systems - which doesn't require any cooperation from JetBrains, just an unpatched security issue. In fact, a patch by JetBrains for the exploited issue seems to have been available, but was not installed [2].
So while any company deserves scrutiny, these particular allegations against JetBrains smell like FUD to me.
See also JetBrains' own statements on the SolarWinds thing: https://blog.jetbrains.com/blog/2021/01/06/statement-on-the-...
[1]: https://en.wikipedia.org/wiki/JetBrains
[2]: https://www.cisa.gov/news-events/cybersecurity-advisories/aa...