Declarative Clarity


Although Clarity generally supports declarative programming, the code examples resort to imperative programming with statements mutating the state of the contract as side effect.

Would it be possible for Clarity to support a declarative programming style also for functions that determine the next state of the contract?

It can be beneficial to avoid or at least restrict side effects by keeping most functions pure. The Welcome to Clarity guide even recommends a naming convention calling out functions with side effects:

Functions that mutate data by convention terminate with an ! exclamation point.

Yet the Clarity tutorial defines functions that mutate the contract state as side effect:

(define-map tokens ((account principal)) ((balance int)))

(define-private (token-credit! (account principal) (amount int))
  (if (<= amount 0)
      (err "must move positive balance")
      (let ((current-amount (get-balance account)))
          (map-set! tokens (tuple (account account))
                      (tuple (balance (+ amount current-amount))))
          (ok amount)))))

(define-public (mint! (amount int))
   (let ((balance (get-balance tx-sender)))
     (token-credit! tx-sender amount)))

In this case, token-credit! mutates the persistent tokens map as a side effect. How could this functionality be implemented in Clarity using a declarative style?


I’m supportive of more declarative features in Clarity, but I’m not sure in this case how best to implement things like token transfers or contract data updates in general in a more declarative style. One approach would be to allow contracts to define something like transformation functions, which do not themselves mutate any state, but instead return transforms, which are then applied to the contract state. I’m not sure if it would offer much benefit for contract developers and I’d need to see some examples of it in use to be convinced.

1 Like

A declarative style could make it harder for developers to get into trouble, while facilitating static analysis. I’ll work on some examples.

How well does Clarity handle side effects in an input function to map? As in extending the earlier example:

(define-private (credit-sender! (amount int))
  (token-credit! tx-sender amount))

(define-public (map-side-effects!)
   (map credit-sender! (list 1 2 3 4 5)))