Re: Accesing structures data (getting lengthy!)
- From: Doug Schwarz <see@xxxxxxxxxxxxxxxxxxx>
- Date: Thu, 11 Aug 2005 16:35:49 GMT
Scott Seidman wrote:
Christopher Hulbert <cchgroupmail@xxxxxxxxx> wrote in
news:67165BB72D9E93C9E408412DDB7E3B8C@xxxxxxxxxxxxxxxxxxx:
I don't want to start the argument up again, but I still don't see how
a "with" keyword is so much better. According to the syntax you
posted earlier, you have to type the leading . anyways, is a leading
w. really that much more inconvient or ugly?
It's not really an argument. I happen to have a task at hand that would profit from this construct. (1) is the way I used to do things, and it didn't really work for me. Now, I float the deep structure to the top, and it works a tad better for me. I have an easier time prototyping and coding, and in my situation it's easier, but its really a kludge, and suffers from some of the same problems that your syntax (1) does, which I'll describe below. If the "with" construct existed, I would use that, and I wouldn't feel bad about it, like I do when floating a deep structure to the top.
I also know that sometimes I go out of my way to avoid using structures with names and organizations that make perfect sense, simply because I don't want to have to type the whole damn thing every time I want to use anything in them for any reason.
Consider two syntaxes (1) a matlab way (2) the "with" keyword way
(1) w=my.very.nested.structure;
w.this w.that w.whatever
w=my.very.nested.structure2; w.this w.that w.whatever
(2) with my.very.nested.structure;
.this .that .whatever
with my.very.nested.structure2; .this .that .whatever
Are they really that different????
I think I can convince you that they are, if you'll excuse my late- afternoon verbosity.
They're different from the readability point of view. In (1), you've created a temporary variable that has no meaningful name (assuming that if its more than a few characters, there's a level of tediousness). My prototyping work from the command line is hard enough to make sense of more than two minutes after I've typed it right now--I don't need to add to it by creating a fruit salad of placeholders and dummy variables. When you're working from the keyboard in a prototyping sort of way, it's tough to remember just what you were using 'w' for (or maybe I was using 'a' as my meaningless place holder??....). It's tough to go back through your history (or your editing enviroment) to pick up "w=" as the assignment statement just won't stand out amongst all the other assignment statements.
(2), however, is quite readable. It doesn't create a fruit salad of meaningless dummy variables that you have to keep track of. "with" is comparitively easy to pick out of a long, boring, command line history, and would certainly be highlighted in any IDE-type editor worth its salt. When you click on or mouse over a structure that starts with a period, the editor can highlight the currently active "with" line, or pop it up as a "tip". Maybe from the command line, simply typing "with" with no arguments would provide the currently active stucture.
They're clearly very different from a memory point of view, with (1) taking up, worst case, twice the memory with respect to the arrays of interest (certainly if you change all the arrays, copies would be created). While the other points can be considered mere preferences, I don't think you can argue with this one.
The biggest and most annoying aspect of using (1) is that you are acting on a mere copy of the object you want to act on. When you act on an object using (2), you're using the real deal. When using (1), you have to remember to go back and fix up your original structure. I'm sure I can find extremely creative ways to have this one bite me on the ass--
ways that are hard to debug. Putting the placeholder back into the original, for some reason, wraps me up in knots. Think about this:
tryme.a.a1=1 tryme.a.a2=2 tryme.a.a3=3 w=tryme.a w.a1=5 tryme.a=w %<=====This seems somehow nasty!!!! tryme.a
Acting in the forward direction, from 'tryme' to 'w' is pretty natural, but going in the backward direction, for some reason, doesn't seem natural to me at all, and for some reason, I have to think about it every time I do it. It seems really easy to screw up your whole structure just by leaving out the last "a", and that seems like something I would do all too often (like typing "clear" instead of "close", a habit which I've managed to break without even overloading clear!), especially when structures run particularly deep. Sometimes, I even feel the need create yet another extra copy of the original structure, in case I mess it up in this tricky step.
In fact, now that I'm thinking about it, using method (1), it's ABSOLUTELY CRITICAL to do all your work in w, and then bring it back to tryme.a. If you accidentally do anything to tryme.a, you will lose all your changes when you copy w to tryme.a!!! Using construct (2), this situation never arises. This is a hard one to argue away, as well. (1) and (2) are looking more and more different! Note that this wouldn't be a problem if there were a way to ALIAS or EQUIV w to tryme.a, or we had some sort of #define preprocessor, but those don't exist. You could also bring w to tryme.a in a loop, element by element, and not lose any additions you've made to tryme.a, but you would still lose modifications of anything that existed when w was created. Also, if we had to restore tryme.a with a nasty loop, alot of the appeal of (1) goes away.
Your argument against the "with" statement seemed to be centered around the idea that syntax (1) made it fairly unnecessary. So, now that I've pointed out some problems inherent to using syntax (1), we should go back and look at problems with syntax (2).
The whole "with" concept seems relatively straightforward to implement, and shouldn't interfere with the parser too much. It would create errors that might be harder to trace if people accidentally put a space in their structure names before a period, but that creates an error already. It's not like the zero-referenced array request that a bunch of serious signal processors militantly demanded, as it wouldn't touch built in functions, or any other functionality, for that matter it shouldn't effect any old code, so long as there are no variables called "with". There might even be exciting unforseen benefits--seems like it would be doable to create separate namespaces in the base, for example.
In a function, I see no real problems. However, from the command line, constructs like (2) usually get evaluated after the "end" statement is typed, but "with" really wouldn't be able to work this way-- There may be some problems associated with a "sticky with" at the command line (but nowhere near the potential problems and misunderstandings caused by using "cell" with two completely different meanings). Searching for the construct usage, and having to parse out variable names that start with a period, might add unacceptable loads to the parser, and might somehow mess up the grammar. I can't speak to implementation by the good folks at Mathworks--that really isn't my bag--but there might be implementation problems that make the whole deal unworkable.
I hope you all haven't forgotten about this discussion, but I've been thinking about this a bit and have come up with something that addresses at least some of Scott's concerns.
-------------------------- with.m -------------------------- function with(varargin) %with: Use a specified field of a structure. % % The WITH function allows you to use a specified field of a structure % without having to specify the whole structure field. For example, % suppose you need to increment several counters nested deep inside % a structure: % % data.field1.field2.counter1 = 1; % data.field1.field2.counter2 = 1; % % To increment them you would need to use % % data.field1.field2.counter1 = data.field1.field2.counter1 + 1; % data.field1.field2.counter2 = data.field1.field2.counter2 + 1; % % which is mistake-prone, takes up a lot of space, and is hard to read. % Using WITH you can write % % with w = data.field1.field2 % w.counter1 = w.counter1 + 1; % w.counter2 = w.counter2 + 1; % with end % % You can use any temporary variable name ('w' in the example above) and % spaces in the with statement do not matter.
% Copyright 2005 by Douglas M. Schwarz
% Warning: this is a bit of a hack since it uses evalin.
persistent struc var
if nargin == 1 & strcmpi(varargin{1}, 'end')
evalin('caller', sprintf('%s = %s; clear %s', struc, var, var))
munlock
else
arg = [varargin{:}];
[var, remainder] = strtok(arg, '= ;');
struc = strtok(remainder, '= ;');
evalin('caller', sprintf('%s = %s; %s = [];', var, struc, struc))
mlock
end------------------------ end with.m ------------------------
In particular, Scott's example:
tryme.a.a1=1 tryme.a.a2=2 tryme.a.a3=3 w=tryme.a w.a1=5 tryme.a=w %<=====This seems somehow nasty!!!! tryme.a
becomes
tryme.a.a1=1
tryme.a.a2=2
tryme.a.a3=3
with w=tryme.a
w.a1=5
with end
tryme.aAlso, the issue of memory is addressed (sorry for the pun) by clearing the structure field so there is only ever one copy of the data around. Esentially,
with w = tryme.a
does this:
w = tryme.a tryme.a = [];
and then
with end
does
tryme.a = w; clear w
but you don't have to keep track of it yourself. Obviously, you would not want to do anything with tryme.a inside of this new 'with' block.
Any comments?
-- Doug Schwarz dmschwarz&urgrad,rochester,edu Make obvious changes to get real email address. .
- Follow-Ups:
- Re: Accesing structures data (getting lengthy!)
- From: Scott Seidman
- Re: Accesing structures data (getting lengthy!)
- Prev by Date: Re: Working with arrays of different datatypes
- Next by Date: Re: Working with arrays of different datatypes
- Previous by thread: Eignvalues/eigenfunctions of Sturm-Liouville operator
- Next by thread: Re: Accesing structures data (getting lengthy!)
- Index(es):
Relevant Pages
|