Example 3 is very different from example 1 and 2.
Example 2 is a function with 4 arguments whereas example 3 has two arguments, first argument is a list with three elements{a_,b_,c_} and 2nd argument is r.
Function names are in Mathematica not only defined by their names but by their name,structure of arguments and the names of the arguments.
Comparing example 1 and 2, they both called like a function with 4 arguments. Example 1 with the double brackets works because function definition are stored as rules in Mathematica and evaluated by the kernel's pattern matching engine.
However example 1 seems awakened to me, because it complicates the syntax without adding any benefit.
Let's have a look how the tree examples are being called by a Pure function:
Example 1:
f[a_, b_, c_][r_] := a b c^r
f[#1, #2, #3][#4] &[1, 2, 3, 4]
(* 162 *)
Example 2:
f[a_, b_, c_,r_] := a b c^r
f[#1, #2, #3,#4] &[1, 2, 3, 4]
(*162*)
Example 3:
f[{a_, b_, c_},r_] := a b c^r
f[#1, #2] &[{1, 2, 3}, 4]
(*162*)
In general it is preferable to limit the number of arguments for a function to a minimum necessary. Example 1, even that it works technically is not very readable in the code and I would recommend to avoid it.
Hint:
The corresponding rules processed by the Mathematica kernel can be revealed using DownValues. For example
fn[a_, b_, c_, r_] := a+b+c+r
DownValues[fn]
(* {HoldPattern[fn[a_, b_, c_, r_]] :> a+b+c+r} *)