CAMLORN
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.
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.
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.
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.
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 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.
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/
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.
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.
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.
With movies I don't bother with them unless they have descriptive audio, at which point you've got music, sound effects, and two somewhat parallel speech streams going on. That's high informational content.
I did an entire CS degree at 800 words a minute. I program in any programming language you care to name (including the initial learning) at that speed as well. For more complicated concepts I stay at that speed, but pause after every paragraph or so to chunk the content as needed. I'm doing this thread at that speed. Pretty much the only time I slow it down is pleasure reading or sometimes articles when i want to go off and do chores while I listen, but even then it's still faster than human speech.
In general i think answering these sorts of questions needs research that we don't have to my knowledge. Nothing in my personal experience or background really allows me to give you good definitive answers. The sample size to work with is pretty small and in all honesty there's not a lot of good research around blindness day-to-day in the first place.
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
However most blind people I know who do this start hating audiobooks, start hating talks, and generally by far prefer the text option. audiobooks aren't annoying, but they're below my baud if you will. Net result: boredom/falling asleep to whatever it is and the need to actively make an effort to listen. Some things which require active listener participation--math lectures for example--are different. I guess the best way I can put it is that speed is inversely proportional to the amount of, I guess let's call it active listening, required.
I've given a lot of thought to this stuff, but we don't really have the right words for me to communicate it properly. A neuroscientist or linguist might, but I'm not either of those.
To me, the fact that this does in fact seem to be bidirectional at least some is more interesting than that I can listen fast.
1219 is a record as far as I know. We measured it explicitly by getting the screen reader to read a passage and dividing. I spent months working up from 800 to do it and lost the skill once I stopped (there was a marked level of decreased comprehension post 1000, but I was able to program there; still, in the end, not worth it). When I try to described the required mental state it comes out very much like I'm on drugs. Most of us who reach 800 or so stay there, though not always that fast for i.e. pleasure reading (I do novels at about 400). it's built up slowly over time, either more or less explicitly. I did it because I was in high school doing muds and got tired of not being able to keep up; it took about 6-8 months of committing to turn the synth faster once a week no matter what, keeping it there and dealing with a day or two of mild headaches. Note that for most blind people these days, total synthesis time per day is around 10+ hours; this stuff replaces the pencil, the novel, etc. Others just seem to naturally do it. You have little choice, it's effectively a 1 dimensional interface, so from time to time you find a reason to bump the knob. And that's enough.
Whether and how much the skill transfers to normal human speech, or even between synths, is person-specific. I can't do Youtube at much beyond 2x. Others can. It's definitely a learned skill.
0: https://ahicks.io/posts/April%202017/rust-struct-field-reord...
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: [email protected]
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.
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: [email protected]
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.
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.
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.
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.
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.
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.
nonetheless, the idea isn't original to us.
0: http://blog.ezyang.com/2011/06/debugging-compilers-with-opti...
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
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.