> The synchronous abstraction makes reasoning about time in a synchronous program a lot easier, thanks to the notion of logical ticks: a synchronous program reacts to its environment in a sequence of ticks, and computations within a tick are assumed to be instantaneous,
I wouldn't classify HDLs as synchronous or reactive programming explicitly because the last assumption in the quote (instantaneous ticks) is emphatically false when doing HDL programming. Synchronous programming (as with FRP systems in haskell, usage of mobx or Vue in javascript, or other such libraries) affords the programmer this tick based Excel-like approach to expressing cause-effect chains. You really can't do this in, say, Verilog if you want a functioning program.
This type of imprecision seems common when talking of programming (language) paradigms: are they based on languages in an idealised world, execution environments, language ecosystems, APIs exposed by the operating system? We can only really talk about them in an exact sense when we work in an artificial environment as in Roy and Haridi. Given the inherent imprecision, I don't see why when we deal with real systems, we shouldn't bend definitions a little bit and say a language "sort-of" or "mostly" exhibits a certain paradigm.
Edit: Ah, found it. https://groups.google.com/forum/m/#!topic/eve-talk/YFguOGkNr...
In fact, if I only had one paradigm to play with, I'd probably also want the current one, despite its limitations.
So what we then do is take the current paradigm and try to conservatively extend it. That also doesn't seem to work because you can't just bolt paradigms on top of each other. So putting on my revolutionary hat, we have to blow it all up.
I think the solution is generalization ("refactor to abstract superclass"): do something more general, then reproduce the dominant as well as other paradigms from within that generalization.