Re: Writing a HoldAll function that evaluates its arguments
- To: mathgroup at smc.vnet.net
- Subject: [mg86250] Re: Writing a HoldAll function that evaluates its arguments
- From: Jens-Peer Kuska <kuska at informatik.uni-leipzig.de>
- Date: Fri, 7 Mar 2008 02:25:18 -0500 (EST)
- References: <fqo8h1$sq9$1@smc.vnet.net>
Hi, you should think over your question. The And[] function is a Kernel function written in C++. In C++ this behaviour is needed to prevent the access of a pointer that is not allocated because if(true==a->flag) { ... } will crash your C++ code if a is NULL and so one writes if(a && true==a->flag) { ... } and is save. In Mathematica are no pointers and so one needs this not realy. You can mimic The behaviour of And[] with Clear[myAndLike] SetAttributes[myAndLike, HoldAll] myAndLike[seq__] := Block[{tmp}, Catch[ If[(tmp = ReleaseHold[#]) === False, Throw[False], tmp] & /@ Map[Hold , Unevaluated[{seq}], {1}] ] ] and myAndLike[1 == 1, 3 == 2, Print["Hi!"]; a + a + a] will return False and Print[] nothing while myAndLike[1 == 1, 1 + 2 == 3, Print["Hi!"]; a + a + a] Print "Hi!" and return {True, True, 3 a} Regards Jens PS: Once you enter the evaluation, it is always done until the result change no more and so it is not possible to make a "evaluates each of its arguments exactly once" like LIPS does. Szabolcs Horv=E1t wrote: > What is the simplest and most elegant way of implementing a function > that has HoldAll, but it still evaluates each of its arguments exactly > once (and does not go into infinite evaluation)? > > I can come up with some ways (explicitly checking whether evaluation > changes the arguments), but neither of them are particularly elegant. > > The function should evaluate like this: > > Attributes[f] === {HoldAll} > f[] --> f[] > f[3] --> f[3] > f[1+2] --> f[3] > f[1,2] --> f[1,2] > f[0+1,1+1] --> f[1,2] > etc. > > > Let me explain my motivation for asking this seemingly absurd question > with an example: > > One built-in function that has this behaviour is And[]. This special > behaviour was needed to make And[] a "short-circuiting" function: it > evaluates the arguments one by one, and it returns False *immediately* > when one argument evaluates to False, without evaluating any further > arguments. > > Szabolcs >