Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2000
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2000

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

Search the Archive

Re: How to call by reference for particular argument(s)?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg22145] Re: How to call by reference for particular argument(s)?
  • From: Dr Dan <drdanw at my-deja.com>
  • Date: Wed, 16 Feb 2000 02:35:08 -0500 (EST)
  • References: <8889e1$c4r@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

One of the most difficult things about learning Mathematica programming
is that Mathematica is not c or FORTRAN.  Some of my worst Mathematica
programs were written while I was also coding c software.  Your example
shows that you are trying to think in a low-level language.  The sooner
you begin to think in terms of Mathematica constructs, the more
powerful and elegant your programs will become.

Mathematica does not have call-by-reference, or even call-by-value,
because Mathematica does not have a function call stack.  In
Mathematica, every time you make a definition (using Set (=) or
SetDelayed (:=), for example) the kernel stores a rule associated with
a pattern of symbols.  When an expression is evaluated, the evaluator
checks for patterns within the expression that have rules associated
with them, and applies the rules.  The evaluator continues this
operation until the expression quits changing; the final expression is
returned as the result.  Nothing is "passed" during evaluation; the
function name and arguments are recognized as matching a pattern, the
arguments are substituted into the function definition, and the
resulting expression is evaluated.

This may seem very obscure and esoteric now, but once you train
yourself to think like a Mathematica programmer, your position
algorithm (which would be very clever in FORTRAN) becomes a one-liner:

In[15]:=
myPosition[v_, e_List] := Flatten[Map[Position[v, #1] &, e]]

In[16]:=
res = myPosition[{a, b, c, d, e}, {b, d}]

Out[16]=
{2, 4}

The symbol res now has the value {2,4} without a reference having been
passed to a subroutine.  This style imitates a Function call in BASIC.
If you want to imitate Subroutine call that returns several results via
call-by-reference, define the function to return a list of results.
For example, if your function is to return the position of every symbol
in the second argument and the second argument in reverse order, write


myPosition2[v_, e_List] := Module[{p, rev},
	p = Flatten[(Position[v, #1] & ) /@ e];
	rev = Reverse[e];
	{p, rev}]

In[36]:=
{res, rev} = myPosition2[{a, b, c, d, e}, {b, d}]

Out[36]=
{{2, 4}, {d, b}}

In[37]:=
res

Out[37]=
{2, 4}

Your second problem, in which myPosition does not evaluate with the
arguments u1 and u2, occurs because of the attribute HoldAll.  HoldAll
tells Mathematica to hold all arguments of a function without
evaluation.  Since u1 and u2 are not evaluated into the lists they
represent, your function fails.


In article <8889e1$c4r at smc.vnet.net>,
  d8442803 at student.nsysu.edu.tw (Wen-Feng Hsiao) wrote:
> Dear all,
>
> I cannot figure out how to call by reference for particular
arguments.
> Say, I want to design a function, which will return the position list
> where the second list locates in the first list. For example,
>
> If one inputs the following code:
>
> In[1]:=
> res={};
> myPosition[{a, b, c, d, e}, {b, d}, res];
> res
>
> It outputs {2, 4}. Since the b and d in the second list are in the
> positions 2 and 4 of first list. My code is listed below.
>
> SetAttributes[myPosition, HoldAll];
> myPosition[v1_, {e1_, e2___}, res_Symbol] := Module[{tmp},
>       tmp = Flatten[Position[v1, e1]];
>       If[Length[tmp] != 0,
>         AppendTo[res, tmp[[1]]]];
>       If[nil[{e2}] =!= nothing, (* if e2 not null *)
>         myPosition[v1, {e2}, res]]];
>
> The difficulties are when I change it to the followings, it cannot
work:
>
> In[10]:=
> res={};
> u1={a, b, c, d, e}; u2={b, d};
> myPosition[u1, u2, res];
> res
>
> the myPosition[u1, u2, res] cannot be resolved. How can I do? Change
the
> signature to myPosition[v1_Symbol, {e1_Symbol, e2___Symbol},
res_Symbol]
> does not work either. It's obvious that the intended call by
reference is
> only for the third argument "ref", so please show me the rope,
thanks!
> Furthermore, is there any function exists for the same purpose as
> myPosition?
>
> Wen-Feng
>
>


Sent via Deja.com http://www.deja.com/
Before you buy.


  • Prev by Date: Re: Re: Sorting
  • Next by Date: Finally...the results
  • Previous by thread: Re: How to call by reference for particular argument(s)?
  • Next by thread: Re: How to call by reference for particular argument(s)?