# Why doesn't repeated PatternSequence work with explicit pattern names?

Why would this work:

Clear[f]
f[a : PatternSequence[b_, c_]] := {a};
f[1, 2]
(* {1, 2} *)


and this also works:

Clear[f]
f[a : PatternSequence[_, _] ..] := {a};
f[1, 2, 3, 4]
(* {1, 2, 3, 4} *)


but this does not work?

Clear[f]
f[a : PatternSequence[b_, c_] ..] := {a};
f[1, 2, 3, 4]
(* f[1, 2, 3, 4] *)


Edit: Now that @RunnyKine's answer and @kguler's comment have perfectly answered my original question, I have another related question: is there a pattern-based way that I could extract the first element of the repeated pattern sequence without doing this?

Clear[fNew]
fNew[a : PatternSequence[_, _] ..] := Partition[{a}, 2][[All, 1]]
fNew[1, 2, 3, 4]
(* {1, 3} *)

-
The fact that f[3, 4, 3, 4] and f[1, 2, 1, 2] works suggests why f[1,2,3,4] does not work, no? –  kglr Jul 19 '14 at 1:14
ahh. gotcha! Thanks so much to you both. –  seismatica Jul 19 '14 at 1:16
The purpose of argument patterns on the lefthand side of a Set or SetDelayed is to allow the evaluator to determine which, if any, down-values can be used for further evaluation of the expression. It is not intended to be and can not be use as a kind macro preprocessor for modifying the argument sequence. So the answer to latest question is: no. –  m_goldberg Jul 19 '14 at 2:13
For the update to your question, fNew[a : (PatternSequence[_, _] ..)] := {a}[[1 ;; ;; 2]] will do it efficiently. fNew[a : (PatternSequence[_, _] ..)] := Downsample[{a}, 2] will do the same. –  ciao Jul 19 '14 at 2:29
@rasher, I think OP's looking for a pattern-based way on the RHS. See OP's comment below my answer. –  RunnyKine Jul 19 '14 at 2:41

This has nothing to do with PatternSequence rather the problem is with how you use Repeated (..). Take for example the following function definition:

f[x : {{_, _} ..}] := Norm[N[x]]


Now if we feed it the following input:

f[{{1, 1}, {1, 2}, {1, 3}}]


The function works as expected and yields:

4.07914333


Now let's redefine the function as follows (we use g instead)

g[x : {{a_, b_} ..}] := Norm[N[x]]


Now notice it looks just like f above but we've introduced the pattern objects a_ and b_

We feed it the same input as above:

g[{{1, 1}, {1, 2}, {1, 3}}]


And we get:

g[{{1, 1}, {1, 2}, {1, 3}}]


Well, strange, nothing happens. No match. Now let's try a different input, one where the first pair is repeated:

g[{{1, 1}, {1, 1}, {1, 1}}]


Now we get:

2.44948974


A different input with the first pair repeated:

g[{{1, 2}, {1, 2}, {1, 2}}]


Yields

3.87298335


So, you see that Repeated works in mysterious ways, well, not really. The point here is that, with no explicit pattern, you get a structural match (for lack of a better term) but with explicit pattern names you have to repeat terms just like the pattern describes. So for your last example, if you do:

f[1, 2, 1, 2]


You get:

{1, 2, 1, 2}


and

f[1, 2, 1, 2, 1, 2]


Gives:

{1, 2, 1, 2, 1, 2}


As expected.

-
Thanks @RunnyKine! This explains it perfectly, though if you have any insight on the related question I added in my question edit I'd love to hear it. –  seismatica Jul 19 '14 at 1:29
@seismatica, are you talking about replacing both Partitioning the List and collecting the first term of each List with a pattern-based approach or just the first term part? –  RunnyKine Jul 19 '14 at 1:56
I wanted to collect the first term of each PatternSequence without starting from a if that's at all possible. –  seismatica Jul 19 '14 at 1:57
@seismatica. I can't see a way to do that. Maybe someone else could help. –  RunnyKine Jul 19 '14 at 2:45