Readit News logoReadit News
eckzow commented on Ask HN: Who is hiring? (August 2021)    · Posted by u/whoishiring
eckzow · 4 years ago
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.

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/

eckzow commented on Which Parsing Approach?   tratt.net/laurie/blog/ent... · Posted by u/matt_d
iso8859-1 · 5 years ago
How do parser combinators like megaparsec fit into this?

https://hackage.haskell.org/package/megaparsec

eckzow · 5 years ago
The first footnote of the article says:

> 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.

eckzow commented on Announcing Rust 1.15   blog.rust-lang.org/2017/0... · Posted by u/steveklabnik
smaddox · 9 years ago
Is there a good solution for getting the code onto a chip? Last time I tried with the open source GCC stack, I eventually gave up and installed the painfully large (~1GB) IDE from TI.
eckzow · 9 years ago
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.

eckzow commented on The Resurgence of C Programming   oreilly.com/learning/the-... · Posted by u/ingve
CorvusCrypto · 9 years ago
fosho. Will look into those, but I guess my question is if it's worth practicing some development for embedded devices in rust to switch jobs or if most are still using C and I shouldn't waste the time.

EDIT: if anyone can answer this that would be so awesome :)!

eckzow · 9 years ago
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).

eckzow commented on Why C++ sucks (2016 edition)   dorinlazar.ro/why-c-sucks... · Posted by u/ingve
Ace17 · 10 years ago
"The split between source and headers, which makes project management quite slow. If you make all header libraries you’ll have a lot of copied code – the binaries will be larger. You’ll have to recompile that code every time you want to use it."

You can't say "the split between source and header sucks" just because it's painfull to use it wrong ("all header libraries") !

(All header libraries are justified when you're dealing with highly templated stuff, but in this case you have no way to avoid recompiling this code every time you use it, as each required template instance needs to be generated anyway - smart compilers will get rid of duplicated instanciations).

The split between source and headers is a key to good encapsulation. From a software design point of view, it's good way to break long dependency chains.

eckzow · 10 years ago
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.

Deleted Comment

eckzow commented on Learning C with gdb   recurse.com/blog/5-learni... · Posted by u/luu
nhebb · 11 years ago
One of the assignments I enjoyed the most was the "bomb lab". The bomb is a C program (w/ some Assembly required) that you have to defuse at certain phases in order for it to run to completion. It felt like a game more than an assignment, using and learning gdb along the way.

This isn't the oourse I took, but here's a good example of the lab: http://condor.depaul.edu/glancast/373class/docs/lab2.html

eckzow · 11 years ago
And if that kind of "game" is your thing, you may also enjoy https://microcorruption.com
eckzow commented on Google Nears $1 Billion Investment in SpaceX   wsj.com/articles/google-n... · Posted by u/Kopion
tw04 · 11 years ago
I would imagine he means trying to navigate the debris when sending other stuff into orbit, or bringing spacecraft home. I've often wondered this myself... at some point do we have so much stuff up there it's near-impossible to get spacecraft out without serious danger to their crews? And what about when it's time to retire them?

Legitimate question.

eckzow · 11 years ago
You may find this Wikipedia page enlightening: http://en.wikipedia.org/wiki/Kessler_syndrome
eckzow commented on Branch-free FizzBuzz in Assembly   pepijndevos.nl/2015/01/03... · Posted by u/luu
iamdanfox · 11 years ago
Apparently the Rust compiler produces a slightly different branch-free FizzBuzz[1] involving this delightful snippet:

    static OUT: &'static [u8] = b"\
    1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n11\nFizz\n13\n14\nFizzBuzz\n\
    16\n17\nFizz\n19\nBuzz\nFizz\n22\n23\nFizz\nBuzz\n26\nFizz\n28\n29\nFizzBuzz\n\
    31\n32\nFizz\n34\nBuzz\nFizz\n37\n38\nFizz\nBuzz\n41\nFizz\n43\n44\nFizzBuzz\n\
    46\n47\nFizz\n49\nBuzz\nFizz\n52\n53\nFizz\nBuzz\n56\nFizz\n58\n59\nFizzBuzz\n\
    61\n62\nFizz\n64\nBuzz\nFizz\n67\n68\nFizz\nBuzz\n71\nFizz\n73\n74\nFizzBuzz\n\
    76\n77\nFizz\n79\nBuzz\nFizz\n82\n83\nFizz\nBuzz\n86\nFizz\n88\n89\nFizzBuzz\n\
    91\n92\nFizz\n94\nBuzz\nFizz\n97\n98\nFizz\nBuzz\n";

    ...
1: http://chrismorgan.info/blog/rust-fizzbuzz.html

eckzow · 11 years ago
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.

On my machine, building with:

  $ clang++ -std=c++14 fizzbuzz.cpp -O2 -S
Gives code similar to:

  main:                                   # @main
          .cfi_startproc
  # BB#0:
          pushq   %rax
  .Ltmp0:
          .cfi_def_cfa_offset 16
          movl    $1, %edi
          movl    $_ZL6output, %esi
          movl    $413, %edx              # imm = 0x19D
          callq   write
          xorl    %eax, %eax
          popq    %rdx
          retq
  .Ltmp1:
          .size   main, .Ltmp1-main
          .cfi_endproc
  
          .type   _ZL6output,@object      # @_ZL6output
          .section        .rodata,"a",@progbits
  _ZL6output:
          .ascii  "1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n11\nFizz\n13\n14\nFizzBuzz\n16\n17\nFizz\n19\nBuzz\nFizz\n22\n23\nFizz\nBuzz\n26\nFizz\n28\n29\nFizzBuzz\n31\n32\nFizz\n34\nBuzz\nFizz\n37\n38\nFizz\nBuzz\n41\nFizz\n43\n44\nFizzBuzz\n46\n47\nFizz\n49\nBuzz\nFizz\n52\n53\nFizz\nBuzz\n56\nFizz\n58\n59\nFizzBuzz\n61\n62\nFizz\n64\nBuzz\nFizz\n67\n68\nFizz\nBuzz\n71\nFizz\n73\n74\nFizzBuzz\n76\n77\nFizz\n79\nBuzz\nFizz\n82\n83\nFizz\nBuzz\n86\nFizz\n88\n89\nFizzBuzz\n91\n92\nFizz\n94\nBuzz\nFizz\n97\n98\nFizz\nBuzz\n"
Of course, having now written this I feel like I should retroactively fail my last interview.

[1] https://gist.github.com/anonymous/7818f902a374a953b274

eckzow commented on Branch-free FizzBuzz in Assembly   pepijndevos.nl/2015/01/03... · Posted by u/luu
Terretta · 11 years ago
Random fizzy buzzy observation:

Always a little baffled when I see three cases (fizz, buzz, and fizzbuzz) rather than both fizz and buzz handled well such that modulo 15 gets a fizz and a buzz.

The normal fizz buzz is divisible by 3 gives a fizz, divisible by 5 gives a buzz. It so happens that 15 is both, so should exhibit both. But as I see it, handling the 15 right should be emergent behavior of a correctly written fizz and correctly written buzz, not a separate test case.

But what if the business requirement changes that divisible by 4 gives a fizz and divisible by 5 gives a buzz? Now the "3 cases" programmer doesn't just change 3 to 4, and correctly see fizzbuzz emerge on divisible by 20, he's still got a spurious fizzbuzz on the divisible by 15 case. He's got to remember this case, do some manual computation, and change his 15 to 20. Structuring the code in such a way the programmer has to track all ancillary implications of one business rule change seems a recipe for disaster.

So I consider as broken all code that explicitly prints "fizzbuzz" with a third conditional.

eckzow · 11 years ago
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}.

u/eckzow

KarmaCake day74November 6, 2012View Original