D enters Tiobe top 20
Ola Fosheim Grøstad
ola.fosheim.grostad at gmail.com
Sun Nov 10 00:27:46 UTC 2019
On Saturday, 9 November 2019 at 21:11:14 UTC, Doc Andrew wrote:
> I'm pretty ignorant of how all that would all work, is there
> some sort of a standard way to give optimizers "hints" based on
> what the solver can show?
I don't think so, but if you establish something that is to weak
for verification it still can potentially be used for
optimization.
> I don't want to over-sell the potential performance gains.
Of course not, you would have to provide actual examples. The
"easy" gains would be from removing dynamic checks, but not so
easy in reality. If it is easy then the optimizer can already do
it using dataflow analysis.
So figuring out "trivial" small examples where the optimizer
fails by looking at generated assembly is a good starting point.
> - Universal quantification: The low-impact way would be to set
> aside an attribute @forall or @foreach, then figure out what
> tuple elements you'd need to generate a VC from them and how
> you'd tie them to a function, module, variable, etc.
I was more thinking, what do you do if it fails? One cannot keep
O(N) or O(N^2) asserts in the code as a dynamic check... :-/
I guess the easy solution is to require that "ensure" is
fulfilled at compile time and not allow quantified expressions in
asserts.
> (Longer-term, consider a change to the language to create a
> foreach expression or add a new expression "forall" (or
> something). I would anticipate a lot of weeping and gnashing of
> teeth.)
I once added a unicode-token-layer to the dmd-lexer, and added
alternative unicode math symbols to expressions. It only took a
few hours. Modifying the lexer is a lot easier than expanding the
parser. I think people who would write VC also would be familiar
with math notation, so I one could just use that to avoid clashes.
E.g. you could have a not-so-pretty ascii syntax and a unicode
shorthand.
Like: "∀" vs "@vc_forall"
Unicode tokens is really easy to do this way as you just can
rewrite "∀" to "@vc_forall" and "∃" to "@vc_exists", so no major
changes are needed to add unicode symbols.
> - Loop invariants: Allow invariant{} blocks inside loop
> statements in addition to classes and structs. This is the only
> part of the DIP that I can foresee requiring a language change;
> I don't know any way of attaching a UDA to a statement. I
> _think_ this would be the only blocker.
Proving loop progression and termination is very important, and
not so easy. What some FV languages do is that they introduce
ghost-variables for this (variables that are conceptually
computed but not used for code generation).
So basically you increment the ghost variable(s) every iteration
and prove that there is a threshold for the value where the loop
terminates.
But it won't really change the language that is compiled. It only
changes the language that is verified. So not an effective change.
But verification will probably have to happen after template
expansion... Not sure how to deal with that. Unless you want to
verify templated code... which would be cool, but not sure of
what roadblocks you would hit.
> (Even better would be strong subtypes, refinement types, or
> first-order types, but you can simulate them well enough with
> contracts in an invariant clause).
Lots of potential with more advanced typing... but prepare to be
met with a lot of resistance for things that are actual language
changes (things that can affect code gen and not only the
verifier).
> A smaller language change would be to give invariant a
> parameter with a hypothetical or ghost variable and allow it on
> aliases:
Well, yes, but not necessarily a language change... As a start
you could just define a local function "__vc_invariant" and treat
it special by the verifier?
> I'd welcome any more-informed thoughts on how to proceed and go
> through the DIP process, if there's interest!
I don't know enough about what makes a DIP succeed. What is
common in other languages is to make a library/tool
implementation first as proof of concept and then argue that it
would be better as a language extension.
So that probably is the better approach... But I don't know.
But reserving the vocabulary makes a lot of sense. Then I would
point to other languages, particularly FV languages, so that you
reserve the most common terms "@requires", "@ensures", "@forall",
"@exists" etc.
But in a proof-of-concept you can just use "_vc_requires" or some
other prefix.
>> I am actually not sure how this could be done well. Because
>> you could have array accesses within a conditional expression.
>
> Flow analysis can sort that out, checking both branches of the
> conditional and making sure that contracts hold in every case.
No, I meant how to express it syntactically in a way that allows
you to distribute pre-verified code.
(The point of having verification would be to cover those cases
that standard flow analysis fail on.)
> analysis. The first time you see warnings like "Cannot prove
> abc is less than def (example: def = 255)" because you didn't
> consider edge cases, it opens your eyes to how proofs can
> really save you from a lot of testing and debugging.
Yes, maybe that is a use case.
If you write up something formal you ought to list such
use-cases, and what they require.
> The goal is that a user doesn't have to do anything different
> than normal to write verifiable code.
:-/ not possible though.
> One kind of neat thing that SPARK has is the ability to break
> volatile down into sub-categories like "Effective_Reads", where
> reading a value takes something off a UART, or
> "Effective_Writes", where writing to a hardware register has
> some effect on the system, and "Async_Readers/Writers" where
> some hardware will be accessing memory behind the scenes... now
> how that affects the state of a proof, I'm not totally sure.
IIRC, D does not provide volatile though... You have to use
something intrinsics-like. So memory mapped registers are not
types in D, it is dealt with as a memory fenced access-action...
> So, having done no DMD compiler hacking myself, is the state of
> the "DMD as a library" mature enough now to where somebody
> could import dmd.compiler, get an AST and start figuring out
> VCs?
No idea. I think the major hurdle for you would be the templating.
Maybe only deal with non-templated code, because then you can use
one of the D parsers and rewrite the code with
verification-annotations instead of modifying the actual
compiler. For a proof-of-concept.
> A DIP without some sort of prototype tooling, even if
> primitive, is going to be pretty toothless, IMO.
Yes. You could write something "informational". Then evolve it
later.
But you'll get feedback on whether there is any interest at all
in the community? If there is no interest then it would not be
possible to maintain it in the compiler either.
Starting a discussion on the vocabulary might tell you something
about what kind of support you can expect for your ideas.
More information about the Digitalmars-d
mailing list