You stop when you feel like it. You can also call getScores[], getCalled[] , getPrcntp[] at any time to get the current state of these variables (if you need that for further processing).
Regards, Leonid
On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck <mcguyver...@yahoo.com>wrote:
> this code is supposed to randomly select a student from a list, keep track > of how many times he/she has been called, and how many answers they have > gotten correct.
> I am having problems getting the following code to repeat on request: i > have tried do loops, while loops, and labels none have worked. please help
> this code is supposed to randomly select a student from a list, keep > track of how many times he/she has been called, and how many answers > they have gotten correct.
> I am having problems getting the following code to repeat on request: i > have tried do loops, while loops, and labels none have worked. please > help
> You don't need a loop at all, if I understand your goal correctly. What > you > need is a bit of Dynamic functionality. Hope this will get you started:
> You stop when you feel like it. You can also call getScores[], > getCalled[] > , getPrcntp[] at any time to get the current state of these variables > (if > you need that for further processing).
> Regards, > Leonid
> On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck > <mcguyver...@yahoo.com>wrote:
>> this code is supposed to randomly select a student from a list, keep >> track >> of how many times he/she has been called, and how many answers they have >> gotten correct.
>> I am having problems getting the following code to repeat on request: i >> have tried do loops, while loops, and labels none have worked. please >> help
> On Sat, 23 Jan 2010 06:30:56 -0600, Leonid Shifrin <lsh...@gmail.com> > wrote:
> Hi Glenn,
>> You don't need a loop at all, if I understand your goal correctly. What >> you >> need is a bit of Dynamic functionality. Hope this will get you started:
>> You stop when you feel like it. You can also call getScores[], >> getCalled[] >> , getPrcntp[] at any time to get the current state of these variables (if >> you need that for further processing).
>> Regards, >> Leonid
>> On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck <mcguyver...@yahoo.com >> >wrote:
>> this code is supposed to randomly select a student from a list, keep >>> track >>> of how many times he/she has been called, and how many answers they have >>> gotten correct.
>>> I am having problems getting the following code to repeat on request: i >>> have tried do loops, while loops, and labels none have worked. please >>> help
>>> this is the code to manipulate the lists created above >>> repeat = "yes"; >>> c = "wrong"; >>> l = Length[name]; >>> n = RandomInteger[l - 1] + 1;
Thanks! I've just noticed something I don't understand, however.
How can displayPanel[] be used outside the makeScorePanel function, when it uses studentInfo, text, buttons, and class -- all of which are local to the Module??
Bobby
On Sat, 23 Jan 2010 14:57:25 -0600, Leonid Shifrin <lsh...@gmail.com> wrote:
>> On Sat, 23 Jan 2010 06:30:56 -0600, Leonid Shifrin <lsh...@gmail.com> >> wrote:
>> Hi Glenn,
>>> You don't need a loop at all, if I understand your goal correctly. What >>> you >>> need is a bit of Dynamic functionality. Hope this will get you started:
>>> You stop when you feel like it. You can also call getScores[], >>> getCalled[] >>> , getPrcntp[] at any time to get the current state of these variables >>> (if >>> you need that for further processing).
>>> Regards, >>> Leonid
>>> On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck <mcguyver...@yahoo.com >>> >wrote:
>>> this code is supposed to randomly select a student from a list, keep >>>> track >>>> of how many times he/she has been called, and how many answers they >>>> have >>>> gotten correct.
>>>> I am having problems getting the following code to repeat on request: >>>> i >>>> have tried do loops, while loops, and labels none have worked. >>>> please >>>> help
>>>> this is the code to manipulate the lists created above >>>> repeat = "yes"; >>>> c = "wrong"; >>>> l = Length[name]; >>>> n = RandomInteger[l - 1] + 1;
this is one of the nice (IMO) features of local variables in Module. By default, they have the attribute Temporary, which means that they are destroyed once the execution exits Module. However, if some global symbols refer to them (like the functions you've mentioned), they are not destroyed, but kept in a symbol table. I use this trick all the time - this allows for example to share local variables (and functions) between several functions, which enables us to implement something similar to classes in OOP (If I remember corerctly, this idea has been fully exploited by Roman Maeder in his implementation of OOP in Mathematica - classes.m package).
Have a look at my post in this thread, if you will
I used this trick to implement traversals of nested directory structure with possible directory skips which can be set at run-time based on a skip function provided by the user.
One of the many other ways to use this which I find useful is to propagate exceptions of a given type without explicitly making the exception tag global. One particular such use I discussed in the thread:
Generally, this is a good option when you want to make an essentially global variable available to a given set of functions but not to others - you make it like
Module[{youvar},
f1[args]:=(body-referring-to-yourvar)
f2[args]:=(body-referring-to-yourvar)
... ];
This is a cheap way to introduce namespaces without making a full-blown package. This allows us to use some of the nice OOP-like stuff (such as private variables / methods) without the need to employ a general OOP machinery (that is, when we just need nice encapsulation but not so much OO-style polymorphism / inheritance). As long as the user never uses variables with a dollar sign in their names (which can possibly collide with those generated by Module), this should be safe enough.
One use of this is to make functions with "memory", similar to static local variables in C functions - some of the function's variables remember their values in between function calls. For example, the following function will produce the next Fibonacci number on demand, and yet it will be as fast as the iterative loop implementation for generation of consecutive Fibonacci numbers (since Module is invoked only once, when the function is defined):
In some cases, this can also improve performance, since some of the local variables in a function can be made "semi-global" by this trick which may eliminate the need of Module invocation in each function call, and the associated overhead:
I generally find this technique very useful, and also I think that it has not been fully exploited (at least I did not fully exploit it yet). For example, you can do nice things when you couple it with Dynamic functionality, since Dynamic happens to work also on these Module-generated variables.
It may however have some garbage-collection issues (I discussed this in the first of the threads I mentioned above), since once you abandon such local variables/functions, they will not be automatically garbage-collected by Mathematica and can soak up memory (I have been bitten by this a few times). Of course, this can be dealt with as well, it's just not automatic.
On Sat, Jan 23, 2010 at 5:18 PM, DrMajorBob <btre...@austin.rr.com> wrote: > Thanks! I've just noticed something I don't understand, however.
> How can displayPanel[] be used outside the makeScorePanel function, when it > uses studentInfo, text, buttons, and class -- all of which are local to the > Module??
> Bobby
> On Sat, 23 Jan 2010 14:57:25 -0600, Leonid Shifrin <lsh...@gmail.com> > wrote:
> Hi Bobby,
>> I agree - your modification makes it more elegant. I particularly liked >> your use of indexed variables and RandomChoice.
>> Cheers, >> Leonid
>> On Sat, Jan 23, 2010 at 12:48 PM, DrMajorBob <btre...@austin.rr.com> >> wrote:
>>> On Sat, 23 Jan 2010 06:30:56 -0600, Leonid Shifrin <lsh...@gmail.com> >>> wrote:
>>> Hi Glenn,
>>>> You don't need a loop at all, if I understand your goal correctly. What >>>> you >>>> need is a bit of Dynamic functionality. Hope this will get you started:
>>>> You stop when you feel like it. You can also call getScores[], >>>> getCalled[] >>>> , getPrcntp[] at any time to get the current state of these variables >>>> (if >>>> you need that for further processing).
>>>> Regards, >>>> Leonid
>>>> On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck <mcguyver...@yahoo.com >>>> >wrote:
>>>> this code is supposed to randomly select a student from a list, keep
>>>>> track >>>>> of how many times he/she has been called, and how many answers they >>>>> have >>>>> gotten correct.
>>>>> I am having problems getting the following code to repeat on request: i >>>>> have tried do loops, while loops, and labels none have worked. please >>>>> help
> this is one of the nice (IMO) features of local variables in Module. By > default, they have the attribute Temporary, which means that they are > destroyed once the execution exits Module. However, if some global > symbols > refer to them (like the functions you've mentioned), they are not > destroyed, > but kept in a symbol table. I use this trick all the time - this allows > for > example to share local variables (and functions) between several > functions, > which enables us to implement something similar to classes in OOP (If I > remember corerctly, this idea has been fully exploited by Roman Maeder in > his implementation of OOP in Mathematica - classes.m package).
> Have a look at my post in this thread, if you will
> I used this trick to implement traversals of nested directory structure > with > possible directory skips which can be set at run-time based on a skip > function provided by the user.
> One of the many other ways to use this which I find useful is to > propagate > exceptions of a given type without explicitly making the exception tag > global. One particular such use I discussed in the thread:
> Generally, this is a good option when you want to make an essentially > global variable available to a given set of functions but not to others - > you make it like
> Module[{youvar},
> f1[args]:=(body-referring-to-yourvar)
> f2[args]:=(body-referring-to-yourvar)
> ... > ];
> This is a cheap way to introduce namespaces without making a full-blown > package. This allows us to use some of the nice OOP-like stuff (such as > private variables / methods) without the need to employ a general OOP > machinery (that is, when we just need nice encapsulation but not so much > OO-style polymorphism / inheritance). As long as the user never uses > variables with a dollar sign in their names (which can possibly collide > with > those generated by Module), this should be safe enough.
> One use of this is to make functions with "memory", similar to static > local > variables in C functions - some of the function's variables remember > their > values in between function calls. For example, the following function > will > produce the next Fibonacci number on demand, and yet it will be as fast > as > the iterative loop implementation for generation of consecutive Fibonacci > numbers (since Module is invoked only once, when the function is > defined):
> In some cases, this can also improve performance, since some of the local > variables in a function can be made "semi-global" by this trick which may > eliminate the need of Module invocation in each function call, and the > associated overhead:
> I generally find this technique very useful, and also I think that it has > not been fully exploited (at least I did not fully exploit it yet). For > example, you can do nice things when you couple it with Dynamic > functionality, since Dynamic happens to work also on these > Module-generated > variables.
> It may however have some garbage-collection issues (I discussed this in > the > first of the threads I mentioned above), since once you abandon such > local > variables/functions, they will not be automatically garbage-collected by > Mathematica and can soak up memory (I have been bitten by this a few > times). > Of course, this can be dealt with as well, it's just not automatic.
> Regards, > Leonid
> On Sat, Jan 23, 2010 at 5:18 PM, DrMajorBob <btre...@austin.rr.com> > wrote:
>> Thanks! I've just noticed something I don't understand, however.
>> How can displayPanel[] be used outside the makeScorePanel function, >> when it >> uses studentInfo, text, buttons, and class -- all of which are local to >> the >> Module??
>> Bobby
>> On Sat, 23 Jan 2010 14:57:25 -0600, Leonid Shifrin <lsh...@gmail.com> >> wrote:
>> Hi Bobby,
>>> I agree - your modification makes it more elegant. I particularly >>> liked >>> your use of indexed variables and RandomChoice.
>>> Cheers, >>> Leonid
>>> On Sat, Jan 23, 2010 at 12:48 PM, DrMajorBob <btre...@austin.rr.com> >>> wrote:
>>>> On Sat, 23 Jan 2010 06:30:56 -0600, Leonid Shifrin <lsh...@gmail.com> >>>> wrote:
>>>> Hi Glenn,
>>>>> You don't need a loop at all, if I understand your goal correctly. >>>>> What >>>>> you >>>>> need is a bit of Dynamic functionality. Hope this will get you >>>>> started:
>>>>> You stop when you feel like it. You can also call getScores[], >>>>> getCalled[] >>>>> , getPrcntp[] at any time to get the current state of these >>>>> variables >>>>> (if >>>>> you need that for further processing).
>>>>> Regards, >>>>> Leonid
>>>>> On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck >>>>> <mcguyver...@yahoo.com >>>>> >wrote:
>>>>> this code is supposed to randomly select a student from a list, keep
>>>>>> track >>>>>> of how many times he/she has been called, and how many answers they >>>>>> have >>>>>> gotten correct.
>>>>>> I am having problems getting the following code to repeat on >>>>>> request: i >>>>>> have tried do loops, while loops, and labels
I had no doubt you'd like this one. I really hope that this feature will stay in later versions. Besides, changes to this seem unlikely because this is a fundamental mechanism behind scoping in Module, and it has been this way for a very long time (I don't know since which version but I wouldn't be surprised if it was there already in version 1).
On Sun, Jan 24, 2010 at 10:51 AM, DrMajorBob <btre...@austin.rr.com> wrote: > Huh! That's an amazing little secret trick you have, there!
> I wonder, though, if it could go away in a new version.
> Bobby
> On Sun, 24 Jan 2010 04:11:07 -0600, Leonid Shifrin <lsh...@gmail.com> > wrote:
> Bobby,
>> this is one of the nice (IMO) features of local variables in Module. By >> default, they have the attribute Temporary, which means that they are >> destroyed once the execution exits Module. However, if some global symbols >> refer to them (like the functions you've mentioned), they are not >> destroyed, >> but kept in a symbol table. I use this trick all the time - this allows >> for >> example to share local variables (and functions) between several >> functions, >> which enables us to implement something similar to classes in OOP (If I >> remember corerctly, this idea has been fully exploited by Roman Maeder in >> his implementation of OOP in Mathematica - classes.m package).
>> Have a look at my post in this thread, if you will
>> I used this trick to implement traversals of nested directory structure >> with >> possible directory skips which can be set at run-time based on a skip >> function provided by the user.
>> One of the many other ways to use this which I find useful is to propagate >> exceptions of a given type without explicitly making the exception tag >> global. One particular such use I discussed in the thread:
>> Generally, this is a good option when you want to make an essentially >> global variable available to a given set of functions but not to others - >> you make it like
>> Module[{youvar},
>> f1[args]:=(body-referring-to-yourvar)
>> f2[args]:=(body-referring-to-yourvar)
>> ... >> ];
>> This is a cheap way to introduce namespaces without making a full-blown >> package. This allows us to use some of the nice OOP-like stuff (such as >> private variables / methods) without the need to employ a general OOP >> machinery (that is, when we just need nice encapsulation but not so much >> OO-style polymorphism / inheritance). As long as the user never uses >> variables with a dollar sign in their names (which can possibly collide >> with >> those generated by Module), this should be safe enough.
>> One use of this is to make functions with "memory", similar to static >> local >> variables in C functions - some of the function's variables remember their >> values in between function calls. For example, the following function will >> produce the next Fibonacci number on demand, and yet it will be as fast as >> the iterative loop implementation for generation of consecutive Fibonacci >> numbers (since Module is invoked only once, when the function is defined):
>> In some cases, this can also improve performance, since some of the local >> variables in a function can be made "semi-global" by this trick which may >> eliminate the need of Module invocation in each function call, and the >> associated overhead:
>> I generally find this technique very useful, and also I think that it has >> not been fully exploited (at least I did not fully exploit it yet). For >> example, you can do nice things when you couple it with Dynamic >> functionality, since Dynamic happens to work also on these >> Module-generated >> variables.
>> It may however have some garbage-collection issues (I discussed this in >> the >> first of the threads I mentioned above), since once you abandon such local >> variables/functions, they will not be automatically garbage-collected by >> Mathematica and can soak up memory (I have been bitten by this a few >> times). >> Of course, this can be dealt with as well, it's just not automatic.
>> Regards, >> Leonid
>> On Sat, Jan 23, 2010 at 5:18 PM, DrMajorBob <btre...@austin.rr.com> >> wrote:
>> Thanks! I've just noticed something I don't understand, however.
>>> How can displayPanel[] be used outside the makeScorePanel function, when >>> it >>> uses studentInfo, text, buttons, and class -- all of which are local to >>> the >>> Module??
>>> Bobby
>>> On Sat, 23 Jan 2010 14:57:25 -0600, Leonid Shifrin <lsh...@gmail.com> >>> wrote:
>>> Hi Bobby,
>>>> I agree - your modification makes it more elegant. I particularly liked >>>> your use of indexed variables and RandomChoice.
>>>> Cheers, >>>> Leonid
>>>> On Sat, Jan 23, 2010 at 12:48 PM, DrMajorBob <btre...@austin.rr.com> >>>> wrote:
>>>>> On Sat, 23 Jan 2010 06:30:56 -0600, Leonid Shifrin <lsh...@gmail.com> >>>>> wrote:
>>>>> Hi Glenn,
>>>>>> You don't need a loop at all, if I understand your goal correctly. >>>>>> What >>>>>> you >>>>>> need is a bit of Dynamic functionality. Hope this will get you >>>>>> started:
Actually there was no Module in version 1. (e.g. see the documentation for
> Module). Module was introduced in Version 2. Version 1 had only Block.
Yes indeed. The moment I read your reply I recalled having read about it somewhere (Wagner's book perhaps) - also that one of the main reasons for its appearance was that Block is a dynamic scoping construct and lots of people were confused by the name and using it as a lexical scoping construct instead, which of course is very error-prone.
> Andrzej Kozlowski
> (Nice tricks, by the way. I have know about some of them for a long time > but others are new to me.)
Well, thanks. Somehow all of them came out as results of my experiments with Mathematica, at the times when I did not have Maeder's books or other sources of information on this topic. I actually think that I would not have come to them had I known more about Mathematica at the time.
I have been looking for these construct for years, this will simplify and clean a lot some of my co-routines (cross invoking routines) and similar pieces of code.
Up to now, I have overcome the gap by reserving some global variables to simulate _local variables with persistent values between calls_. A rather weak and error prone programming technique.
I have been tempted to post many times to ask for a canonical and straightforward solution, and your finding seems to be the safest and natural way. I hope WRI will document and leave the feature as it is now.
They clearly should, since it sounds as being something very very powerful; and I do not understand why it has not been clearly documented yet.
-----Original Message----- From: Leonid Shifrin [mailto:lsh...@gmail.com] Sent: Monday, January 25, 2010 11:06 AM Subject: Re: Re: looping
Bobby,
this is one of the nice (IMO) features of local variables in Module. By default, they have the attribute Temporary, which means that they are destroyed once the execution exits Module. However, if some global symbols refer to them (like the functions you've mentioned), they are not destroyed, but kept in a symbol table. I use this trick all the time - this allows for example to share local variables (and functions) between several functions, which enables us to implement something similar to classes in OOP (If I remember corerctly, this idea has been fully exploited by Roman Maeder in his implementation of OOP in Mathematica - classes.m package).
Have a look at my post in this thread, if you will
I used this trick to implement traversals of nested directory structure with possible directory skips which can be set at run-time based on a skip function provided by the user.
One of the many other ways to use this which I find useful is to propagate exceptions of a given type without explicitly making the exception tag global. One particular such use I discussed in the thread:
Generally, this is a good option when you want to make an essentially global variable available to a given set of functions but not to others - you make it like
Module[{youvar},
f1[args]:=(body-referring-to-yourvar)
f2[args]:=(body-referring-to-yourvar)
... ];
This is a cheap way to introduce namespaces without making a full-blown package. This allows us to use some of the nice OOP-like stuff (such as private variables / methods) without the need to employ a general OOP machinery (that is, when we just need nice encapsulation but not so much OO-style polymorphism / inheritance). As long as the user never uses variables with a dollar sign in their names (which can possibly collide with those generated by Module), this should be safe enough.
One use of this is to make functions with "memory", similar to static local variables in C functions - some of the function's variables remember their values in between function calls. For example, the following function will produce the next Fibonacci number on demand, and yet it will be as fast as the iterative loop implementation for generation of consecutive Fibonacci numbers (since Module is invoked only once, when the function is defined):
In some cases, this can also improve performance, since some of the local variables in a function can be made "semi-global" by this trick which may eliminate the need of Module invocation in each function call, and the associated overhead:
I generally find this technique very useful, and also I think that it has not been fully exploited (at least I did not fully exploit it yet). For example, you can do nice things when you couple it with Dynamic functionality, since Dynamic happens to work also on these Module-generated variables.
It may however have some garbage-collection issues (I discussed this in the first of the threads I mentioned above), since once you abandon such local variables/functions, they will not be automatically garbage-collected by Mathematica and can soak up memory (I have been bitten by this a few times). Of course, this can be dealt with as well, it's just not automatic.
Regards, Leonid
On Sat, Jan 23, 2010 at 5:18 PM, DrMajorBob <btre...@austin.rr.com> wrote:
> Thanks! I've just noticed something I don't understand, however.
> How can displayPanel[] be used outside the makeScorePanel function, when it > uses studentInfo, text, buttons, and class -- all of which are local to the > Module??
> Bobby
> On Sat, 23 Jan 2010 14:57:25 -0600, Leonid Shifrin <lsh...@gmail.com> > wrote:
> Hi Bobby,
>> I agree - your modification makes it more elegant. I particularly liked >> your use of indexed variables and RandomChoice.
>> Cheers, >> Leonid
>> On Sat, Jan 23, 2010 at 12:48 PM, DrMajorBob <btre...@austin.rr.com> >> wrote:
>>> On Sat, 23 Jan 2010 06:30:56 -0600, Leonid Shifrin <lsh...@gmail.com> >>> wrote:
>>> Hi Glenn,
>>>> You don't need a loop at all, if I understand your goal correctly. What >>>> you >>>> need is a bit of Dynamic functionality. Hope this will get you started:
>>>> You stop when you feel like it. You can also call getScores[], >>>> getCalled[] >>>> , getPrcntp[] at any time to get the current state of these variables >>>> (if >>>> you need that for further processing).
>>>> Regards, >>>> Leonid
>>>> On Thu, Jan 21, 2010 at 12:55 PM, glenn kuhaneck <mcguyver...@yahoo.com >>>> >wrote:
>>>> this code is supposed to randomly select a student from a list, keep
> Besides, changes to this seem unlikely because this > is a fundamental mechanism behind scoping in Module, and it has been this > way for a very long time (I don't know since which version but I wouldn't be > surprised if it was there already in version 1).
Actually there was no Module in version 1. (e.g. see the documentation for Module). Module was introduced in Version 2. Version 1 had only Block.
Andrzej Kozlowski
(Nice tricks, by the way. I have know about some of them for a long time but others are new to me.)
Andrzej Kozlowski wrote: > On 25 Jan 2010, at 11:08, Leonid Shifrin wrote:
>> Besides, changes to this seem unlikely because this >> is a fundamental mechanism behind scoping in Module, and it has been this >> way for a very long time (I don't know since which version but I wouldn't be >> surprised if it was there already in version 1).
> Actually there was no Module in version 1. (e.g. see the documentation for Module). Module was introduced in Version 2. Version 1 had only Block.
> Andrzej Kozlowski
> (Nice tricks, by the way. I have know about some of them for a long time but others are new to me.)
Oh dear. As I pointed out in 1992, the Module mechanism is flawed. Module makes up names,
as you can see by g1[x_]:=Module[{r}, r]
with dollar signs. e.g. I got r$592 one time.
The standard advice is you can avoid conflict yourself by not using names with dollar signs in them.
Unfortunately, if you have several independent programs perhaps written by different people and they each generate persistent names via Module[{...,r...} ...] and you load them into the same system then THEY can conflict.
> Andrzej Kozlowski wrote: >> On 25 Jan 2010, at 11:08, Leonid Shifrin wrote: >>> Besides, changes to this seem unlikely because this >>> is a fundamental mechanism behind scoping in Module, and it has been = this >>> way for a very long time (I don't know since which version but I = wouldn't be >>> surprised if it was there already in version 1). >> Actually there was no Module in version 1. (e.g. see the =
documentation for Module). Module was introduced in Version 2. Version 1 = had only Block.
>> Andrzej Kozlowski >> (Nice tricks, by the way. I have know about some of them for a long =
time but others are new to me.)
-------
> Unfortunately, if you have several independent programs perhaps =
written by different people and they each generate persistent names via = Module[{...,r...} ...] and you load them into the same system then THEY = can conflict.
> run it a bunch of times. Save g1 and A in file f1 > start up a new system > define > g2[x_]:=Module[{r},If[NumberQ[A[r]],Print[r],A[r]=1]]
> run it a bunch of times. Save g2 and A in file f2. > start up a new system
> load files f1 and f2.
> the behavior of g1 and g2 will be, so far as I can tell, dependent on > the (random?) setting of some inaccessible counter in Mathematica.
This is very good, but still I think it falls short of the quality of an = earlier example of why Richard would "shy away from a presentation that = required the reader to own a free Mathematica player". I mean that he = might want to write "a paper whose topic was the Mathematica Player = itself".
I think if not exactly a world record, that post was a record of sorts = for this forum. This one, while still pretty good, is not really keeping = up with that standard.
I do hope some day instead of warning us of the possible problems that = might be caused by his imaginative though somewhat contrived examples of = "possible" user behaviour, Richard tries to produce an actual, "real = life" example. Perhaps he could start by trying to generate this = "possible conflict" by following the procedure he has so kindly produced = as a warning to all of us. With luck this will keep him occupied for a = while...
>> (RJF) the behavior of g1 and g2 will be, so far as I can tell, dependent on >> the (random?) setting of some inaccessible counter in Mathematica.
....
In private mail, I was told that this counter is not inaccessible, but has the name $ModuleNumber. This still does not correct the problem, and the rest of my comment holds.
> I do hope some day instead of warning us of the possible problems
Design errors cause possible problems. These are identified by people who then try to correct them. Apparently AK would prefer that programs be run (say as a control system for a laboratory experiment? a medical treatment with x-rays? Safety for a nuclear power plant? Aircraft control?) and then only when an actual "real-life" example causes problems should we go back and correct the design.
After all, what are the chances that a pseudo-random 32-bit number generator would hit a previously specified secret number? Pretty unlikely, right? Oh one chance in 2^32 or so. How long would it take a modern computer to run through 2^32 random numbers? Maybe less than a minute That's one of the nice things about computers. They do arithmetic rapidly.
> might be caused by his imaginative though somewhat contrived examples of > "possible" user behaviour, Richard tries to produce an actual, "real > life" example. Perhaps he could start by trying to generate this > "possible conflict" by following the procedure he has so kindly produced > as a warning to all of us. With luck this will keep him occupied for a > while...
> Apparently AK would prefer that programs be run (say as a control
system for a laboratory experiment? a medical treatment with x-rays? Safety for a nuclear power plant? Aircraft control?) and then only when an actual "real-life" example causes problems should we go back and correct the design.
Sigh... I guess I should be flattered at the influence that I obviously must have on the spread of he dreadful cancer (Mathematica), which threatens mankind with untold disasters unless stopped by RJF's valiant efforts to which he devotes so much of his time (payed for by California tax payers?) but it's all in vain - we are all doomed anyway. The worst Mathematica can do is speed it up a little.
So while the going is good why be so depressing? How about letting us hear some more "cheerful facts" as in:
I am the very pattern of a modern major-general : I've information vegetable, animal, and mineral ; I know the kings of England, and I quote the fights historical. From Marathon to Waterloo, in order categorical ; I'm very well acquainted, too, with matters mathematical I understand equations, both the simple and quadratical ; About binomial theorem I'm teeming with a lot of news With many cheerful facts about the square of the hypotenuse ; (Joyfully.) With many cheerful facts about the square of the hypotenuse.
Of course you should replace major-general with "professor of computer science" and make other suitable changes.
Richard Fateman wrote: > Andrzej Kozlowski wrote: >> On 25 Jan 2010, at 11:08, Leonid Shifrin wrote:
>>> Besides, changes to this seem unlikely because this >>> is a fundamental mechanism behind scoping in Module, and it has been this >>> way for a very long time (I don't know since which version but I wouldn't be >>> surprised if it was there already in version 1). >> Actually there was no Module in version 1. (e.g. see the documentation for Module). Module was introduced in Version 2. Version 1 had only Block.
>> Andrzej Kozlowski
>> (Nice tricks, by the way. I have know about some of them for a long time but others are new to me.)
> Oh dear. As I pointed out in 1992, the Module mechanism is flawed. > Module makes up names,
> as you can see by g1[x_]:=Module[{r}, r]
> with dollar signs. e.g. I got r$592 one time.
> The standard advice is you can avoid conflict yourself by not using > names with dollar signs in them.
> Unfortunately, if you have several independent programs perhaps > written by different people and they each generate persistent names via > Module[{...,r...} ...] and you load them into the same system then > THEY can conflict.
> run it a bunch of times. Save g1 and A in file f1 > start up a new system > define > g2[x_]:=Module[{r},If[NumberQ[A[r]],Print[r],A[r]=1]]
> run it a bunch of times. Save g2 and A in file f2. > start up a new system
> load files f1 and f2.
> the behavior of g1 and g2 will be, so far as I can tell, dependent on > the (random?) setting of some inaccessible counter in Mathematica.
Clearly, Module should not be used to generate names that will be saved and loaded into another Mathematica session. If you REALLY need several people to independent people to generate such names without getting clashes, it might be better to generate names based on AbsoluteTime and $UserName/$LicenseID/$MachineID as appropriate.
To describe the Module mechanism as 'flawed' because you can't use it in this way, seems totally unreasonable - akin to describing real arithmetic as 'flawed' because it can't represent Sqrt[-1]!
One of the nice features of Module, is that the method of localising names is totally explicit - so that it is easy to work out what is going on is subtle cases.
> Sigh... I guess I should be flattered at the influence that I obviously > must have on the spread of he dreadful cancer (Mathematica),
You could guess that, but my guess is that your sarcasm detector needs recalibration.
... Gilbert and Sullivan ... quote from the Major-General Song..
> Of course you should replace major-general with "professor of computer > science" and make other suitable changes.
Hm, I see Stephen Wolfram (perhaps played by David Ogden Stiers) and especially Wolfram|Alpha in this. He has the accent, and the program fits the description.
> To describe the Module mechanism as 'flawed' because you can't use it in > this way, seems totally unreasonable - akin to describing real > arithmetic as 'flawed' because it can't represent Sqrt[-1]!
Except that other programming languages provide the same facility (lexical scope) while not having the same problem. That is, there is the ordinary way of implementing lexical scope, not the Mathematica way.
> One of the nice features of Module, is that the method of localising > names is totally explicit - so that it is easy to work out what is going > on is subtle cases.
Mathematica's implementation is, I think, based on someone's reading of an explanation of lexical scope. Perhaps, "You can think of L.S. as a kind of renaming". But without reading the next sentence, which might be "but of course it is not implemented that way".
I agree with your statement -- that looking at the strange renaming it is possible to explain some phenomena that you might find puzzling. But so many things having to do with scope in Mathematica are, at some level, potentially puzzling, that this is a drop in the bucket. E.g. when do names get bound during pattern matching? What is the real value of something which is evaluated any number of times until it has no remaining names, so that x=x+1 assigned to x, 255+Hold[1+x], etc.
And proper lexical scope implementation is not so hard, I think. Even given Mathematica semantics.
On Jan 30, 5:13 am, Richard Fateman <fate...@cs.berkeley.edu> wrote:
> David Bailey wrote:
> ...
> > To describe the Module mechanism as 'flawed' because you can't use it in > > this way, seems totally unreasonable - akin to describing real > > arithmetic as 'flawed' because it can't represent Sqrt[-1]!
> Except that other programming languages provide the same facility > (lexical scope) while not having the same problem.
You like to "strain out gnats and swallow camels", don't you? Any mechanism can be abused. In this case, inadvertent abuse seems very unlikely, while Leonid has demonstrated productive use (very cool). Therefore, the implementation your ideology demands would have a real problem.
> That is, there is > the ordinary way of implementing lexical scope, not the Mathematica way.
So? Mathematica does it better, enabling you to single out little bits of the state and make them persistent. It's much like the "continuations" of other languages, except it's:
1. Better targeted.
2. More transparent.
Continuations are an obfuscated, undisciplined, "shotgun" mechanism compared to what Mathematica offers here (yes, I know, they are beloved by CS sacerdotes).
> > One of the nice features of Module, is that the method of localising > > names is totally explicit - so that it is easy to work out what is going > > on is subtle cases.
> Mathematica's implementation is, I think, based on someone's reading of > an explanation of lexical scope. Perhaps, "You can think of L.S. as a > kind of renaming". But without reading the next sentence, which might > be "but of course it is not implemented that way".
It doesn't match your ideology. I doubt many Mathematica users share that ideology.
> I agree with your statement -- that looking at the strange renaming it > is possible to explain some phenomena that you might find puzzling.
It's only strange because it doesn't match your ideology.
> But > so many things having to do with scope in Mathematica are, at some > level, potentially puzzling, that this is a drop in the bucket. E.g. > when do names get bound during pattern matching? What is the real value > of something which is evaluated any number of times until it has no > remaining names, so that x=x+1 assigned > to x, 255+Hold[1+x], etc.
> And proper lexical scope implementation is not so hard, I think. Even > given Mathematica semantics.
What you call proper I call less capable. I may be using Leonid's techniques in the future.
> What you call proper I call less capable. I may be using Leonid's > techniques in the future.
Less capable in that Mathematica is capable of errors that a correct implementation could not commit. I think the only "plus" is that the renaming allows one to use the same debugging tools some of the time.
"Continuations" which you think are too esoteric, is an underlying implementation technique that can, and has, been used to provide remarkable facilities, some of which you probably would like. Like resuming the computation of terms in a Taylor series when you decide you need more. Or resuming an iteration after exiting with an error indication. Or implementing search with backtracking in a trivial fashion. And other ideas that have clear applications in computer algebra systems.