8

This is my first question. I'm fairly new to Mathematica and completely new to SE, so I apologize if this question is trivial.

I'm working on a problem that requires a function to be redefined several times and applied to data. My "function generator" (not sure if this is the proper application of this term) looks like this:

makeLine[{m_, b_}] := line = Function[{x, y}, y - m x - b]

The idea being that the program can call line several times and then redefine it and call it again.

I was hopeful that I could do something like this:

Module[{line}, makeLine[{1, 0}]]

to avoid defining line as a global function, but it doesn't work.

?line

Global`line
line = Function[{x\$, y\$}, y\$ - 1 x\$ - 0]

So, is it possible to do this? If not, can someone suggest an alternate construct that does essentially the same thing?

Haer'Dalis
  • 417
  • 4
  • 9

2 Answers2

6

As Daniel describes in a comment you could make the symbol to define a parameter of makeLine. Just to show a different way I'll use a SubValues pattern:

SetAttributes[makeLine, HoldAll]
makeLine[sym_][{m_, b_}] := sym = Function[{x, y}, y - m x - b]

Module[{line},
 makeLine[line][{5, 2}];
 Array[line, {5, 2}]
]
{{-6, -5}, {-11, -10}, {-16, -15}, {-21, -20}, {-26, -25}}

However, it may be simpler to just define the symbol locally yourself:

ClearAll[makeLine]
makeLine[{m_, b_}] := Function[{x, y}, y - m x - b]

Module[{line},
 line = makeLine[{5, 2}];
 Array[line, {5, 2}]
]
{{-6, -5}, {-11, -10}, {-16, -15}, {-21, -20}, {-26, -25}}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
3

Block works as you expect.

Block[{line}, makeLine[{1, 0}]]

Module probably does not work, because it will only fake scoping for values that appear literally in it's body (ie so called lexical scoping).

Block has "dynamic" scoping. More info here.

Ajasja
  • 13,634
  • 2
  • 46
  • 104