They appear procedural because of syntax sugar - ie, the body of a function is basically implicitly wrapped in (progn ...), (begin ...), ($sequence ...), etc - which are all equivalent expression forms which evaluate their sub-expressions in order and return the result of the last one.
(progn a b c) ;; CommonLisp
(begin a b c) ;; Scheme
($sequence a b c) ;; Kernel
;; evaluate a, then b, then c,
;; ignore the results of evaluating a and b
;; return the result of evaluating c.
So when you see: (define (foo)
(expr1)
(expr2)
(expr3))
If we desugar, it would be (define foo (lambda () (begin (expr1) (expr3) (expr3))))
We get behavior that looks just like other procedural languages (without a "return" keyword) - but everything is still an expression.A similarity is the comma operator in C. Imagine you didn't write statements but the body of your C functions was entirely chains of comma operators.
CommonLisp has a couple of other useful related forms - prog1 and prog2. They still evaluate their sub-expressions in order, but prog1 returns the result of evaluating the first expression, and prog2 returns the result of the second expression.
(define (foo) (prog1 (expr1) (expr2) (expr3))
(foo)
;; evaluates expr1, then expr2, then expr3
;; returns the result of evaluating expr1
;; ignores the results of evaluating expr2 and expr3