HNHacker News
TopNewBestAskShowJobs

dandotway

1,046 karma · joined August 15, 2021

submissionscomments
dandotway··on Emergence of Life in an Inflationary Universe (2020)
> The most philosophically and mathematically consistent interpretation of Quantum Mechanics is that there are "many worlds".

Why is "many worlds" the most mathematically consistent? (I won't bother asking for the philosophical bit; I'm sure it's too long for an HN post.)

dandotway··on Emergence of Life in an Inflationary Universe (2020)
Atheists: "We have faith natural selection at a cosmic level makes life way more likely."

Christians: "We have faith supernatural selection at a cosmic level makes afterlife way more likely."

dandotway··on Faster CPython (2021) [pdf]
Question for JIT experts: JS and Python are extremely hard to optimize because they both allow redefining anything at any time, yet V8 crushes Python by an order of magnitude in many benchmarks[1]:

         All times in seconds (lower is better)
  
  benchmark          Node.js     Python 3    Py takes x times longer
  ==================================================================
  regex-redux          5.06         1.34     ** Py3 is faster (PCRE C)
  pidigits             1.14         1.16     0.02
  reverse-complement   2.59         6.62     2.56
  k-nucleotide        15.84        46.31     2.92
  binary-trees         7.13        44.70     6.27
  fasta                1.91        36.90     19.3
  fannkuch-redux      11.31       341.45     30.19 (wut?)
  mandelbrot           4.04       177.35     43.9  (srsly?)
  n-body               8.42       541.34     64.3  (no numpy fortran cheat?)
  spectral-norm        1.67       112.97     67.65 (Python for Science[TM])

(If Python is allowed to call fast C code (PCRE) for regex-redux, I don't see why Python shouldn't be allowed to call fast Fortran BLAS/etc for n-body, but rules are rules, I guess. V8 doesn't cheat at spectral-norm, it's 100% legit JS.)

Both ecosystems have billions invested by corporations worth trillions; bottomless money exists to make Python faster. So why isn't Python faster?

V8's tactics include dynamically watching which loops/calls get run more than (say) 10,000 times and then speculatively generating[2] native machine instructions on the assumption the types don't change ("yep, foo(a,b) is only called with a and b both float64, generate greased x86-64 fastpath"), but gracefully falling back if the types later do change ("our greased x86-64 'foo(float64,float64)' routine will be passed a string! Fall back to slowpath! Fall back!"). Why doesn't Python do this? Is it because Google recruited the only genius unobtainium experts who could write such a thing? Google is a massive Python user, too.

[1] https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

[2] https://ponyfoo.com/articles/an-introduction-to-speculative-...

EDIT: HN commenter Jasper_ perhaps has the answer in another post[3]: "The current CPython maintainers believe that a JIT would be far too much complexity to maintain, and would drive away new contributors. I don't agree with their analysis; I would argue the bigger thing driving new contributors away is them actively doing so. People show up all the time with basic patches for things other language runtimes have been doing for 20+ years and get roasted alive for daring to suggest something as arcane as method dispatch caches. The horror!"

[3] https://news.ycombinator.com/item?id=30047289#30050248

dandotway··on Keeping POWER relevant in the open source world
Big Endian POWER isn't bug-for-bug compatible with buggy Javascript usage of typed arrays that assumes little endianness, and thus browsers/nodejs/deno on POWER will be exposed to bugs that don't affect little endian x86-64/ARM.

After so many years of endianness bugs in C/C++ code, it's perplexing that the web standards committee voted to put typed arrays in Javascript in such a way that exposes platform byte order to Javascript programmers who can't generally be expected to have low-level C/C++/ASM experience with memory layout issues:

  function endianness () {
    let u32arr = new Uint32Array([0x11223344]);
    let u8arr = new Uint8Array(u32arr.buffer);
    if (u8arr[0] === 0x44)
        return 'Little Endian';
    else if (u8arr[0] === 0x11)
        return 'Big Endian';
    else
        return 'WTF (What a Terrible Failure)';
  }
EDIT: my old Power Mac was big endian, but I just read POWER has an endianness toggle. So in little endian mode it ought run endian-buggy JS with bug-for-bug compatibility.
dandotway··on SICP: JavaScript Edition available for pre-order
> [15] Richard Waters (1979) developed a program that automatically analyzes traditional Fortran programs

Anyone have a PDF link to a paper about this Fortran analyzer?

dandotway··on The horizon problem for faster than light travel
While faster-than-light (FTL) travel is impossible through spacetime as PhD physicists know it (i.e. as "Relativity-confirming experiments reveal it"), there are forms of apparent FTL that have mainstream PhD acceptance, because they don't allow information to travel from point A to point B faster than light and thus do not violate causality.

The expansion of the observable universe itself being apparently FTL is perhaps the most interesting. If we point the Hubble telescope (and soon JWST) towards opposite ends of the observable universe, we observe extreme redshift galaxies receding away from each other in opposite directions greater than twice lightspeed if we measure according to "distance in light years" from earth. But no photons or information from a galaxy at one side of our observable universe can be sent to a galaxy at the opposite end: they are receding away from each other too rapidly, these two galaxies exist Beyond the Cosmological Event Horizon relative to each other and are forever unknowable to each other, and thus causality is not violated.

An advanced alien race in galaxy A might be able to beam a message to earth before galaxy A vanishes Beyond the Cosmological Event Horizon within the next 100 million years earth-time, and likewise galaxy B might beam a message to earth within the next 100 million years earth-time, but earth can't relay the message from A to B or B to A because they have already forever receded from each other and will soon both likewise forever recede away from us.

dandotway··on Patents are out of control, and they’re hurting innovation (2017)
Individuals and small business owners don't have time to learn patent law, nor do they have money to have dedicated legal departments like rich corporations. If I was sued I would not listen to some anonymous stranger on HN. I would get a lawyer. And I would be charged $300-$800/hr by said lawyer. In the patent ecosystem the patent-holding apex whales and lawyer-sharks hunt smaller creatures to eat, and devour whole.
dandotway··on Patents are out of control, and they’re hurting innovation (2017)

  - never talk to cops

  - never read a patent

  - never read proprietary source code
I need a nice printable version of this to post on my wall.
dandotway··on Patents are out of control, and they’re hurting innovation (2017)
Clearly you've never been sued by a patent troll.

The patent system only benefits (1.) rich corporations that can afford the millions of dollars in lawyer fees to litigate patent claims, (2.) the lawyers that receive said fees.

dandotway··on Why static languages suffer from complexity
+NaN For comments that make me laugh out loud for duration T>2.0 seconds, I wish HN provided a way to transmute/sacrifice one's past karma points into additional +1 mod points.
dandotway··on Why static languages suffer from complexity
So whenever I have to study someone else's 'dynamic' python I encounter this sort of thing:

  def foo(bar, baz):
      bar(baz)
      ...
What the heck is 'bar' and 'baz'? I deduce no more than 'bar' can be called with a single 'baz'. I can't use my editor/IDE to "go to definition" of bar/baz to figure out what is going on because everything is dynamically determined at runtime, and even

  grep -ri '\(foo\|bar\|baz\)' --include \*.py
Won't tell me much about foo/bar/baz, it will only start a hound dog on a long and windy scent trail.
dandotway··on How do you handle a plutonium-powered pacemaker?
https://archive.ph/uEt1V
dandotway··on A simple defer feature for C
> I like the idea of a small, performant language

So the earliest C compilers were under 5000 lines of C+asm:

  https://github.com/mortdeus/legacy-cc
If you want a minimal "standard committee approved" C89 compiler then David Hanson's lcc and Fabrice Bellard's tcc both come out to over 30,000 lines. To understand C89 fully you at a minimum have to read a ~220 page (14,248 line) copy of the (draft) ANSI standard:

  http://port70.net/~nsz/c/c89/c89-draft.txt
I don't know what the smallest C23 compiler would be with all the new features since C89 added, but it's at the point where a single human can't implement a C compiler anymore. It's becoming a language only rich corporations have the wealth and power to implement and steer.
dandotway··on A simple defer feature for C
"Another programming language" cannot even meaningfully exist if all programming languages are forced to have the same feature set. Should Python get C-like low-level pointer manipulation so that Python users don't need to "pull in another programming language" of C to do pointer manipulation?

C doesn't need "defer" because C programmers have managed since the 1970s to implement operating systems, compilers, interpreters, editors, etc., just fine without it. Those who want a bigger C can use C++, this pond is big enough for two fish.

dandotway··on A simple defer feature for C
Features that seem like a good idea at the time often don't stand the test of time 20-30 years in the future. In the mid-90s Object-Oriented Programming was super-hyped so a bunch of other languages bolted on OO, such as Fortran and Ada. But now we have Go/Rust/Zig rejecting brittle OO taxonomies because you always end up having a DuckBilledPlatypus that "is a" Mammal and "is a" EggLayer.

A great strength of C is that if you want more features you just go to a subset of C++, no need to add them to C. C++ is the big, ambitious, kitchen-sink language. When C++ exists we don't need to bloat C.

Fortran was originally carefully designed so that people who aren't compiler experts can generate very fast (and easily parallelized) code working with arrays the intuitive and obvious way. But later Fortran added OO and pointers making it much harder to auto-parallelize and avoid aliasing slowdown. Now that GPUs are rising it turns out that the original Fortran model of everything-is-array-or-scalar works really well for automatically offloading to the GPU. GPUs don't like method-lookup tables, nor do they like lambdas which are equivalent to stateful Objects with a single Apply method.

Scientists are moving to CUDA now, which on the GPU side deletes all these features that Fortran was bloated with. Now nVidia offers proprietary CUDA Fortran which is much more in the spirit of original Fortran, deleting OO and pointers for code that runs on GPU. If the ISO standards committee didn't ruin ISO Fortran for scientific computing by bloating it with trendy features we could all be running ISO Fortran automatically on CPUs and GPUs with identical code (or just a few pragmas) and not be locked in to proprietary nVidia CUDA.

But GPUs are now mainly used for crypto greed instead of science for finding cancer cures or making more aerodynamic aircraft so maybe it all doesn't matter anyway.

dandotway··on Nothing like this will be built again (2002)
> The two reactors at Torness have a combined electricity output of 1200 MW

If they bumped 1200 MW to 1210 MW they'd have the 1.21 GW they need to operate a Flux Capacitor.

https://www.youtube.com/watch?v=f-77xulkB_U

dandotway··on How to make $13M on the App Store
As long as Apple gets its 30% cut, why is Apple incentivized to hire a bunch more staff with healthcare, vacation, and pension benefits who are paid to crack down on this? "Dear AAPL Shareholders, rejoice! We reduced our 30% cut of $10B per quarter from garbage in the App Store by spending over $1B per quarter to hire over 10,000 staff to eliminate these ill-gotten gains."
dandotway··on Practical Common Lisp (2005)
If you have a second, I'm curious to learn more about your head scratching experiences with JVM. I want to make a program that I can trust will still run the exact same (bug-for-bug compatible) many years in the future without maintenance. One approach is to make it completely bug-free using a formal verifier for a strict formalization of C, but this is extraordinary effort and there is no guarantee that bugs in the stack of garbage my app sits atop and the libraries I call (SDL2?) will cause unwanted user observable behavior. Truly bug-free is actually stricter than what I really need; I just need exact bug-for-bug compatibility so that my bugs always are deterministic. It seems with the JVM at least, the bug-for-bug determinism is really good (except when it obviously isn't and can't be, like thread scheduling, network communications, ...). For client GC there is a low-latency guarantee and people seem happy. Have you found the Java GC is not all it's reputed to be? There are so many huge companies with billions invested in Java and its bug-for-bug compatibility, I think it could easily still be around in a 100 years along with COBOL and is a safe investment for individuals who value longevity above what is trendiest and shiniest.
dandotway··on Practical Common Lisp (2005)
Having learned a number of Lisp systems in the past, I wouldn't necessarily recommend ANSI Common Lisp as a first choice for a Lisp unless your needs are very particular, because it is an enormous design-by-committee language having a draft standard of about 1360 pages:

  https://lisp.com.br/archive/ansi_cl_standard_draft_nice.pdf
This means that in addition to the time spent doing the programming that solves your technical problem, you also have to devote considerable time to language lawyering, investigating if the interpretation of a Lisp expression your Common Lisp produces is or is not standard conforming, using only the frequently ambiguous English of that enormous standard as your guide.

The Java JVM was carefully designed to give identical results on all hosts for the Java platform unless you go out of your way to get nondeterminism or platform specific behavior (make the value of the number N depend on thread scheduling, or use JNI that assumes a platform byte order, etc.). C/C++/Rust allow undefined behavior if you shift a 64-bit int more than 64 bits, but Java on the JVM for example masks the lower 6 bits of a 64-bit shift ('& 0x3f') so that you get the same result on all CPUs rather than a CPU-dependent result:

  https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19
The nice thing about this is that the JVM makes a "try it and see" approach more viable: if your program has a bug at least it has the same bug everywhere. You won't suddenly get a crash 10 years in the future when your customers upgrade to a new CPU, because your Java bytecodes on their new CPU will faithfully maintain bug-for-bug compatibility.

Clojure is a Lisp that runs on the JVM. I haven't personally used Clojure, but having done quite a bit of Common Lisp, Emacs Lisp, Scheme, etc., it looks to be very well designed and very well loved by its users, and using it could spare you from having to language lawyer the ANSI Common Lisp standard, as it seems to be more "try it and see" friendly.

I've been learning a lot about formal verification for C programs, how to truly make code that is bug free, and to do this you need to first make certain decisions about how you are going to formalize the language standard. E.g. will you assume that CHAR_BIT==8 or will you allow CHAR_BIT>=8 because the official ANSI/ISO C standard allows this even though all modern computers have CHAR_BIT==8? Then for any program you input to your verifier you must judge whether all its behavior is well-defined or if there is undefined behavior (arithmetic overflow, etc.).

There are quite good formal verification tools for Java, also, like JBMC and Krakatoa, and smaller Lisp languages are traditionally among the least tedious to formally verify (very simple semantics, unlike Common Lisp), but the time investment to learn these tools is enormous.

dandotway··on Vim prank: alias vim='vim -y'
> I said that multiple cursors are a gimmick which is less efficient

My Dear Dude, you are surely aware that computer editors are Religion among programmers, that vi vs. emacs, tabs vs. spaces, etc., have been fiercely debated for decades and will continue to be fiercely debated for decades to come. Thus, like all matters of politics and religion, if you are going to insult the Editor Religion of your fellow programmer and call it a gimmick, you might do well to at least accept the challenge when foul is cried and the gauntlet is thrown down demanding a scorable, quantifiable, objective, numerical measure of your performance claim that settles the question as fact rather than opinion.

But you would do better still to refrain from insults like 'gimmick', especially when the programmer whose favored multi-cursor feature you are insulting has demonstrated a deep interest in the history of computer editors, naming out ed/vi/vim/emacs/Sam/Acme/VSCodium, etc., and fully understands how to do ':%s/foo/bar/gc' in vim and the more powerful things documented by ':h :s' within vim and the even more powerful things yet in Acme involving the 'x' and 'X' commands but despite all this has found that multi-cursor can usually finish the edit before even half of that ':s///' command can be typed or a suitable regular expression mentally devised that gobbles the correct substrings on the correct lines without accidentally gobbling incorrect substrings on incorrect lines or incorrect substrings on correct lines or correct substrings on incorrect lines.

dandotway··on Fortran is easy to learn
In my undergrad computer science program, I implemented the rudiments of a very simple CPU using AND, OR, and NOT logic gates. I learned how to program microprocessors in assembly language. I learned how to implement a programming language interpreter. I implemented a compiler with a lex that tokenized its input stream and had a parser that built an AST from said tokens, and had a code generator that walked the AST and output a sequence of instructions. This was all covered in an undergrad CS program, not a Masters or PhD, so you don't have to be a genius at the level of John von Neumann to design programmable computational machinery from scratch using only the resources in your brain, because the geniuses like von Neumann already invented it in their brains instead, and good teachers at universities have found gentle ways to pass it from their brains into your brain.

The original FORTRAN '57 did not even have SUBROUTINE, FUNCTION, CALL, etc., for implementing subroutines. Those came with FORTRAN II in 1958, which was the main language Kemeny's original BASIC was based on in the early 1960s, but Kemeny changed FORTRAN II's DO loop to the easier to remember 'FOR I = 1 TO 42 ...'.

Knuth designed his original 1960s MIX computer using just pencil and paper, designed it to be easy to run programs using just pencil and paper.

If you yourself could not build a rudimentary BASIC or cut-down FORTRAN using only the resources in your brain and a sheet of paper with a pencil, you might be spending too much time working with overcomplicated programming tools that do not bring joy to your life.

dandotway··on Vim prank: alias vim='vim -y'
> In reality, you would think about and act upon each in turn

Here's a real example from real coding I was doing, then:

  color.r = 42;
  color.g = 42;
  color.b = 42;
I want to bump the 'r' and 'b' from 42 up to 255 but leave 'g' alone. So I,

  1. Alt-click after the two 42's I want to change
  2. Ctrl-Backspace, type '255'
  3. Done
With a vim I could

  1. Use '/42<RET>' or '?42<RET>' to search towards a 42 I want to change
  2. Use 'n' or 'N' command to skip the 42 I don't want to change (possibly)
  3. Use 'cw' followed by '255<ESC>' to change the first 42
  4. Use 'n' or 'N' to get to the next 42, skipping the 42 I don't want to change
  5. Use '.' to repeat the 'cw255<ESC>'
Alternatively with vim

  1. Use ':%s/= 42/= 255/gc' to query replace the right occurrences
  2. Answer 'y' or 'n' for each occurrence
  3. Still requires more keystrokes, time, and thought than VSCodium
It's funny all these posts presuming that multi-cursor is a gimmick only used by idiots who don't know how to use regular expression query replace and the vim '.' command. Yeah, I know how to use those, and multi-cursor is often faster. And VSCodium has a powerful multi-file query-replace that is faster to learn than the equivalent vim/emacs/grep/sed.
dandotway··on Fortran is easy to learn
Ancient FORTRAN, as opposed to complicated modern Fortran/C++/Rust, has a huge advantage if you ever crash your spaceship on a resource rich alien world and have to build a programmable computer from scratch from first principles using only knowledge that a single human could memorize. Modern languages require nontrivial compiler theory to parse a sequence of language symbols into an Abstract Syntax Tree (AST), etc. But Ancient FORTRAN is essentially designed to be read in and translated just a few 80 column punch card lines at a time, much like assembly languages. Compilers were written that could fit inside computers with only a few thousand words of 16 or 18 bit memory. Magnetic Core memory from that era was often made by hand, by little old ladies weaving it in factories I've been told, and was used for the Apollo moon spacecraft and was extremely reliable:

  https://en.wikipedia.org/wiki/Magnetic-core_memory
Ancient LISP and BASIC variants also stand out in this regard of not requiring you to undergo years of training and theory to implement and fully understand.

Fabrice Bellard's minimalist but complete quickjs.c Javascript interpreter is presently about 54,000 lines of C:

  https://github.com/bellard/quickjs/blob/master/quickjs.c
Javascript is an enormous, complicated, designed-by-committee language, as are essentially all other languages we are forced to use. I do hope there is a renaissance of simpler technology, technology not driven by competitive egos but by a desire for the joy of simplicity and understanding. But such simpler technology won't be useful for building backend infra for Big AdTech ad-bidding exchanges so that we can be bombarded with ads for One Weird Trick to burn belly fat or whatever.
dandotway··on Vim prank: alias vim='vim -y'
> Please do look into vim's regular expressions

So here's an editing task. Given the following in your editing buffer,

  signed char foo;
  /* ... 10 more lines ... */
  unsigned short bar;
  /* ... 10 more lines ... */
  const char *const s = "Dennis Ritchie little-loved 'const'.";
  
What is the fastest sequence of vim commands to

  1. delete 'signed' from signed char foo
  2. delete 'short' from unsigned short bar
  3. delete the two occurrences of 'const' from 'const char * const s'
With VSCodium

  1. Alt-click just past the end of each of the 4 strings to be deleted.
  2. Ctrl-Backspace.
  3. Done.
This involves

1. Three keyboard keys total (Ctrl, Alt, Backspace), each pressed and released once.

2. Four mouse clicks total, plus four target aiming tasks for these clicks.

This sequence requires zero thought or planning prior to execution.

I want to see the keyboard keystroke count for your best vim sequence, which will require a pause to plan out prior to execution, whatever you come up with.

> This might be because I don't work from a desktop and use a trackpoint, or maybe because when I do use a desktop I use a trackball.

Multiple peer-reviewed human-computer interaction studies have shown that for a broad range of pointing and editing tasks the mouse is faster than touchpads, trackpoint nipples, trackballs, and pens. (I do use a pen occasionally and if not for the pressure/tilt sensitivity it would be mostly pointless.) There's no need to dig into the literature because you can just try it yourself: next time you have both a mouse and your trackpoint/trackball handy try benchmarking your performance at,

  https://humanbenchmark.com/tests/aim
There is no way you are hitting the curve peak around 400ms with a trackpoint/trackball/touchpad. There is a reason essentially all pro gamers who compete for millions in sponsorship bucks use mice instead of touchpads/trackpoints/trackballs: mice are faster. (There might be like 1 out of 1000 pros who use a trackball for Starcraft-like games, but none of them are top-ranked.)

Also try

  https://aimtrainer.io/
I agree VSCodium is not as cool as Acme, but it is nevertheless very efficient or I wouldn't use it over Vim, Emacs, or Acme.

If you do not personally like mice or mouse driven multiple-cursors that's cool, enjoying the journey is often more important than getting to the destination as fast as possible.

But I do claim that if and when text editing competitions for prize money are held, those who use mouse-driven multiple selection will be at a decisive competitive advantage over those who don't. This is just a claim which I cannot prove until such competitions are held. And, again, if a mouse makes you less happy than something slower, then the tortoise beats the hare, so to speak.

dandotway··on Vim prank: alias vim='vim -y'
The Acme editor, used by C creator Dennis Ritchie, converted me to the Rodent Religion. The mouse is the fastest way to point to something on your computer screen, especially a quality gaming mouse with mouse acceleration disabled. Pointing at things on a computer screen and clicking is a highly competitive activity involving billions of dollars annually; pro gaming mouse designs have evolved to be lightweight and extremely efficient at this task.

Pianists can rapidly move their hands to 100% accurately strike keys more than a foot away at blink-of-the-eye speed because they practice, and master mouse users can flick their hand from keyboard to mouse to keyboard again at blink-of-the-eye speed if they practice. Anchoring at the keyboard is not the fastest way to edit text.

There needs to be a text editing competition organized with prize money. Then shall all the world see that mouse users best the Rodentless in battle.

If I need to double-backspace five different caret positions visible on screen, I can Ctrl-click (or Alt-click) to set multiple cursors faster than a master vimmer's brain can devise a suitable ':[x,y]s/.../.../g' command to accomplish the same thing. I know this because I've used vim more than 20 years, and I also learned ed's and sam's editing languages used by the original Unix gods. The Unix gods switched to the Sam editor in the early 1980s which is a bit like a mouse-oriented re-imagining of vi. Then some switched to Plan 9's Acme in the 1990s, which retains Sam's editing language. The Sam/Acme editing language is not line-oriented like ed/vi/vim, e.g. ':#3,#42' selects character 3 through 42 regardless of how many newlines are between char 3 and 42 and does not select to the beginning of the line before char 3 nor to the end of the line after char 42. You can also do ':/re1/,/re2/' and unlike vim this won't grab to the beginning of line before /re1/, etc. Acme doesn't have multiple cursors though and needs some TLC, it doesn't talk to an X server efficiently and draw pixels efficiently because it's based on Plan 9's drawterm. VSCodium does everything I need but is ultra-bloated and I'd love lighter weight.

dandotway··on Vim prank: alias vim='vim -y'
I tried to make vim work like VSCodium (VSCode on telemetry diet), but found it too hard and gave up.

1. How well do you handle the mouse in xterm? Vim actually has fantastic mouse support in xterm (:set mouse=a), e.g. you can use focus-follows-mouse scrollwheel to scroll individual split content panes, drag click to resize the split dividers, etc. (Although, last time I tried under WSL with the old-school win-console, vim's focus-follow-mouse scrollwheel scrolling didn't work there whereas emacs did work (with xterm-mouse-mode)).

2. Can you handle multiple cursors gracefully (vim-visual-multi) with the mouse like VSCodium? Emacs doesn't have a non-buggy multi-cursor mode and I gave up on achieving this with Emacs. I just use VSCodium now, which means allocating over 300MB of system RAM and gigabytes of dedicated graphics VRAM for its 'HW accelerated' rendering that decelerates all other HW graphics rendering on my machine.

dandotway··on Why the C Language Will Never Stop You from Making Mistakes
For my use cases thus far, the usual C portability pitfalls haven't applied: whether char is signed or unsigned, the range of 'int', little vs. big endian, etc.
dandotway··on Why the C Language Will Never Stop You from Making Mistakes
I've used SPARK with GNAT Studio, I've used Frama-C, and I'm also experimenting with CBMC. Frama-C is way more powerful than SPARK, but also consequently has a much deeper learning curve.

SPARK does not allow doubly linked lists:

https://blog.adacore.com/pointer-based-data-structures-in-sp...

  For example, singly-linked lists and trees are supported whereas
  doubly-linked lists are not.
With Frama-C you can prove doubly linked lists and all manner of complicated pointer manipulating graph algorithms. It does not impose a Rust-like pointer ownership policy as does SPARK.

However, for embedded development, SPARK's restrictions are a good trade-off, as the more restrictive rules allow more proofs to be fully automated than with Frama-C and simplify diagnostic messages. A fly-by-wire avionics computer doesn't need to dynamically allocate a billion graph nodes. But SPARK is not "general purpose" like C with Frama-C is.

AdaCore's SPARK tool stack is not actually written in SPARK as far as I can see, much of it is actually OCaml and Coq/Gallina for the Why3 component also used by Frama-C. See all the .ml OCaml and .v Gallina source code for yourself:

https://github.com/AdaCore/why3

And of course the compiler backend for Ada/SPARK is GNU GCC, written in unverified C:

https://github.com/gcc-mirror/gcc/tree/master/gcc/config

Compare with CompCert, the formally verified C compiler:

https://github.com/AbsInt/CompCert

Frama-C unfortunately requires a user to be mathematician-logician logic programming expert to fully utilize. One can begin training in Coq/Gallina with the large free online Software Foundations course:

https://softwarefoundations.cis.upenn.edu/

dandotway··on Why the C Language Will Never Stop You from Making Mistakes
Yes, a compiler written in C could be verified with Frama-C, but "verifying in Frama-C" for something that hard (i.e. has many proof steps that cannot be automated) really means verifying in a proof assistant that can interact with Frama-C that understands ACSL, and Coq is usually used. And indeed, the loop invariants you mention usually cannot be automatically proved and must be proved manually, which is why there is such a learning curve to Frama-C. I first started using Frama-C without having used Coq/Gallina/OCaml, and I began to learn them simply because I hit a roadblock with Frama-C where I couldn't really progress without a deeper understanding for why automatic proving fails when it fails, why the error messages when automatic proving fails often aren't terribly helpful, what the current limits of automatic proving are, how the automatic proving actually works under the hood, etc.

Coq has been used to formally verify a large body of classical mathematics. Coq can 'understand' what a prime number is and can be used to prove that there are infinitely many primes, can prove that sqrt(2) is irrational, etc. Coq can prove a recursive solver for the Towers of Hanoi actually solves the problem, etc. And thus Coq can prove a C program to solve the Towers of Hanoi correctly solves the problem, because Coq can reason about C programs.

I've been slowly working through the Software Foundations series on using Coq/Gallina:

https://softwarefoundations.cis.upenn.edu/

Another poster mentioned CBMC which I just started playing with. It is much less powerful than Frama-C, there isn't the ACSL specification capability and theorem proving, but it is much more automatic and much faster to get started with. For many cases if I just want to verify that a certain C file frees all its mallocs, doesn't have out-of-bounds accesses, and that all obviously bounded loops terminate, CBMC is much easier. Also, like Frama-C, it converts C functions into "goto programs" (removes the syntactic sugar of 'for' and 'while' loops to obtain a more pure Control-Flow-Graph (CFG)) for certain forms of analysis, and when I first encountered this in Frama-C there was no explanation why, whereas the manual for CBMC actually has an excellent gentle introduction:

http://cprover.diffblue.com/background-concepts.html

dandotway··on Why the C Language Will Never Stop You from Making Mistakes
I just went through the CBMC tutorial[1] to make sure I'm not crazy. Yes, CBMC is a bounded model checker, as I thought.

  CBMC can also be used for programs with unbounded loops. In this
  case, CBMC is used for bug hunting only; CBMC does not attempt to
  find all bugs.
Frama-C is about eliminating ALL bugs, you are allowed to prove your "unbounded" loop algorithm actually terminates, and terminates with the correct solution, if you are willing to learn to use the manual proof assistant. CBMC can check for an extremely important class of errors, but it doesn't let you prove, say, your traveling salesman solver always returns a shortest trip T through the graph G, or that the graph coloring register allocator for your C compiler always correctly colors the graph, something that is actually done for the CompCert formally verified C compiler (using the Coq/Gallina proof assistant, which can be used with Frama-C).

However, having now gone through the CBMC manual, it appears to be much faster and easier to use for my own limited purposes than Frama-C. I don't need a sledgehammer to swat flies. I also like that the installation procedure on my machine was simply,

  $ sudo apt install cbmc
So I plan to give cprover a shot now, thanks for the heads up. : )

[1] http://www.cprover.org/cprover-manual/cbmc/tutorial/

Page 1 of 6Next →