12

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} *)
seismatica
  • 5,101
  • 1
  • 22
  • 33
  • 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 01:14
  • ahh. gotcha! Thanks so much to you both. – seismatica Jul 19 '14 at 01: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 02:13
  • 3
    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 02: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 02:41
  • Thanks @rasher! Your method seems to be the best one yet to do what I want; the reason why I decided to assign the names to the pattern sequence in the first place is to someone use that name to manipulate them in the function definition. Using a pattern (without naming it) as a parameter and then having to seek for what that pattern is again in the RHS seem a little backward to me. I think m_goldberg's comment kinda addresses that but I don't quite feel advanced enough to know precisely what he/she was talking about (researching for what down-values were hurt my head). – seismatica Jul 19 '14 at 04:58
  • @seismatica In my opinion your addendum would be better as a separate follow-up question. – Mr.Wizard Jul 19 '14 at 07:10

1 Answers1

13

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.

RunnyKine
  • 33,088
  • 3
  • 109
  • 176
  • 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 01: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 01: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 01:57
  • @seismatica. I can't see a way to do that. Maybe someone else could help. – RunnyKine Jul 19 '14 at 02:45