clarity-lang / reference

The Clarity Reference
146 stars 34 forks source link

Add void type #54

Open jbencin opened 1 year ago

jbencin commented 1 year ago

In Rust, there exists the unit type, () . This enables us to return Result<(), Error> for functions which may fail, but do not return meaningful data when successful. Having an empty value for the Ok() case allows us to avoid writing extra code to handle data that would be unnecessary.

Clarity currently does not have such a type. I've seen several functions which either return an error or (ok true), but never (ok false). When calling these functions, it is still necessary to write code to handle the (ok false) case, which increases the cost to call them, as well as making the code more confusing and difficult to read/audit.

Adding an equivalent type in Clarity would enable writing cleaner and more efficient contracts. As an example, consider the following function from the subnet contract here:

(define-private (inner-transfer-stx (amount uint) (sender principal) (recipient principal))
    (let (
            (call-result (stx-transfer? amount sender recipient))
            (transfer-result (unwrap! call-result (err ERR_TRANSFER_FAILED)))
        )
        (asserts! transfer-result (err ERR_TRANSFER_FAILED))
        (ok true)
    )
)

;; Call the function
...
(asserts! (try! (inner-transfer-stx amount sender CONTRACT_ADDRESS)) (err ERR_TRANSFER_FAILED))
...

With a void type, calling the function could be simplified:

(define-private (inner-transfer-stx (amount uint) (sender principal) (recipient principal))
    (let (
            (call-result (stx-transfer? amount sender recipient))
            (transfer-result (unwrap! call-result (err ERR_TRANSFER_FAILED)))
        )
        (asserts! transfer-result (err ERR_TRANSFER_FAILED))
        (ok)
    )
)

;; Call the function
...
(try! (inner-transfer-stx amount sender CONTRACT_ADDRESS))
...

Note that I used (ok) in this example, but I am not sure of the best way to represent this, whether it is (ok), (ok void), (ok ()), (ok {}), or something else.