Self Healing Code with clojure.spec
blog.cognitect.com
blog.cognitect.com
[1] http://crest.cs.ucl.ac.uk/autotransplantation/downloads/auto...
Absolutely. There are three additional issues I see with it.
Most code in our codebase deal with business objects, not with mucking about with integers. Very little of that code would have similar signatures. This would make, in many cases, for an empty pool of candidates.
Secondly, the fact that function X crashes does not always mean that function X is wrong, it may just be a case of an upstream function W sending the wrong input. If you happen to have a "no-check" version of X, the "self-heal" will happily let invalid data get into your system.
But the worse is that, while I don't know clojure.spec, I doubt that it's able to describe side effects. Who wants a program that invokes arbitrary side effects looking for a good candidate because writeData(data: string) -> void crashed with an error?
It's possibly an interesting research topic, but practically, it seems either useless or plain nasty.
Do you want reliable software? Fail fast, design with failure in mind and keep it tested by injecting failures every now and then.
I think the Erlang approach is very good and it doesn't need esoteric approaches
(Genuinely curious.)
(This comment is not meant as a criticism of the blog post btw, just a slightly related question)
The leg up that lisps have over Python is that Python's eval/exec operates on strings whereas lisps can easily manipulate the AST. (I'm not sure if I should call it abstract for a lisp.) Directly manipulating Python's AST can be done with the aptly named ast module, but personally I find it easier to do string templating and eval.
But maybe a similar method could be used as part of static analysis to help programmers. It could look through your functions and search for library functions you could import to replace them with. Or it could look for functions that do very nearly the same, but handle edge cases differently.
You can always view the term and type levels of a programming language as two separate but intertwined languages. In this case, both the term and type level would be identical instead of the type level being specialized with logic programming-esque constructs as usual.
On the other hand, in a typed language, when you check whether a term “t” has type “T”, it's a precondition that “T” is a valid type. If you haven't established that “T” is a type, you have to establish it first.
Functions that you define take parametrized input and use predefined logical constructs and produce some output. Self-healing (diction demands a more appropriate word, perhaps rectifying as code isn't defined ontologically as holistic, though a reordering of ethics might serve that purpose one day), so: self-rectifying code does so by working in the boundary conditions set by the logician who defines its instruction, and merely iterates through code chunks and tests against user defined output until it is successful. The big O to achieve fairly complex goals makes implementation very manageable, I presented a paper on this at my alma mater a few years ago and was a bit surprised it had yet to receive much traction. Every parameter can be included in the logic to ensure space and time complexity restraints are met, as well as code style.
Would you argue against a medical procedure that heals your cells instead of healing your organ at the tissue level?
The Error this was, brought forth the fail early, fail loud approach?
You can not switch context that easily, without erecting a whole system of Meta-Information for every function. So instead of debugging, we start to fill out forms again, hoping- not knowing for certain that the result will be self repairing. And then the idea dies, to be reborn again, one generation into the future. Because self-repair system even in nature are often flawed and kill the repaired organisms.
If time and resources wouldn't matter- you would stand a better chance of solving this, by having a result fitness function (aka unit test) and a genetic algorithm, modifying the code.
But I guess that saying that your system died from autoimmune disease is way more "exciting" than saying that it died from a segfault.
I can't imagine why would anyone want to have an untested set of semibuggy functions just to replace them at will. However, I can imagine the tinkering code approach, not "self-healing", when we are expecting ALL functions to be good, it is just we don't know which one fits better to the situation. People actually do this all the time since the beginning of the history, but perhaps the discussed approach can introduce more abstract framework for that.