Most Bitcoin and Ethereum transactions are completely explicit. They specify the exact state changes to be made and prove that the signer has permission to update that state. You have given your permission for a specific, precisely defined change of state. Either that exact state change will occur, or no update will be made.   Smart contracts, however, complicate things. The outcome of a call to a smart contract may depend on many things. As such, smart contracts prevent us from knowing the outcome of a transaction before it is confirmed. Its state changes are unknown before the transaction is included in a block. By signing the transaction, the user has consented to whatever state changes the contract defines, without knowledge of the outcome.   Given that the entire point of a blockchain is to create and update a state securely, smart contracts are intuitively problematic. Contracts should describe the state changes that are allowed, based on the current state. Users would then submit proposed state updates, which would be validated by the contract. If the state updates are approved, the exact state update the user wants would be made. This is a declarative smart contract, as it declares what allowed state changes, and leaves all control logic and implementation to the users. Declarative contracts align the structure of the contract implementation with the reality of the chain by defining exactly what state modifications are permissible and letting the user modify state directly.   Solidity has been adding features that make it more declarative. And the best practices for Solidity (like Checks-Effects-Interactions) are declarative.