Merging two held expressions into a held compound expression

Consider

e1 = Hold[a = x + x; b = y + y + y];
e2 = Hold[c = a + a + b + b + b; c^2];


How can I obtain the following?

e12 = Hold[a = x + x; b = y + y + y; c = a + a + b + b + b; c^2]


For example,

e1 ~Join~ e2


does not work since it gives one "," sign in the middle. another attempt

With[{e1temp = e1, e2temp = e2}, Hold[e1temp; e2temp]]


gives nested Hold calls that at the end do not want to evaluate (and are hard to get rid off):

Hold[Hold[a = x + x; b = y + y + y]; Hold[c = a + a + b + b + b; c^2]]]


I am amazed that such a simple thing is causing me so much pain. :)

Edit

My current solution.

merge[Hold[expr1_], Hold[expr2_]] := Hold[expr1; expr2]
merge[e1, e2]

Hold[(a = x + x; b = y + y + y); (c = a + a + b + b + b; c^2)]

-
I have solved it by coding a special merge function: merge[Hold[expr1_],Hold[expr2_]] := Hold[expr1, expr2], though I do not really understand why it woks. anyway, I would like to know whether there are other ways (e.g. without using such a function; and yes, the construct ()& would be cheating). –  zorank Mar 3 '14 at 14:10
another option is to convert everything to strings and the merge strings and use ToExpression to convert back. but, that I would like to avoid too... –  zorank Mar 3 '14 at 14:18
That function from your comment gives precisely the same result as Join. It should be merge[Hold[CompoundExpression[expr1__]], Hold[CompoundExpression[expr2__]]] := Hold[CompoundExpression[expr1, expr2]]. –  Szabolcs Mar 3 '14 at 14:22
apologies (it was a typo in the definition). please take a look at the EDIT above. it gives the right thing (though with too many ()'s). smart to put explicit CompoundExpression headers. but, as I said, the question is whether it is possible to do it wihout the merge function. –  zorank Mar 3 '14 at 14:29
@Szabolcs I had believed that the following accomplishes what you want to do: e12 = Thread[Join[e1, e2]] gives Hold[a = x + x; b = y + y + y, c = a + a + b + b + b; c^2] However, as Szabolcs pointed out in a comment to the answer I had posted, it puts it as two elements in the Hold with the comma in between. I realized that this was the same as what zorank had meant with the ~Join~ command, so I have deleted it as an answer and moved it here to a comment. –  Andy Mobley Mar 4 '14 at 5:12

I'm not sure why you don't like your merge function. This is the same pattern matching approach but using ReplaceAll:

{e1, e2} /. {Hold[x_], Hold[y_]} :> Hold[x; y]


If you would rather avoid patterns here is one (ugly) option:

Block[{CompoundExpression}, (e1; e2) ~Thread~ CompoundExpression ~Thread~ Hold]

-

I think there is nothing wrong with the solutions you have. If for whatever reason you'd really need to join into one CompoundExression instead of nesting three of them, then here are two way to achieve that:

CompoundExpression @@@ Join[
Hold @@@ Hold[a = x + x; b = y + y + y],
Hold @@@ Hold[c = a + a + b + b + b; c^2],
2
]


Many functions which operate on "generalized" lists have a level argument and so does Join. Unfortunately it wants the heads of all levels above the one it operates to be the same which makes necessary to exchange the CompoundExpression by Hold temporarily for you example and the above a little more complicated than one would wish...

Of course pattern matching is also an options which almost always will provide a solution:

Replace[
{Hold[a = x + x; b = y + y + y], Hold[c = a + a + b + b + b; c^2]},
{Hold[CompoundExpression[cp1__]], Hold[CompoundExpression[cp2__]]} :>
Hold[CompoundExpression[cp1, cp2]]
]

-
what does the @@@ construct mean? I've checked the documentation, but can't find it. Is it a combination of the two @ and @@? –  zorank Mar 6 '14 at 9:26
@zorank: @@ is a shortcut for Apply. @@@ is a shortcut for Apply[_,_,{1}] that is apply at first level. You'll find details in the documentation for Apply... –  Albert Retey Mar 6 '14 at 14:32