Cx supports functions, if and loops for both combinational and synchronous logic. You can have a function that spans over two cycles. You can give parameters to this kind of function just like in software, except that in the end this is all inlined and the state machine is flattened.
The language encourages a higher level of abstraction where you think in terms of blocking reads and data availability rather than "is my signal true". The best is that this can be extended just by changing the port signature, for example to provide rendez-vous style communications (we call it "sync ack" but they're not implemented yet), whereas in HDL you'd have to write a lot of boilerplate code.
Another property is that there is no synthesizable subset in Cx. As far as I know, this is very rare in languages for hardware design, but the language is entirely synthesizable. You never have to think about synthesis versus simulation. Exactly like in software, nobody ever wonders if they can write code that won't run on the processor :-)
And for the example you mention, this is another interesting feature of the language. Because we support sequential loop constructs etc. you can actually write code that works and synthesizes pretty easily, albeit it is slow. And then you can produce a derived version that is optimized :-)
This is scary. I want the tool to tell me "I can't synthesize this" because when it does, it might infer characteristics of the design that I might not want.
Do you have some kind of paper or detailed explanation about this part?
Sometimes a bad design is not bad because it's badly written, it's bad because it's not complying with some timing constraints or because the synthesis tool decided to infer some crazy system from the code the designer wrote.
In Cx you can't create latches, loops work for combinatorial logic and synchronous logic alike, and all in all there are no unsynthesizable constructs. Finding out if a piece of code will result in unacceptable performance is a different problem, I hope to have the compiler kind of "guide" you on this kind of things.
That's a workflow where optimization requires knowing the internals and how they interact, but you can ignore such things if you just want correctness. At least in software, that model works well, because the performance of most of the code we write doesn't matter - even in applications where performance is a concern.
People may get hung up on this because the example on your page is so simple. The equivalent VHDL and Verilog is also relatively simple. A simple example is good, and a comparison is good, but just presenting the differences is not enough. Stress what someone coding in Cx does not have to think about. In other words, what are the abstractions in Cx?
Consider what the equivalent page for C versus assembly would look like for a function that computes some simple arithmetic. Some people may say, "Oh, sure, the assembly has a few more lines because you need to push and pop parameters from the stack, but that's no big deal." And it's not - for one function. What's the big deal is that there are entire concepts - saving existing registers, pushing parameters onto the stack, register management - that C programmers don't need to think about. (Most of the time.)
The code you link to elsewhere in this thread hints to me that there are indeed significant abstractions behind Cx, that make it more than just an alternative syntax to Verilog and VHDL. See: https://github.com/synflow/sha-256/blob/master/SHA256/src/co...