Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.

Dismiss

88 views

Skip to first unread message

Nov 18, 2009, 7:15:10 AM11/18/09

to

Dear Mathematica gurus,

One of the things that initially made Mathematica difficult for me to

use was scoping -- in particular, the fact that all symbols by default

appear in the global namespace. Even though this is a default

behavior for interactive evaluation in many packages, e.g.

R, in Mathematica, it leads to a greater potential for errors because

unlike those languages, in Mathematica

(1). a symbol can have multiple DownValues, and

(2). if one forgets to explicitly localize a symbol inside a scoping

construct, it may silently be taken from the global namespace.

After many years I finally figured out a (more or less) clean way to

structure my code and workflow, through a combination of defining

modules, contexts, packages, and careful use of Clear and Remove.

I still wonder, however, why there isn't a construct similar to Module

that would define a unique private context for _all_ symbols within

the construct (i.e. without having to declare them in a list). You

can kind of simulate this behavior by using BeginContext["MyCont`"]

together with redefining $ContextPath temporarily to only have

"MyCont`" and "System`". This is obviously too verbose to be of

practical use, but I do wonder why there isn't a built-in construct.

I suppose my question is -- is there a deep wisdom behind its absence,

or perhaps I am an anomaly in thinking that such behavior (automatic

lexical scoping for symbols in subroutines, present in R and

many others) would be incredibly handy?..

Thanks,

--Leo

Nov 19, 2009, 5:25:32 AM11/19/09

to

Hi Leo,

I certainly don't qualify as a guru (and don't want to), but here are my two

cents.

1. I usually think of a notebook as an interactive development and

visualization tool (apart from it being an interactive document, the aspect

which is more relevant for presentation rather than for development),

something like a top-level in some other functional languages. Modules and

other smaller-scale localization tools should be sufficient within a

notebook, and if they are not, it's a clear sign to me that the (part of

the) functionality must be moved into a properly formed package (at least

using BeginPackage - EndPackage etc).

2. Nobody forbids you to use BeginPackage - EndPackage with inner Begin-End

and private sub-contexts within a notebook, with the same benefits as they

give you in stand-alone package files.

3. A somewhat related question about automation of the steps needed to

localize some code in a certain context was recently asked on the group. I

posted some possible solution in this thread:

http://forums.wolfram.com/mathgroup/archive/2009/Aug/msg00701.html

It is not without bugs though - I mentioned some of the limitations (all of

which can be fixed) in my post. Eventually I will fix them and have a more

complete solution available. See if the solution from my post can serve your

needs.

Regards,

Leonid

Nov 19, 2009, 5:26:16 AM11/19/09

to

I'm not certain why many people seem to have problems with localization of

symbols. I write lots of Mathematica definitions and code, I never use

CleanSlate or Remove or Clear all Global` symbols and I never get into

trouble (well, hardly ever).

symbols. I write lots of Mathematica definitions and code, I never use

CleanSlate or Remove or Clear all Global` symbols and I never get into

trouble (well, hardly ever).

There are a few simple Mathematica style principles that can avoid most such

problems.

1) Never assign values to simple symbols that you might conceivably want to

use as symbolic variables, for example in equation solving. To save

intermediate results while working out some development use names that you

would never use as theoretical symbols; names such as: step1, step2,

testmat, temporary.

2) Always use ClearAll[functionname] before a function definition because in

development one might easily change the lhs argument pattern, leaving old

definitions around. Also clear function names before solving differential

equations because afterwards you may want to define them from the solution.

3) Always have an Initialization Section and load all packages needed in the

notebook there, usually with Initialization cells.

The following is an example of the type of writing we often see in postings

to MathGroup.

a = .5;

b = 3;

f = Exp[-a x] Sin[b x];

Plot[f, {x, 0, 6}]

It works, but is an invitation to problems because one might later forget

that these symbols have values, or where exactly they were set. So clean up

the symbols and write a definition instead that localizes the arguments.

Clear[a, b]

ClearAll[f]

f[a_, b_][x_] := Exp[-a x] Sin[b x]

Plot[f[.5, 3][x], {x, 0, 6}]

Or if one doesn't want to keep specifying the parameters in function calls

because they aren't changed often, write:

ClearAll[f]

With[{a = .5, b = 3},

f[x_] := Exp[-a x] Sin[b x]]

Plot[f[x], {x, 0, 6}]

I apologize for a response that is more elementary than you were probably

looking for but I hope it will be helpful to many new users.

As for having a construction that automatically localized all symbols within

it, I think one would soon find that exceptions were desired, in which case

it is not much more convenient than the present case. Perhaps you meant to

localize all symbols that have a Global context? But then suppose you are

not working in the Global context? One could end up with some complicated

rules as to what is localized. It seems better in localization structures to

specify explicitly what is being localized.

David Park

djm...@comcast.net

http://home.comcast.net/~djmpark/

Nov 20, 2009, 6:49:17 AM11/20/09

to

timers" have learned to use these style principles the hard way :-)

--V. Stokes

Nov 21, 2009, 3:35:10 AM11/21/09

to

hi David;

"David Park" <djm...@comcast.net> wrote in message

news:he36g8$efk$1...@smc.vnet.net...

>

> Clear[a, b]

>

> ClearAll[f]

> f[a_, b_][x_] := Exp[-a x] Sin[b x]

>

> Plot[f[.5, 3][x], {x, 0, 6}]

>

How about also using the above, but also use /. to assign values to

parameters.

Plot[f[a, b][x] /. {a -> .5, b -> 3}, {x, 0, 6}]

You are right, I am finding that if one is very aware and disciplined during

programming Mathematica then can side step many common problems, because in

Mathematica it is more easy to fall into subtle problems for new users than

in other programming languages. If one is slightly sleepy while programming

in Mathematica, then many strange problem will show up later on.

I also wish that Mathematica error handling can be improved in the sense

that when some error shows up in some long running code, that at least it

would tell me on which _line_ the error happened. not just some error

message telling me that I can do this or that.

It seems that, when this happens, I spend more time trying to figure where

the error is coming from because the error message never tells me where this

error is, even though it must have known. It does not even tell me which

function it was in.

If there was an easy to use debugger, I could run the code inside it,

telling it to stop when an error or warning occurs, and this way I know

exactly where the error was. But there is no such thing in Mathematica.

(Please do not tell me to use this so called debugger in Mathematica 7,

under Evaluation, I tried, and have no idea how it is supposed to work).

I hope this error handling improves in next version of Mathematica, and

please make the debugger like a _normal_ and standard debugger is supposed

to be.

May be what we also need is like what David had here, a set of articles that

talks just about good programming styles for Mathematica, or good "patterns"

to follow, targeted to users like most of us, who are not expert Mathematica

programmers. I think this will be very useful.

thanks,

--Nasser

Nov 22, 2009, 6:08:56 AM11/22/09

to

Hi Nasser,

Yes rules are a good way to introduce data without setting values to

symbols. This might especially be the case if you are working a problem with

units. You might have something like:

(Problem1Data = {x0 -> 3.25 Meter, v0 -> 5.2 Meter/Second})//Column

then perform symbolic calculations, perhaps using Solve or DSolve, with

equations that contain x0 and v0 and then substitute the data into the

result at the end of the symbolic calculation. Notice that units should be

part of the data and not part of the equations.

result /. Problem1Data

As far a debugging and code development are concerned, I believe most

difficulty occurs by combining too much at once without looking at the

subparts. For me, most routines start out as separate steps in a notebook,

sometimes in one cell and sometimes in separate cells evaluated on a typical

case. I want to see the output and don't use ";" until I'm pretty satisfied

I know what I'm getting. After that, most errors come from failure to

consider special cases.

Only when I've calculated some cases do I try to write a formal definition

and start moving the steps to a Module. There I may only add one step at a

time and repeatedly evaluate to see that any generalizations are working. I

may add Print statements to display intermediate values until I am finished

or I may add them if a problem arises. Sometimes I might set a global temp

variable to some intermediate result, retrieve it from an evaluation, and do

some code development using it as starting data. Mathematica allows one to

do all this simple stuff within a single notebook so why not take advantage

of it? Mathematica is really ideal for this kind of development. Anyway for

me it has worked pretty well and I've never felt the need to study how the

various debuggers work.

Then I might copy a routine to a notebook Routines section (which I call

Package Purgatory) and add a usage statement, SyntaxInformation and other

ancillary definitions. Then after using it for awhile and if it seems

generally useful I may move it to Package Heaven.

From: Nasser M. Abbasi [mailto:n...@12000.org]

hi David;

"David Park" <djm...@comcast.net> wrote in message

news:he36g8$efk$1...@smc.vnet.net...

>

> Clear[a, b]

>

> ClearAll[f]

> f[a_, b_][x_] := Exp[-a x] Sin[b x]

>

> Plot[f[.5, 3][x], {x, 0, 6}]

>

How about also using the above, but also use /. to assign values to

parameters.

Plot[f[a, b][x] /. {a -> .5, b -> 3}, {x, 0, 6}]

You are right, I am finding that if one is very aware and disciplined during

programming Mathematica then can side step many common problems, because in

Mathematica it is more easy to fall into subtle problems for new users than

in other programming languages. If one is slightly sleepy while programming

in Mathematica, then many strange problem will show up later on.

I also wish that Mathematica error handling can be improved in the sense

that when some error shows up in some long running code, that at least it

would tell me on which _line_ the error happened. not just some error

message telling me that I can do this or that.

It seems that, when this happens, I spend more time trying to figure where

the error is coming from because the error message never tells me where this

Nov 22, 2009, 6:09:17 AM11/22/09

to

> > Clear[a, b]

> >

> > ClearAll[f]

> > f[a_, b_][x_] := Exp[-a x] Sin[b x]

> >

> > ClearAll[f]

> > f[a_, b_][x_] := Exp[-a x] Sin[b x]

I've seen this more complex form of function definition go by once or

twice in the past, but never used it or learned about it myself.

Pointers to tutorial explanations?

[Or, more challenging, an explanation, in classic "teach a man to fish"

mode, of how a mythical "ordinary user" might go about quickly and

efficiently _finding_ such tutorial explanations, for this specific

case, in Mathematica documentation.]

Nov 23, 2009, 7:10:53 AM11/23/09

to

It's called SubValues. One advantage is that it cleanly separates parameters

from variables. Another is that you can write expressions such as:

from variables. Another is that you can write expressions such as:

f[a, b]'[x]

You can also use it conveniently as a postfix operator:

x//f[a, b]

There would be many operations in Mathematica that would be easier to use if

they were defined with SubValues. For example the various

GeometricTransformations are inconvenient in their present form because they

have to be wrapped around a piece of graphics. Postfix operation would be

more convenient. (In Presentations I do provide alternative postfix forms of

all these operators because we always have the primitive form of graphics

available to operate on and it is convenient to define a basic form and then

move it to its proper place.)

But SubValues seems to be the poor orphan of Mathematica "Values". There is

a usage message but no documentation page. I don't know of any tutorial for

it. Command completion for SubValues definitions doesn't give the entire

expression, which I think it should. And DocuTools doesn't handle it

properly. WRI seems to avoid SubValues in any of their basic functions. I

don't know if there is a good reason for this.

You can type SubValues in the DC SEARCH box and then use "Try your search on

all Wolfram sites" to get a fair amount of MathGroup discussion about

SubValues.

The saying is: "Give a hungry man a fish and he'll be back the next day.

Teach a hungry man to fish and you won't see him again for two or three days

- if he hasn't drowned in the meantime."

From: AES [mailto:sie...@stanford.edu]

> > Clear[a, b]

> >

> > ClearAll[f]

> > f[a_, b_][x_] := Exp[-a x] Sin[b x]

I've seen this more complex form of function definition go by once or

0 new messages

Search

Clear search

Close search

Google apps

Main menu