Replace Table by functional programming

Partition[{#, # #} & /@ Range[3, 6], 2]

{{{3, 9}, {4, 16}}, {{5, 25}, {6, 36}}}


Array[{#, #^2} & @@ {#2 + 2 #} &, {2, 2}, {0, 3}] (* or *)
Outer[{#, #^2} & @@ {#2 + 2 #} &, {0, 1}, Range[3, 4]]

{{{3, 9}, {4, 16}}, {{5, 25}, {6, 36}}}

Removing hard-coded parameters:

f1 = Module[{x = #[[1]], l = Length@#}, 
    Array[{#, #^2} & @@ {#2 + l #} &, {l, l}, {0, x}]] &;
f1 @ Range[3, 4]

{{{3, 9}, {4, 16}},
{{5, 25}, {6, 36}}}

f1 @ Range[4, 6]

{{{4, 16}, {5, 25}, {6, 36}},
{{7, 49}, {8, 64}, {9, 81}},
{{10, 100}, {11, 121}, {12, 144}}}

And, similarly for Outer:

f2 = Module[{l = Length@#, x = #}, 
      Outer[{#, #^2} & @@ {#2 + l #} &, Range[l] - 1, x]] &;

f2 @ Range[3, 4]

{{{3, 9}, {4, 16}},
{{5, 25}, {6, 36}}}

f2 @ Range[4, 6]

{{{4, 16}, {5, 25}, {6, 36}},
{{7, 49}, {8, 64}, {9, 81}},
{{10, 100}, {11, 121}, {12, 144}}}

Also

☺ = # /. ♯_ :> ({#, #^2} & @@@ ({♯ + #} & /@ {0, (♯♯ = 0; ♯♯++ & /@ #; ♯♯)})) &;

☺ @ {3, 4}

{{{3, 9}, {4, 16}}, {{5, 25}, {6, 36}}}

☺ @ Range[3, 7]

{{{3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}},
{{8, 64}, {9, 81}, {10, 100}, {11, 121}, {12, 144}}}


BlockMap[{{#1[[1]], #[[1]]^2}, {#1[[2]], #[[2]]^2}} &, Range[3, 6], 2]
(* {{{3, 9}, {4, 16}}, {{5, 25}, {6, 36}}} *)