# Return unevaluated expression from function

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:

Apply[foo]@Unevaluated[Print@1]
(* foo[1] *)

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

Apply[foo]@*tee@Unevaluated[Print@1]
(* 1 *)
(* Null *)

(* not exactly the case I need this for,
but demonstrates that the issue is not only with Composition *)
Apply[foo]@tee@Unevaluated[Print@1]
(* 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])

### Update

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 @*.

• looks like closely related: Why doesn't a Composition hold its arguments and what can be done about it? and related: 78979 – Kuba Mar 30 '18 at 20:18
• @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. – Lukas Lang Mar 30 '18 at 20:33
• Ok, thanks for the edit. I will leave those links for interested readers anyway. – Kuba Mar 30 '18 at 22:18
• What if you change all Unevaluated to Inactivate? – swish Mar 30 '18 at 22:26
• Try SetAttributes[tee, HoldAllComplete];; tee[x_] := (Echo @ HoldForm @ x; Unevaluated[Unevaluated][Unevaluated[x]]) – J. M. will be back soon Mar 30 '18 at 22:35