MathGroup Archive 2000

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: @@@ for Version 3??

  • To: mathgroup at smc.vnet.net
  • Subject: [mg23123] Re: [mg22967] @@@ for Version 3??
  • From: Hartmut Wolf <hwolf at debis.com>
  • Date: Wed, 19 Apr 2000 02:30:52 -0400 (EDT)
  • Organization: debis Systemhaus
  • References: <200004050241.WAA01036@smc.vnet.net> <8ch9iv$95n@smc.vnet.net> <Pine.GSO.4.21.0004061746200.23405-100000@flip.eecs.umich.edu> <200004070654.CAA16541@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

See below for more on @@@ and Version 3:

Hartmut Wolf schrieb:
> 
> Daniel Reeves schrieb:
> >
> > > (If you don't have version 4, then replace @@@ by the alternative
> > > input form:
> > >
> > > In[5]:= Hold[F[x] @@@ k] // InputForm
> > > Out[5]//InputForm=
> > > Hold[Apply[F[x], k, {1}]]
> > > )
> >
> > Or you can actually replace the
> > @@@
> > with
> > @@#&/@
> >
> > Ugly, but I do it that way so it's easy to switch over to the ver4 way
> > sometime in the near future when I can feel sure that my code won't ever
> > need to run on ver3 anymore.
> >
> 
> Hallo Daniel,
> 
> nice ideom! Yet you have to be cautious when applying it:
> 
> In[1]:= k = {{a1, b1}, {a2, b2}, {a3, b3}}
> 
> In[2]:= f @@@ k
> Out[2]= {f[a1, b1], f[a2, b2], f[a3, b3]}
> 
> In[3]:= g /@ f @@@ k
> Out[3]= {g[f[a1, b1]], g[f[a2, b2]], g[f[a3, b3]]}
> 
> In[4]:= f @@#&/@ k
> Out[4]= {f[a1, b1], f[a2, b2], f[a3, b3]}
> 
> In[5]:= g /@ f @@#&/@ k
> Out[5]= {f[g[a1], g[b1]], f[g[a2], g[b2]], f[g[a3], g[b3]]}
> 
> So @@#&/@ is not a "read macro" to be textually substituted by @@@ when
> transiting from version 3 to 4 (or vice versa). Of course the correct
> expression for In[5] would be:
> 
> In[6]:= g /@ (f @@ # &) /@ k
> Out[6]= {g[f[a1, b1]], g[f[a2, b2]], g[f[a3, b3]]}
> 
> The full form Apply[f, k, {1}] however remains correct in any case for
> both versions.
> 
> If you want to have a true syntactical equivalent substition for @@@ you
> may have one; define
> 
> In[16]:= aaa = ( Function[{e}, #1 @@ e ] /@ #2 &)
> 
> In[17]:= f ~aaa~ k
> Out[17]= {f[a1, b1], f[a2, b2], f[a3, b3]}
> 
> In[18]:= g /@ f ~aaa~ k
> Out[18]= {g[f[a1, b1]], g[f[a2, b2]], g[f[a3, b3]]}
> 

Dear Daniel,

this was one of my replies I soon felt uncomfortable with after having
pressed the send button too early.  First of all, I missed to include a
neccessary wink ;-)  Second, although I raised a problem, this is not
the solution, not at all a "true syntactical equivalent".  What is still
flawed are the associativity rules for @@@, @@, /@.  In Version 4 these
operators all are of equal precedence and group to the right:

With  aaa = Apply[#1, #2, {1}] &  however ~aaa~ groups to the left, and
the precedence is one above @@ and /@, see:

In[21]:= g @@@ f @@@ k === g ~aaa~ f ~aaa~ k
Out[21]= False
In[22]:= g @@@ f @@@ k === g ~aaa~ (f ~aaa~ k)
Out[22]= True

In[23]:= g @@@ f @@ k === g ~aaa~ f @@ k
Out[23]= False
In[24]:= g @@@ f @@ k === g ~aaa~ (f @@ k)
Out[24]= True


In[25]:= g @@@ f /@ k === g ~aaa~ f /@ k
Out[25]= False
In[26]:= g @@@ f /@ k === g ~aaa~ (f /@ k)
Out[26]= True

However, when you always explicitly parenthesize your expressions you
can safely use your suggested (elegant I think it is) ideom:

In[27]:= g @@@ f @@@ k === g ~aaa~ (f @@ # & /@ k)
Out[27]= True



For some days I pondered the question: can we do better?

First of all, I think we cannot define @@@ as new operator in Version 3.
The front end scanner will separate this into the two tokens @@ and @ on
the fly on sequential input (this is from version 3):

	f @@ @ g

(Only input cell, key [Enter] not pressed yet.) If we activate Show
Expression from the Format menu (or press [Ctrl]+[Shift]+[e]) we see
(and still nothing evaluated):

Cell[BoxData[
    RowBox[{"f", " ", "@@", 
      RowBox[{"@", " ", "g"}]}]], "Input"]

(You can see from that expression, that no Space was input between the
second and third '@'.) 

An idea would be to use Low-Level Input Rules (as explained in §2.8.17);
however we must first find an input string which we can use for
reworking the parsed input. After some futile trials I came up with the
sequence

	f @$@ g

Cell[BoxData[
    RowBox[{"f", " ",  "@", 
      RowBox[{"$", "@",  " ", "g"}]}]], "Input"]

which interpreted in FullForm is of course just

	f[$[g]]

I think, you will never come across the symbol $ to have a value,
contrary to 'q' (which else I would have preferred for input ergonomy)
 
<< now quit the kernel and restart >>

In[1]:= MakeExpression[ RowBox[{f_,  "@", 
      RowBox[{"$", "@", g_}]}], StandardForm] := 
  MakeExpression[RowBox[{"mapply", "[", f, ",", g, "]"}],
		StandardForm]

We try it:

In[2]:= k = {{a1, b1}, {a2, b2}, {a3, b3}}

In[3]:= f @$@ k
Out[3]= mapply[f, {{a1, b1}, {a2, b2}, {a3, b3}}]

In[4]:= g @$@ f @$@ k
Out[4]= mapply[g, mapply[f, {{a1, b1}, {a2, b2}, {a3, b3}}]]

So all what we have to do is define mapply:

In[5]:= mapply[f_, g_] := Apply[f, g, {1}]

In[6]:= f @$@ k
Out[6]= {f[a1, b1], f[a2, b2], f[a3, b3]}

So it works! Grouping turned out to be right (automatically, as a
consequence of the grouping of @). 

Now how to get the right precedence with @@ and /@ ? Again we locally
manipulate the parse tree:

In[8]:=
MakeExpression[RowBox[{
      RowBox[{f_, "@", 
        RowBox[{"$", "@", g_}]}], "@@", h_}], StandardForm] := 
  MakeExpression[RowBox[{"mapply", "[", 
      RowBox[{f, ",", 
        RowBox[{g, "@@", h}]}], "]"}], StandardForm]
In[9]:=
MakeExpression[RowBox[{
      RowBox[{f_, "@", 
        RowBox[{"$", "@", g_}]}], "/@", h_}], StandardForm] := 
  MakeExpression[RowBox[{"mapply", "[", 
      RowBox[{f, ",", 
        RowBox[{g, "/@", h}]}], "]"}], StandardForm]


With that things seem to work:

In[10]:= g @@@ f @@@ k === g @$@ f @$@ k
Out[10]= True
In[11]:= g @@@ f @@ k === g @$@ f @@ k
Out[11]= True
In[12]:= g @@@ f /@ k === g @$@ f /@ k
Out[12]= True

Of course also

In[13]:= g /@ f @$@ k
Out[13]= {g[f[a1, b1]], g[f[a2, b2]], g[f[a3, b3]]}

In[14]:= g @@ f @$@ k
Out[14]= g[f[a1, b1], f[a2, b2], f[a3, b3]]

I tried more cases, they all worked. I would be interested if someone
finds a hole in it!

Kind regards,  Hartmut


  • Prev by Date: Re: Help! Mathematica on my 500MHz outperforms my GHz machine!
  • Next by Date: Kernel keeps crashing
  • Previous by thread: Re: best solution?
  • Next by thread: Re: best solution?