Re: How to delay action of ...[[i]] (Part[...,i])
- To: mathgroup at smc.vnet.net
- Subject: [mg112300] Re: How to delay action of ...[[i]] (Part[...,i])
- From: Scott Graham <greylander at gmail.com>
- Date: Wed, 8 Sep 2010 00:59:26 -0400 (EDT)
Hi Leonid, Thanks for you insights. Hopefully I have not inadvertently started a great debate. I was speaking loosely when referring to the "core" language. I merely refer to functionality is defined in Mathematica "by default", whether part of the kernel or defined at a higher level. It may well be that NDSolve is one of the few places that the issue of indexing lists before they are instantiated is likely to come up. But I imagine more than a few new Mathematica users may come to it initially to solve differential equations numerically (people coming from a physics background, for example), and the counter-intuitive manner in which indexing works is likely to frustrate them and make them go back to using Fortran or C before they have taken the time to understand what I have just figured out for myself (I happen to be very stubborn... and I happened to have some free time). Also people coming from a more traditional programming background will have certain intuitions regarding indexing of lists and arrays that will lead to confusion if and when what looks to them like an array index, [[]], surprisingly dismembers an expression. At the very least, an additional paragraph or two of explanation in the documentation for List[], Part[], and NDSolve[], perhaps in the "Possible Issues" section, would go a long way. Cheers, Scott On Tue, Sep 7, 2010 at 10:54 AM, Leonid Shifrin <lshifr at gmail.com> wrote: > > > On Tue, Sep 7, 2010 at 9:59 AM, Greylander <greylander at gmail.com> wrote: > >> I have answered my own question! And understand a bit more how to >> 'think' in Mathematica... >> >> The problem is that Part[[]] acts on any expression. What I have >> finally figured out is that I need a version of part (or a version of >> [[...]]) that acts *only* on lists (i.e. expressions with "List" >> head), and searching and exploring the documentation, I eventually >> learned how to do that. This will have exactly the desired result. >> >> Here is what I did: >> >> VPart[expr_List,k_] :=Part[expr,k] >> >> And I also define subscripting in an expression to invoke VPart[]: >> >> expr_List[Ctrl+-]k_ :=VPart[expr,k] >> >> Above the [Ctrl+-] means literally press the Ctrl key and the - >> (minus) key, so that "k_" will then be a subscript. >> >> Now I have one remaining question: why is there not something like >> this already defined in the core of Mathematica? It seems obvious (to >> me) that one would want a version of Part[] (element selection) >> restricted to List expressions only. >> > > To my mind, the kernel should contain either functionality which is not > easily reproduced with top-level Mathematica code (either because of > efficiency > or because the rest of the language is not sufficient to reproduce the > feature > in a satisfactory way), or functions which are so frequently used in > practice that the > convenience of having them as single commands overweights the conceptual > cost > of extending the kernel. Functions like Most and Rest I think can be > examples of the latter. > > As far as I can tell, your case with Part restricted on lists does not fall > into > either category. Restricted patterns give a powerful mechanism to define > functions > only on certain types of arguments - this is just what you used in your > implementation. > OTOH, at least in my experience, problems with Part applied to general > structures > when intended to work only on lists are pretty rare and I always treat > them as > programming mistakes on my side. And having Part work universally on > general > Mathematica expressions has major advantages in terms of simplicity and > consistency > of the language, which I think greatly overweight occasional puzzling > situations like the > one you encountered. > > In fact, one of the main reasons for my appreciation of Mathematica > language is that > it does expose enough of its internals to the user that in most cases one > can create > custom functions for whatever purposes one needs, and work around the lack > of > any particular function in the kernel, just as you did it here. But this > kind of extensibility > stems from the small number of "orthogonal" general functions (like Part, > or functions > related to patterns, such as Pattern, ReplaceAll, etc) much more than it > would from a > huge API for all tasks one can possibly think of. > > Regards, > Leonid > > > > >> >> >> >> >> On Sep 6, 4:13 am, Greylander <greylan... at gmail.com> wrote: >> > Consider the following toy example: >> > >> > in> goo[v_] := v.{1, 1}*(3 v) >> > in> foo[k_][v_] := goo[v] [[k]] >> > >> > in> goo[nnn] >> > out> 3 nnn nnn.{1, 1} >> > >> > in>foo[1][{2, 3}] >> > out>30 >> > >> > in> foo[2][nnn] >> > out>nnn >> > >> > Notice how in this last output, because the parameter nnn is >> > undefined, [[k]] ends up acting on the structure of the expression in >> > goo, but the intuitive behavior would be for evaluation of [[k]] to >> > also be delayed. The output I would like to see is: >> > >> > in>foo[2][nnn] >> > out> ( 3 nnn nnn.{1,1} ) [[2]] >> > in> nnn = {4,5} >> > % >> > out> 135 >> > >> > But of course it does not happen that way. >> > >> > I realize that Mathematica is a specification rather than procedural >> > language, but surely there is some reasonably elegant way to to delay >> > the effect of [[2]] above so it acts on the eventual result of >> > goo[nnn] and not on the structure of the expression. >> > >> > This is related to my other questions about using NDSolve on dependent >> > variables that have arbitrary structure and therefore require some >> > kind of indexing. >> > >> > There must some basic aspect of the Mathematica language that I have >> > missed which makes indexing and list manipulation more intuitive. (I >> > hope!) >> > >> > Anyone have any insights? >> >> >> >