Zipline | South San Francisco, US | Remote ok (with travel) | Full Time | Embedded Systems | Robot Perception
Zipline uses drones to deliver critical and lifesaving medicine to thousands of hospitals serving millions of people in multiple countries. Our mission is to provide every human on Earth with instant access to vital medical supplies. Join Zipline and help us make this a reality for billions of people.
We're hiring an embedded systems specialist to help us build perception systems for our aircraft. You'll build high-performance, real-time, safety-critical embedded software systems from kernel drivers to neural networks. We write Rust and C++ on embedded Linux, and we work with hardware from i2c to GPUs. We train networks and analyze data with industry-standard Python tools.
> While that could mean just about anything, nearly everyone who writes a half-decent hand-written parser, whether they know it or not, is writing a recursive descent parser [1].
> [1] Parsing Expression Grammars (PEG)s and “parser combinators” in some functional languages are just recursive descent parsers in disguise.
Which, while I haven't thought about it deeply, intuitively makes some sense: parser combinators encourage an approach mostly equivalent to little functions that do something like "parse a $thing, or parse a $different_thing" (etc.) which very much translates down like a recursive descent parser.
I don't know if I would call it "good" but if you're willing to settle for "official" there is http://www.ti.com/tool/MSP430-FLASHER which will work with TI's own MSP-FET on all three major OSs.
Accepts a .hex so you can use whatever toolchain you want.
I'll second my sibling comment in saying that C (and C++!) will be around for a long time, and is epically easier to get hired with if you're trying to break into the industry. The C ecosystem just has too many advantages at this point (i.e. not just existing code but also number of supported platforms, etc.).
Also, a significant fraction of embedded code is going to be "unsafe" Rust by definition: drivers performing volatile load/stores on memory mapped hardware. In those scenarios, defect mitigation techniques are a matter of system architecture (MPUs, pre-empting deadline-based task schedulers) rather than being language-specific. Arguably even Rust provides you with no protection against the most devious bugs (memory barrier usage, cache-DMA interactions).
The machine is ultimately unsafe. Rust's strength is to be able to encapsulate that unsafety to be a small part of your code, and have most of your code be safe. This is even true in an embedded or osdev context, though the percentage is higher than in an application context.
I agree with your sentiment, but I think the situation is a bit more nuanced.
The usual argument is that headers don't actually provide good encapsulation: implementation details internal to the class (i.e. private members) end up getting leaked into the public header. There are workarounds (pimpl, opaque "handle" types, etc.) but they all have their own disadvantages (mostly an extra layer of indirection).
Complicating the matter is the issue of static polymorphism--CRTP and its friends cause the template-ization forcing lots of code into headers. Smarter compilers help a bit (with de-virtualization and constexpr), but if you want to guarantee that something is resolved at compile time, turning it into a template is the only real option.
Lastly there's the inlining specter; the separate compilation model means that without link-time optimization (which has admittedly made great strides in the last few years), code must be moved into headers to be eligible for inlining. Premature optimization and all that, but this is a death-by-a-thousand-cuts situation where the language gets in the way of doing the performant thing (and you're probably only using C++ if you care about performance in one aspect or another).
None of these things is an insurmountable problem, to be sure, but they represent little inefficiencies (either for the programmer or the program) which are not generally present in more modern language implementations. I am thinking primarily of Rust, for which the static polymorphism and link time optimization stories are strong--although perhaps that is in direct reaction to some of these C++ shortcomings, and we'll discover Rust has warts of its own after a few decades of wear and tear.
Call me old-fashioned, but I actually think the separate compilation model is a good thing: it makes it possible to delegate the build process to a mostly language agnostic tool, and to mix languages easily (C, C++, D) in the same project.
About the implementation details internal to the class: the 'private' keyword is the problem, not the header files.
If you want polymorphism, why not just use an abstract base class - as you would have had a layer of indirection anyway.
If you don't want polymorphism, just use "handle" types. Am I missing something?
By my reading that implementation was assembled by humans, not the optimizer.
Although, there's certainly nothing magical that prevents the optimizer from generating such code. Here's something[1] I just threw together that (ab)uses constexpr to do just that.
This code snippet really made my night. I never thought of using constexpr to write a FizzBuzz that compiles to one of the most "optimal" solutions that I have ever seen. Awesome!
A good interview exercise (not necessarily vouching for fizzbuzz here) allows depth of discussion past the initial answer. It is in this discussion stage where I spend the majority of my time with a good candidate.
In such a discussion we might talk about whether it makes sense to make the /15 case "fall out" naturally. Using your example, there's an implicit assumption that the requirements would change to {4: fizz, 5: buzz, 20: fizzbuzz}, but in real life I've found things have the annoying tendency to change to, e.g. {4: fizz, 5: buzz, 15: fizzbuzz}.
Zipline uses drones to deliver critical and lifesaving medicine to thousands of hospitals serving millions of people in multiple countries. Our mission is to provide every human on Earth with instant access to vital medical supplies. Join Zipline and help us make this a reality for billions of people.
We're hiring an embedded systems specialist to help us build perception systems for our aircraft. You'll build high-performance, real-time, safety-critical embedded software systems from kernel drivers to neural networks. We write Rust and C++ on embedded Linux, and we work with hardware from i2c to GPUs. We train networks and analyze data with industry-standard Python tools.
More information and apply @ https://flyzipline.com/careers/job/4633974003/?gh_jid=463397...
We're hiring for many other positions, too! https://flyzipline.com/careers/