2
$\begingroup$

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)]
$\endgroup$
5
  • $\begingroup$ 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). $\endgroup$
    – zorank
    Commented Mar 3, 2014 at 14:10
  • $\begingroup$ 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... $\endgroup$
    – zorank
    Commented Mar 3, 2014 at 14:18
  • 1
    $\begingroup$ 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]]. $\endgroup$
    – Szabolcs
    Commented Mar 3, 2014 at 14:22
  • $\begingroup$ 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. $\endgroup$
    – zorank
    Commented Mar 3, 2014 at 14:29
  • $\begingroup$ @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. $\endgroup$ Commented Mar 4, 2014 at 5:12

2 Answers 2

5
$\begingroup$

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]
$\endgroup$
1
$\begingroup$

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]]
]
$\endgroup$
2
  • $\begingroup$ what does the @@@ construct mean? I've checked the documentation, but can't find it. Is it a combination of the two @ and @@? $\endgroup$
    – zorank
    Commented Mar 6, 2014 at 9:26
  • $\begingroup$ @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... $\endgroup$ Commented Mar 6, 2014 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.