A handful of large players, each with less than 50% market share, can also distort the market and engage in anti-competitive tactics.
11,905 karma · joined May 21, 2009
A handful of large players, each with less than 50% market share, can also distort the market and engage in anti-competitive tactics.
Define "actually available"
Most public defenders offices are so oversubscribed and underfunded that they can't really provide good representation for the majority of their clients.
Bitcoin is just the first cryptocurrency that has actually managed to take off, but it's been a problem that cryptographers, and in particular cypherpunks (https://en.wikipedia.org/wiki/Cypherpunk), have been working on for a while.
Basically, what's happened is that this stuff that was kind of fringe and crazy back in the day, but people who were into it were really sure was the future, has actually made a major impact on the world.
If there's a broken traffic light in the city, do you expect some workers to come and spend their time fixing it just because it's broken and it's a good thing to do, or do you expect them to get paid to do it?
Now, one could argue that fixing bugs in open source software is a public good, like the traffic lights in a city. So maybe the government should pay for it? Well, I could perhaps buy that argument, but getting increased public funding for that sort of thing is likely to be hard, and it's hard to tell where that money is best spent.
But certain fixes, or new features, will help some people a lot more than others. If you would benefit from a particular bugfix, and someone else will need to do work for it, why not they ask you for money to fix it?
For much of it, if we find a bug, we either fix it ourselves locally, or go through the normal process of submitting a bug report, possibly submitting our own patch, and waiting for a fix from upstream, while finding some way to work around it or the like.
For some of the software that is central to our business, we have a contract with a company that provides support and development services. If we have a bug that we need fixed right now, we get in touch with them and pay an agreed upon rate to do so.
We don't do this for everything we use, because most of it works off the shelf, or we just replace it or work around it, or the open development process works well enough. But for those things that are absolutely key to our business, and for which there's a consulting company that employs several of the core developers on the project, it's definitely worth it to pay for the support that we need.
A few of the improvements that Rust offers are compiler enforced move semantics by default, so assigning, returning, or passing a Box<T> (similar to unique_ptr<T> in C++) will move the ownership to the new location and statically check that you never try to access the old location. In C++, you have to explicitly call std::move(), and checks to make sure you don't reference the old one happen at runtime.
Rust also does safer checking of use of references. In C++, it's possible to return a reference to a stack variable which is no longer valid. In Rust, the lifetimes of references are tracked statically, so you can never have a dangling reference.
So, while the RAII pattern, use of smart pointers, and use of references, will feel fairly familiar to someone familiar with modern C++, they are actually generally more convenient and more safe in Rust.
Rust does not have classes. You define plain old data structures, and use traits to provide polymorphic behavior. Traits are somewhat like interfaces which can contain default implementations of methods. Traits can be used to constrain types. Traits can be used to provide either static (compile time) dispatch, or runtime dispatch, depending on whether the object is monomorphized at compile time or accessed through a fat pointer that includes a vtable to dispatch at runtime.
Rust provides generics which fill a similar niche to templates in C++. In some ways, they are more powerful as arguments can be constrained by traits; in some ways they are less powerful than C++ templates.
For an introduction to traits in Rust, take a look at the book: https://doc.rust-lang.org/book/traits.html
Rust doesn't provide operator overloading directly, but use of operators is equivalent to just calling a method defined on a particular trait in Rust. So, "a + b" is will work for any types that implement the Add trait (https://doc.rust-lang.org/std/ops/trait.Add.html), and is equivalent to calling a.add(b).
I was mostly responding on the basis of desktop browsers, since most of the rest of this thread has been about desktop browsers. You're right, on mobile the WebKit/Blink duopoly, with the shared code base that does mean that they are closer on feature and bug parity, is pretty problematic, but even there I'd say we're in better shape than the early 2000s IE monopoly.
> Mozilla Research are paying me to work on that in the coming months, as Servo doesn't have the user base that would show many of the site compatibility bugs that arise as a result of their bugs, leaving them disproportionately reliant upon the test suite
Nice, that sounds like it'll be quite useful. I am eagerly anticipating being able to actually use a browser based on Servo day-to-day. There's quite some ways to go, but it's great how much progress its made so far.
For one, WebKit is now forked, into WebKit and Blink. Both of them are rapidly diverging. And there are still enough people using Gecko and Trident (and now EdgeHTML) that you can't just target the intersection of WebKit and Blink and still have any reasonable kind of coverage.
For another, I think you fail to understand just how dominant and stagnant the browser market had become when IE was dominant. Not only one browser, but one version of one browser, had over 90% market share, and in controlled environments like corporate networks, effectively 100%. In that kind of environment, it was completely reasonable to just target that one browser.
Today, even if you add up all of the WebKit and Blink browsers based on the most generous market share counts, you won't break 70% market share, and there are even still some statistics that have IE/Trident at over 50% market share. So unless you're targeting a very specific market, like iPhone users (where yes, WebKit's share is 100% due to Apple's monopoly), it's very hard to find any demographic in which there is such a strong dominance as IE had back in the day.
Additionally, browsers and engines are actually being released at regular intervals these days, with new features and bugfixes. Firefox/Gecko and Chrome/Blink are on rolling 6 week release cycles, meaning that there's very little lag to getting new features and fixes out. Safari/WebKit is released less often, but once every year or two. There were 5 years between the release of IE 6 and IE 7, and IE 7 didn't even pass Acid2, it would be another couple of years until IE 8 did. That extremely long period of time in which one version of one engine was so dominant led to an awful lot of sites designing themselves exactly around the bugs and quirks of that one engine.
Couple that with the fact that standards committees are actually working on features that people want, and are making real progress. XHTML stagnated the standards process for a long time, working on a backwards-incompatible specification that did a lot of architecture astronautics on representing documents, when what people needed were backwards-compatible enhancements that supported web applications so they could roll things out incrementally as support became good enough. CSS got a bit mired in CSS 2, but CSS 2.1 allowed them to slim down the specification and get out something working, while CSS 3 allowed them to work on individual features separately, and thus be able to make progress without having to wait for everything in the world to be ready. Another big reason for IE's dominance was that it had proprietary features, like filters and ActiveX and webfont support, and there were no standards that covered similar ground. Now we have HTML5, a plethora of new APIs for interacting with the browser, a substantial number of CSS enhancements, highly competitive JavaScript engines that are capable of running full 3D engines, and so on.
And finally, WebKit, Blink, and Gecko are all open source. People can be involved in helping find and fix bugs, implement new features, port them to new platforms and devices. A big problem with IE was that it was proprietary, and ran on one platform. You could build a desktop browser that ran on Windows with your own chrome around it, but that was about it. Now, you want to make some cool new device that needs web rendering support? You want to experiment with interesting new ways to present web content? You now have several high-quality, open source options to choose from, which have enough market share that most sites have done the compatibility work to make sure they are compatible.
Sorry for the wall of text; I just wanted to make sure that you understand the history, and how very different the present situation is than the one in which the IE 6 monoculture flourished. It can be a bit worrying how two engines with a common ancestor have such dominance on mobile, WebKit and Blink. It's also worrying that Apple's monopoly prevents people from installing browsers with more up-to-date engines on their phones; I think it's an abuse of their control of the platform. But even so, they don't have the kind of market dominance even on smartphones that Microsoft did on desktops back in the early 2000s, so while it's worrying, it's nowhere near as bad.
It seems to me the whole point of the vouch features is to have an easier recourse for other commenters to respond to people being shadowbanned (or otherwise dead for mistaken reasons, like tripping a filter or unfairly flagged by other users), rather than actually having to find the mod email and send an out of band message.
In this comment I just discussed Go, since that's what the parent comment mentioned.
Haskell and OCaml are both great languages, but to a lot of people, they come off as much more "academic" or "ivory tower," and require a lot more effort to learn to use effectively for people who are not used to functional programming.
Couple that with the fact that they still use GC, so are a lot harder to get consistent low-latency performance as well as being a lot more difficult to use for any applications where you need to embed them in other applications, and they just don't offer enough of a reason to move to them over the current combination of "Python for high-level stuff, C or C++ for low-level, performance sensitive stuff".
Rust, on the other hand, promises to be effective for the low-level, performance sensitive stuff, is good for embedding in other languages, offers the additional benefit of giving statically checked memory safe multithreading with shared mutable data structures, and provides a powerful static type system for effective programming in the large.
OCaml and Haskell have somewhat odd syntax, for someone who is coming from C like languages or even Python. You need to learn a bunch of functional programming concepts to use them effectively. You are still limited in what you can do, such as writing a native extension module for your existing Python code base. And they don't really help on one of the major selling points of Rust, which is to be able to write safe multi-threaded code with shared, mutable data structures. While there may be lots of good high-level parallelism available, at some point for certain problems you really just want to be able to use a shared, mutable data structure, but doing so in almost any language but Rust makes it very easy to make a mistake and have aliased, mutable references to it that can invalidate all of your logic, even if it isn't actually memory unsafe.
I am not looking at Rust merely for replacing C for native extension libraries.
I'm looking at Rust for having a good static type system; I'm getting very sick of dealing with "hashly-typed" data in Python, or all those places where I forget a yield and so never actually block on a deferred, causing errors at runtime rather than just not compiling (sometimes type errors, if I try and access that value, but sometimes just things executing out of order, which are much harder to debug).
I'm looking into Rust for having a good multi-threading story. I've been doing plenty of event-driven programming in Python (using Twisted), which is great for non-blocking network I/O, but there are other ways to block on long computations, disk I/O, blocking in native libraries, and so on. At some point, you really do need good multi-threading, and Python falls fairly short in that department. You can hobble by, but it's not pretty.
Go doesn't solve either of these problems. It has slightly more static typing than Python, but without generics, it's pretty limited. It doesn't really do anything to prevent nasty race conditions with shared data structures in multithreaded code. Sure, if you are disciplined and use only message passing of immutable data structures, you can avoid some problems, but part of the point is that when programming in the large, with multiple people working on something over multiple years, it's easy for some mistakes or bad assumptions to creep in an wind up causing problems.
I've taken a look at Go, and it never really appealed to me as a direction to move in. If I want message passing concurrency in a GC'd language with a runtime, I can use Erlang/Elixir. If I want just simple, pretty code without much multithreading, I can use Python. If I want raw performance and low level access, I can use C or C++.
Rust actually does offer advantages over all of these. It does have it's complexity, so for quick and dirty scripting tasks I'm likely to stick with Python. But especially once Rust gets an easier to use non-blocking I/O story (since event based non-blocking is great for networking), I'm going to be seriously considering it simply as a replacement for Python for any large project that will be worked on by several people over several years, just due to the additional safety and static guarantees it offers.
No one actually expects to replace all cars with bikes. But replacing 20% of them would substantially cut down on congestion and emissions; and avoiding further growth in automotive traffic is likewise important.
And yes, I do see parents taking their kids to school by bike; in fact, my father used to do it with my younger brother some 25 years ago, and just yesterday I passed one of my neighbors heading up our very steep hill with her child on the back of her cargo bike.
There isn't a zero-sum game to be played between cars and bikes. Improving bike infrastructure can lead to reduced congestion for cars, fewer bad interactions between drivers and cyclists, etc.
I'm glad that Debian and Ubuntu have finally decided to go with an actually maintained init system, that properly track processes even after arbitrarily many forks and support a reasonable readiness protocol.
For those of you, like me, who may not be very familiar with modern phylogeny and taxonomy, here's the path I charted down to "Homo Sapiens".
Check out under Eukaryota (which includes plants, animals, fungi, and a bunch of single celled organisms), then Opisthokonta. Under that you'll find Nucletmycea, which contains Fungi, finally getting down to a more familiar classification. Another branch under Opisthokonta is Holozoa, which you can then trace down to "Choanomonada + Metazoa", down to "Metazoa", which Wikipedia tells me is another name for "Animalia" (https://en.wikipedia.org/wiki/Metazoa). You can trace down under there to Bilateria (via a few nodes with multiple groups, I've elided those nodes from now on), to Deuterostomia, to Chordata, Craniata, Verbrata, Gnathostomata, Teleostomi, Euteleostomi, Sarcopterygii, Dipnotetrapodomorpha, Tetrapoda, Amniota, Mammalia, Theria, Eutheria, Euarchontoglires, Primates, Haplorrhini, Simiiformes, Catarrhini, Hominoidea, Hominidae, Homininae, Homo, and finally Homo Sapiens.
Also, this is not yet a replacement for systemd:
#include <stdio.h>
int main (int argc, char * argv[])
{
printf ("defer work on the pid 0 until we have a functioning "
"service manager\n");
return 0;
}
(I think they mean "pid 1")You can't prevent people from having tools that can be used to manufacture things, and no one is seriously going to try.
For instance, in species with sexual differentiation, two males or two females cannot mate, but are considered the same species.
For a more precise definition, you would have to, say, look at the probability that a pair of organisms of the appropriate sex from two different populations would be able to mate, and produce viable offspring (that is, offspring that could themselves mate and produce more offspring).
Asking about a single organism that happens to be infertile, or a single pair that happens not to be able to mate or produce viable offspring, is not particularly interesting, but at a population level you could use a statistical test to get a probability distribution, rather than a yes or no answer.
See https://en.wikipedia.org/wiki/Species#Difficulty_defining_or... for more information.
Note also that it can be the case that two different species can mate, and produce offspring, but the offspring itself is not viable (cannot mate and produce offspring). This happens in the case of mating two closely related species, such as when mating a horse and donkey to get a mule (https://en.wikipedia.org/wiki/Mule), or a lion and a tiger to get a liger (https://en.wikipedia.org/wiki/Liger).
So, have someone who is "open" to it go and view something that they haven't otherwise had a chance to perceive in person, then when they wake up tell the experimenter what it was. If it's easy to reproduce, then they should be able to do that, and it should be easy to verify that they had an out of the body experience.
Instead, you just get anecdotes, of people repeating past experiences with no controls to blind it. Human memory is surprisingly faulty, people can fill in details later on in their memory, and so on. So it's very easy to think that you had a dream in which you saw something for the first time, and then later recognize it while you're awake; but it's also possible that you brain just filled in the memory when you saw it later. Or maybe you had seen it in the past but didn't have conscious recollection. And so on.
Simply hearing people say that they had OOB experiences in which they saw things that they never saw in person is not particularly credible.
I know that in practice in Rust, the general approach is to write safe wrapper around any C libraries you're using, so the use of nullable pointers is generally confined to those wrappers.
I think that anything which has no null in normal, idiomatic code, outside of "unsafe", "ffi", or similar subsets, should get 5 stars. The distinction is really about whether you need to worry about any possible value, or any possible reference, being null, which you do in languages like C or Java where all references are nullable.
Giving Java and Rust the same 4 star rating because they both have some form of null and some form of Maybe/Option is a bit misleading. In Rust, Option is what you use in any normal code, and so you don't need to check for Null everywhere. In Java, it's the other way around; nullable references have existed since the beginning and are not segregated in any particular way, while Optional is a recent addition.
Likewise, I think that in Scala and Swift, null is only present for compatibility purposes, and idiomatic code does not use them. I'm not sure about F#. Clojure does use nil idiomatically, and also has '(), which may even count as "multiple NULLs" according to this rubric, though I guess that in Clojure '() is just treated as an empty list, rather than a null value like it is in other Lisps.