Strict or no, Google actually fails at accessibility a lot. The basically broken unergonomic keybindings in docs for starters and the entire fiasco that is Android come to mind immediately. For a really "fun" fail that's recent, Youtube recommendations are now a live region. This means that if you leave that tab focused, your screen reader just starts reading things while you're trying to play music and are across the room and can't stop it. That seems like a minor example except the whole point of Youtube is hearing things so that's kind of a big ball for someone to drop, thinking that live regions are a good plan. Things have improved some (I no longer hate the GCP console) but my point is that strict about accessibility doesn't mean good at accessibility by any means, and Google has a deservedly bad reputation in blindness circles that they earned over a very long time.
HN user
CAMLORN
Sadly the screen readers do actually do a not-so-good job of this, but I think that may in practice be more a function of poor UI for switching indicators on and off. You get 80 cells at most, and even the most conservatively unambiguous abbreviations for controls are going to use 2-3 letters of that. Hit a line with a few links and half your display is gone. I'm not enough of a braille user to know how to go about fixing this for sure, but there is definitely an inefficiency. Ending up in a "but my favorite text-based browser is more efficient" position because it turns a bunch of this off, or because it's configurable in a way your favorite screen reader isn't, or etc is something I can see happening, but nonetheless the real issue there is that screen readers need to be fixed, not that we should go ask all the sighted people to support Lynx.
NVDA's flow for deciding which formatting you care about is to tab through a list of 30 checkboxes. They have hotkeys when the dialog is open but it's still less than ideal if, as I suspect, braille users need to change them more often. And there is also a potential education problem around teaching braille users that the way they get more efficiency is to change them around all the time.
My solution in the world of infinite resources would be to make the cells 5 or 6 dots high so that you can put the formatting in line with the characters it's for. That's something I thought would be useful for a long time. But sadly we live in the world where good braille displays will forever be expensive and thus doubling the price isn't doable.
I own a braille display and use the 93-volume trigonometry textbook from high school and the logic around it with respect to making sure the right chapter was in the classroom with me as an analogy when explaining CPU caches to people. In the long run I discovered that incredibly fast speech rates scale better than braille for most tasks outside educational settings, but if it works for you, by all means use it. And before someone inevitably makes the "but braille is important for literacy and brain development" point: it is, and I advocate learning it.
However, putting the burden on site developers to support text-based browsers for this use case is O(sites) but putting it on the screen reader developers is O(1). In other words only the latter scales. Braille isn't a very good argument for site authors supporting text-based browsers from any practical perspective, and in all honesty I think most of them would find this off-putting. It's already hard enough to get people to do accessibility; if we make the bar as high as that and go around claiming that it's necessary for accessibility, no one will ever bother.
Sadly no. Making charts accessible is an unsolved problem. There have been some efforts for accessible graphing calculators that work more or less, but it's not trivial to make a generic one-size-fits-all solution.
For Sheets, the underlying stuff that runs it is quite complicated. They ended up doing something akin to an offscreen model with HTML to make it work because afaik they use a canvas of some sort to draw everything. In fact, unless you turn on braille mode, both products actually have a built-in screen reader that talks via aria live regions. That's terrible practice, but to their credit they got ahead of what the internet was providing for accessibility and didn't have a choice in that regard.
For something you can practically implement without a huge project, I suggest text descriptions of the data. If you want to do a bit better, make it an HTML table--that'll give some convenient navigability for free.
From my perspective there is very little difference. The interface I get out of Firefox is exposed as if it were a text-based browser for lack of a better analogy (it's not quite the same, but the differences are subtle and not obvious at first glance). But I also get the ability to do all the non-text-based-browser things with that interface instead of being limited to what a text-based browser supports, and those things can be made accessible to me. But the really big advantage is that my skills at driving Firefox also work with Chrome, IE, and Edge, and any web view on the platform. Plus there is a large common subset that is shared with all the desktop apps as well.
I'm not the right person if you're looking for someone who shares enthusiasm for text-based browsers, in other words. In general I would like it if people would stop using blindness as a point in their arguments that they're necessary because it shows a massive misunderstanding of what the world of accessibility is like.
Firefox and Chrome both have mature accessibility API implementations at this point. Edge is also at least okay. Internet Explorer has worked forever. You then couple those with a screen reader--most commonly Jaws or NVDA--and you get something that very much resembles Emacs or what have you: there's around 50 or 60 keystrokes I use on a regular basis. It's like a local client-server model (indeed documentation on this topic uses those terms). You couple something implementing the server with a client, i.e. a screen reader, a one-switch controller, speech recognition, what have you, and those consume exposed semantic information. Browsers then map web pages to the platform's accessibility model for consumption.
NVDA offers scriptability for the web and otherwise in Python as well, so anything it can't do can probably be added. For instance there's an add-on for using your local screen reader to control a remote machine, provided that both run it (not the most applicable to accessibility, but a good example of how far you can take NVDA's scripting). Jaws also does much of this but is much more proprietary including an only half documented scripting language.
The quickest way to get some idea is to probably look at the NVDA user guide: https://www.nvaccess.org/files/nvda/documentation/userGuide....
iOS is also good. unfortunately Apple very much dropped the ball on OS X and hasn't picked it up again, but my brother (also blind, it's genetic) did an entire business degree on an iPhone because he didn't want to be bothered learning a laptop. That's a loss in efficiency, but even the lesser options are now sufficient enough that a non-programmer can pick them up and go get a college degree.
There is an idea that goes something like "Obviously screen readers have to struggle to present information, therefore dedicated text-based browsers are better". That was true in 1995 when we didn't even have MSAA. I know people from that era and they had to hook APIs in other processes at runtime. But in actuality, once you expose the accessibility tree and hand it over to the people who want to use it, good things happen.
I appreciate your assistance but I can check spelling; a simple "Did you know that it's Lynx" would have sufficed. Good to know there's two text-based browsers. I didn't, but I and everyone else I know will go on not using either.
Google themselves are your example. Leaving aside some horrible accessibility keybindings in Docs, both Docs and Sheets are basically fully accessible. in fact Sheets is the best spreadsheet program I've used. It's not as powerful as Excel, but Excel is laggy for a variety of technical reasons that shouldn't exist, at least with NVDA. I can also read presentations in slides, and I might be able to make one. I've never tried; web or not, making slides just isn't something super feasible for a blind person if it's going to look any good.
I have gripes about Aria. It's definitely possible to abuse this stuff and end up with an inaccessible mess, but overall we have been trending toward a more accessible internet and things like the aforementioned do exist.
I've been blind since birth. I started on a device called the Braille 'N Speak 2000, which functioned very much like Emacs. I don't use Emacs because Emacspeak requires Linux desktop and adds a ton of extra complexity on top for very little gain. Linux dropped the ball big time on accessibility and audio in general, and never really recovered. Obviously this is opinionated, but I feel like you're implying that I lost my vision later in life and am forming my opinion around that perspective. You might additionally want to look into Jaws and NVDA. Learning those is about as bad as learning Emacs or etc; knowledge from when you were sighted doesn't transfer in the slightest and the interface is much more arcane than you probably imagine it to be.
I see this like supporting DOS in 2019 or somesuch. There might be an esoteric reason to do so but when 99% of the userbase has left and the old thing can't support new technologies, saying that we need to support the old thing forever because a tiny subset of users still use it stops meaningful progress. If there weren't plenty of good, modern options I would be all for Links but there are, so I'm not. At some point it's on the user for choosing not to leave their little island of familiarity, especially when the user is technical enough to be using Links.
I am blind. I know or have known at least 20 other blind people sufficiently to know what their browsers are. None of them used Links. One of them used Edbrowse. The rest (including myself) are Firefox, Chrome, or Safari. I have at least one personal project (not public) which uses React heavily. Saying that Links is necessary is an outdated view, so much so that we have things like the accessibility object model [0] in progress to possibly go so far as even supporting use cases like remote desktop connections in the browser by making fake screen reader only nodes in the accessibility tree.
In general, the terminal itself is even not so great. There are efforts like Emacspeak which mandate learning what is essentially a second desktop environment, but outside that it turns out that offering semantics (which only non-text browsers and apps can do) is useful: for example knowing whether or not the cursor is in a text editor, so that deletions are significant, or whether text is a table.
The idea that JS is bad for screen readers--or indeed that we use text-based browsers--is a consistent misconception that is no longer true. It was true 10 or 15 years ago, if not longer, but everything AT has come a very long way since then.
For a source that's not just anecdotal, this has info on primary browser: https://webaim.org/projects/screenreadersurvey8/
In the insert case call the function InsertWithAllocqation, and also provide an Insert variant that doesn't allocate but can fail. In the reversing case, call the function ReverseInPlace, then require the user to make a copy either before or after. This gets you the same goal--not hiding the costly allocation--while also making it convenient to use and removing the possibility of mistakes.
The real problem is that without generics, such functions actually have to be written in the same fashion as sorting where you provide a function for reading and writing both, as opposed to just working--so the "simple" loops which are indeed error prone actually become less code, and we all use them instead. I highly, highly doubt even the best Google programmer will always get the boundary condition on that reverse a list loop right especially in an emergency or at 3 AM, and this is a very simple case where Go just can't abstract on par with anything-with-generics.
But my point is that you can meet the goal of not hiding operations just with good naming, if that's what you consider a terminal value of good pl design, and don't need to forego abstraction to do it.
Screen readers have a lot of commands for reading different sized chunks of content. In general there's probably around 50 keystrokes I use on a daily basis. It's not as straightforward as reading from top to bottom, though it can be. I can usually do a Wikipedia article without pausing at 450 or so.
If anyone is curious, here is the NVDA keystroke reference: https://www.nvaccess.org/files/nvdaTracAttachments/455/keyco...
As an interesting sidenote, screen readers have to co-opt capslock as a modifier key, then there's fun with finding keyboards that are happy to let you hold capslock+ctrl+shift+whatever.
They're harsh. But you get used to it in about a week. Espeak is an atypically bad example, which is why NVDA experimented with a fork (and maybe one day the NVDA work will make it upstream). part of what allows them to stay intelligible is the harshness. I've never tried passing one through an EQ but there are already pitch settings and similar to play with, and given that even not wearing headphones slows me down I expect that an EQ would probably be bad for it.
But more to the point there is nowhere to really plug that in to a screen reader, so we can't try it anyway. The audio subsystems of most screen readers are much less advanced than you'd think.
But when the in-group is defined as "is blind"?? I'm not just talking about programmers in this context, or any other cross-section wherein there's some sort of shared vocabulary and context other than the disability itself. I don't think it's been studied, but I've noticed, my parents have noticed, in general enough people around me have noticed it over the years that I'm convinced the effect is real. Is whatever mechanism you're referring to typically general enough that the group can be defined this broadly and still have it happen?
You can pass Espeak recordings around legally. It's just GPL. The license applies to the software, not the content produced via it.
I will attempt to remember and find the time to take my demo recording of this on Rust compiler source code that's currently in dropbox and put it up somewhere more permanent. I doubt Dropbox will care for me much if I allow HN-volume traffic to hit my account. It's Espeak using an NVDA fork with an additional voice that some of us like, so vanilla espeak is in the ballpark.
What I don't remember is if vanilla non-libsonic espeak softcaps the speech rate. It might. I believe new versions of espeak integrate libsonic directly, but that old versions just silently bump the speaking rate down if it's over the max. I haven't used command line espeak directly for anything in a very long time.
Libsonic is an optimized library specifically for the use case of screen readers that need to push synths further: https://github.com/waywardgeek/sonic
Location: Seattle
Remote: Strongly preferred
Willing to relocate: Not right now
Programming languages: Python, Rust, C++, some JavaScript and Go
Technologies: Most of Google Cloud platform, Kubernetes, SQL (Postgres, BigQuery), RabbitMQ, PgBouncer, the Django/Celery stack, enough bash to be dangerous, CMake, Appveyor and Travis CI, some Windows COM.
Résumé/CV: https://ahicks.io/files/resume.pdf
Email: ahicks@ahicks.io
I'm an experienced backend software engineer/generalist with experience on every level of the stack. Highlights include designing custom priority queues, writing a microservice monitoring solution, debugging distributed locks, and participating in multiple AWS to Google Cloud migrations. I've been involved with 4 billing systems and wrote two of them. My favorite professional project so far is an incredibly massive Kubernetes-powered media transcoding cluster. I've also got some extensive ops experience.
My experience with lower levels of the stack comes from my personal projects. The most impactful of these was implementing a significant optimization in the Rust compiler which reorders struct and enum fields to reduce the memory footprint of your code. It's much more complicated than it sounds. I've got a write-up on my blog [0] My other sizeable personal project is Libaudioverse [1] a large C++ library for audio synthesis not dissimilar to WebAudio [2]. Highlights include a parallelizing workflow engine and hand-written SIMD optimizations.
I'm looking for a full-time position with either scheduling flexibility or at least part time remote. My favorite technology is Rust, but I'm open to anything.
0: https://ahicks.io/posts/April%202017/rust-struct-field-reord...
1: https://github.com/libaudioverse/libaudioverse
2: When I started, WebAudio was barely on the horizon. Once the spec reached a degree of maturity, I read it and realized I'd built roughly the same thing.
Location: Seattle
Remote: Strongly preferred
Willing to relocate: Not right now
Programming languages: Python, Rust, C++, some JavaScript and Go
Technologies: Most of Google Cloud platform, Kubernetes, SQL (Postgres, BigQuery), RabbitMQ, PgBouncer, the Django/Celery stack, enough bash to be dangerous, CMake, Appveyor and Travis CI, some Windows COM.
Résumé/CV: https://ahicks.io/files/resume.pdf
Email: ahicks@ahicks.io
I'm an experienced backend software engineer/generalist with experience on every level of the stack. Highlights include designing custom priority queues, writing a microservice monitoring solution, debugging distributed locks, and participating in multiple AWS to Google Cloud migrations. I've been involved with 4 billing systems and wrote two of them. My favorite professional project so far is an incredibly massive Kubernetes-powered media transcoding cluster. I've also got some extensive ops experience.
My experience with lower levels of the stack comes from my personal projects. The most impactful of these was implementing a significant optimization in the Rust compiler which reorders struct and enum fields to reduce the memory footprint of your code. It's much more complicated than it sounds. I've got a write-up on my blog [0] My other sizeable personal project is Libaudioverse [1] a large C++ library for audio synthesis not dissimilar to WebAudio [2]. Highlights include a parallelizing workflow engine and hand-written SIMD optimizations.
I'm looking for a full-time position with either scheduling flexibility or at least part time remote. My favorite technology is Rust, but I'm open to anything.
0: https://ahicks.io/posts/April%202017/rust-struct-field-reord...
1: https://github.com/libaudioverse/libaudioverse
2: When I started, WebAudio was barely on the horizon. Once the spec reached a degree of maturity, I read it and realized I'd built roughly the same thing.
I'd agree with you here, but Rust is powerful enough to abstract serialization behind a macro. You'd probably be using something like Serde instead of writing your own decoder. The macro just adds repr(C) for you and does it, if that's the design it wants to use. Rust's capabilities for abstracting in this way are still expanding, so if it can't today then it probably can tomorrow.
Nonetheless, other things which aren't stable include the discriminant values of an enum and whether/if we use the null pointer optimizations. And probably others. Doing this to any Rust type is not safe as-is, and guaranteeing an ABI for all types just freezes the algorithm, as I've said elsewhere in this thread. SO I'm not seeing how this is a particular problem.
I haven't looked at libstd, so I can't comment to that specifically. But we don't reorder two-field structs.
Rustc special cases them in a lot of places to do things that I will not even pretend to understand, and not reordering 2-element structs keeps them working. Since this already took 6 months of my free time (I have a lot of free time, though not 40 hours a week admittedly), this was for the best.
You can make an argument that we should have, but it doesn't matter from the user's perspective. (a, b) is the same size as (b, a) no matter what a and b are.
This is admittedly a bit ranty, but it hits some important points that a lot of sighted people miss, so I'm posting it anyway.
People have started going down the blind programming language road; look up Quorum. What's not obvious about it is that mostly it's used at schools for the blind.
But I think it's incredibly stupid. I'm a very good C++ programmer. I'm at least reasonable at Python. I know enough Haskell that I'm no longer actively frightened of the monad (i.e. a newbie, but past the biggest hurdle). Obviously I both know and actively like Rust.
You can make a programming language for the blind. You can't make people use it. if we go down that path, we end up in a world where blind programmers work for the blind programming shop because the rehab agencies push you there. And then you make less money.
I know at least 10 other blind programmers. 3 of them either work or have worked at Microsoft. 2 of them maintain my screen reader, which is something around 40000 lines of C++ and Python doing incredibly complicated things to fully hook into the OS. One of them is either currently at or has worked at Google; I'm not in touch with him anymore, so I don't know if he moved on or not.
We don't need programming languages for the blind. We need people to stop tying technologies closely to IDEs and then not making said IDEs accessible.
My other project, Libaudioverse, is cross platform. The irony is that this is because VS was inaccessible. I used CMake instead and learned cdb when I needed a debugger. VS is at the point of dreadfully inconvenient but workable now, but I still don't use the Microsoft stack. It puts me in the position of being at their mercy--if they roll out a new UI tomorrow and it's inaccessible (as they did with 2010), all my personal projects stop instantly, and I maybe lose my job when my employer upgrades it, depending how bad it is. Microsoft is one of the better places for accessibility; there are issues with VS for screen reader users that have been around and reported for years.
Depends on the standard. there are parts of pep8 that are nearly impossible for me to follow, namely the bits about indenting complex expressions that span multiple lines. I mostly don't care about it, save for indenting by fixed amounts at every {. My screen reader can announce changes in indentation level, so it's a way to not have to remember if we're 3 or 10 braces in.
I make the effort to match formatting but I hate it because I get basically no benefit, and the early reviews here had lots of places where eddyb made me change it until I finally learned all the rules for this project. A standard formatting tool and official list of rules for Rust is in the works. That'll be nice to have.
In fairness, the compiler is actually simpler now. Perhaps not as simple as if fields were always in order, but we only determine what type layouts should be in one place instead of two now, and 99% of what you have to do in the rest of it is just foo.memory_index[i] instead of i in all the places you want a field index.
There's also a helper function that lets you invert it. The part of the compiler that builds LLVM types just uses this.
The cost here isn't complexity, it's that "Fields are in increasing order by offset" has been baked into the compiler for years and you have to make sure to change them all.
The first time I think I saw the idea was [0], but I don't know if this is the post that got linked in the discussion threads. Rust didn't have fuel at all until after my changes, and I don't think it's necessary to use it as a limit unless you're letting the optimizer run on the optimizer's output until it stops changing. The number of optimizations Rustc can run is already finite because it doesn't do so.
nonetheless, the idea isn't original to us.
0: http://blog.ezyang.com/2011/06/debugging-compilers-with-opti...
There are two specific cases here where the layout is not obvious.
The first is the null-pointer optimization (I think this is the official name but I swear I question myself every time I mention it), in which we use knowledge that an inner struct contains a reference to avoid enum discriminants. that is, Option<i32> will have an extra field up front saying if it's None or Some, but Option<&i32> will just encode None as the null pointer because references can't be null. This also optimizes something like Result<&i32, ()>. The net result is that a lot of stuff that looks expensive is basically free. There has been discussion of extending this to use multiple pointers so that we can hit more complicated enums like Option<Option<(&i32, &i32)>>, but this has thus far not happened.
The second is enums themselves. The discriminant algorithm is not obvious. If you want a discriminant of a specific size, you can pick it with a repr. But otherwise it's implementation defined.
And there is one third thing we have discussed doing but haven't yet. If you have a bunch of enums nested inside each other, having multiple discriminants is a waste. There is no reason the compiler can't just collapse them down into 1 in a lot (but not all) cases.
For anyone who wants to know the specific algorithm for all of this, it's now all in one place: src/librustc/ty/layout.rs
Didn't know about this. I'll have to see if I can stay involved with some sort of project--the problem is that, currently, the one I was doing is...well...done.
I don't want to leave the Rust ecosystem, and I'd kill to keep working in it. But I didn't realize that there was any source of general funding from Mozilla specifically targeted at Rust. This whole thing was done simply because I'm bored and had a lot of free time and also we thought it would only take a few weeks. Money was far from the motivation initially, but certainly it occurred to me later on that it's amazing for the resume.
Yes, it will do exactly that.
Rust doesn't currently guarantee ABI compatibility. You can't load Rust from a shared library without going via repr(C) anyway. I imagine that the algorithm will be frozen whenever we get to this point, but it shouldn't need to change again unless someone tries to take us as far as what Swift does (which would potentially be a much bigger project than this). There's also been discussion of giving you tools to control it more explicitly, but thus far no one has proposed an RFC.
Libaudioverse separates the audio backend from the audio simulation. It is already possible to do this: you create what I call a read simulation, set up your objects and connect them, and then use getBlock on it. Allowing the computation of an arbitrary number of samples is not permitted because it introduces a number of performance headaches and code complexities; in addition, I've not yet seen anything related to audio output that randomly resizes the blocks on you. If there's enough people that need me to add a queue that automatically breaks the blocks, I will do so. Either way, you can already send it anywhere, and I could have it working on platforms without backends with a minor code change.
More interestingly, if you are connected to an audio device, you can use a GraphListener. GraphListeners call a callback on you every time a block gets processed. As a consequence, it's also more than possible to do stuff like live stream over the internet. I am debating the merit of a backend that advances the simulation without playing: I can see potential uses for it, I'm just not sure if they're good ones.
My problems with compilation of PortAudio were primarily related to ksgid.lib which is apparently now removed from Visual Studio. It's been a while since I did that one so i don't remember specifically what I had to do, but combined with the fact that (on my machine) all the backends but WinMM had to be turned off, it wasn't ultimately important either way. As I recall, it needed a code crawl to find the guilty pragma and some preprocessor definitions that killed it. Portaudio powered the audio for about 4 months before I finally got around to dropping it for the next option, primarily because of latency. Downgrading VS wasn't an option because I lean very heavily on C++11, especially smart pointers and closures.
10000 lines is twice the size of my whole library, but half my library codes itself from a Yaml description (there were good reasons for this; it's actually worked out really, really well). I don't honestly care if the build process is a little awful. I'll deal, if it works on my platform. Having to read an entire 10000 line source file to build up familiarity with the library before fixing it bothers me much more and, if it's still going to need a build step, stopping at "no external dependencies" ought to be enough.
I place great stock in the organization of my files as well as my code, and rarely let them go above 1000 lines each. Perhaps this is a weakness.