Is there any way (except using upvalues) to make a function that returns it's input Unevaluated? What I mean by that:

Take the following example:

(* foo[1] *)

(* this function should only "look" at x, but not affect anything else *)
tee[x_] := (Echo@HoldForm@x; Unevaluated@x)

(* 1 *)    
(* Null *)   

(* not exactly the case I need this for,
   but demonstrates that the issue is not only with Composition *)
(* Print[1] *)    
(* Null *)

The goal is to have the last line behave exactly the same way as the first one (except for the Echo of course). Like I mentioned above, this could probably be done using upvalues, but it feels like there has to be a simpler solution that I'm just not seeing...

Or in other words (in case the above is not clear): How to define a function (tee) with the following properties:

  • Can be composed (@*) with any non-Hold* function (i.e. without any Hold* attribute) without leaking evaluation
  • Should be fully transparent: If the argument is Unevaluated pass it along as such, otherwise don't prevent evaluation
  • Should work with any number of arguments (e.g. (foo@*tee)[a,b])


I seem to have failed state my needs clearly - I am only interested in preserving arguments wrapped in Unevaluated, not in keeping Hold* attributes while using @*.

| improve this question | | | | |
  • $\begingroup$ looks like closely related: Why doesn't a Composition hold its arguments and what can be done about it? and related: 78979 $\endgroup$ – Kuba Mar 30 '18 at 20:18
  • $\begingroup$ @Kuba Thanks for the links, but I don't think they're that closely related - I'm interested in the cases where one explicitly wraps arguments in Unevaluated (which prevents works together with Composition, e.g. (a@*Hold)[Unevaluated@Print@1]). I will try to make the question a bit clearer in that regard. $\endgroup$ – Lukas Lang Mar 30 '18 at 20:33
  • $\begingroup$ Ok, thanks for the edit. I will leave those links for interested readers anyway. $\endgroup$ – Kuba Mar 30 '18 at 22:18
  • 1
    $\begingroup$ What if you change all Unevaluated to Inactivate? $\endgroup$ – swish Mar 30 '18 at 22:26
  • 1
    $\begingroup$ Try SetAttributes[tee, HoldAllComplete];; tee[x_] := (Echo @ HoldForm @ x; Unevaluated[Unevaluated][Unevaluated[x]]) $\endgroup$ – J. M.'s technical difficulties Mar 30 '18 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.