Oops, it looks like Henry beat me to the punch, and that I had overlooked his message.
Oh well, repetition can sometimes be a good thing. Thanks, -- Raul On Sat, Oct 1, 2016 at 12:07 PM, Henry Rich <[email protected]> wrote: > Yep, that's how it works. Temporary results can be operated on in-place. > Also names that will be the target of an assignment: > > y =: x (] , f) y > > can safely append in-place to y, because the old value of y is about to be > destroyed. > > An application like the Longest Ascending Subsequence problem (the topic of > recent discussion here) could not possibly be implemented in tacit code in > less than quadratic time without in-placing; now it can. > > Currently supported for: > > x , y > , y > x m} y > x u} y > x v0`v1`v2} y > u/ y > atomic verbs (+ - * etc) on singletons only > u^:n and u^:v when n/v produces atomic 0 or 1 > hook fork @ @: & &: &. &.: @. " > > > > One correction: > > In-place assignment did not modify names that referred to the same memory > location: > > (J6.02) > a =: i. 10 > b =: a > a =: 2 (7}) a > b > 0 1 2 3 4 5 6 7 8 9 > a > 0 1 2 3 4 5 6 2 8 9 > > The in-place assignment is applied only when the usecount is 1, indicating > that the value is not assigned to any other name. I suspect Marshall was > thinking of memory-mapped arrays, for which an exception is made: there the > in-place assignment is also allowed if the usecount is 2, because one use is > always allowed for the mapping name. > > But that's gone now, subsumed by the new methods. > > Henry Rich > > > On 10/1/2016 10:23 AM, Marshall Lochbaum wrote: >> >> Pascal's answer is fairly good, but this touches on an important change >> and I think the mailing list should get a more comprehensive >> description: >> >> J's arrays are immutable in normal use. When you write (2 (7}) a), J >> makes a new copy of (a), changes the value at index 2 to a 7, and >> returns that array, which is now unrelated to (a). There's no way to >> modify the original array using (}) alone. >> >> J has had an exception to this general rule for a while, in-place >> assignment. If you write >> a =: 2 (7}) a >> then J will modify the contents of (a) to replace index 2 with a 7. This >> is a mutable operation, and it changes other copies of (a) as well: if >> you executed (b =: a) before that line then the value of (b) would >> change. >> >> There's another way to get the speed of mutable operations in many cases >> without sacrificing J's immutable semantics, and this is what Henry is >> doing. Consider the snippet (2 (7}) 1+a). The operation (1+a) creates a >> new array, but this array is only ever used as an input to (}). Thus if >> we can identify these sorts of situations we can avoid copying (a) again >> for that operation, since we know it's safe to modify the array (1+a). >> Provided we never do this to an array that will be used again elsewhere, >> this means that we get a huge speed increase on the operations that can >> reuse their inputs. >> >> In principle, it's not hard to know when we can reuse an argument: J >> keeps track of a reference count for each array that tells it how many >> copies of it are in use. In the statement (2 (7}) a), the array (a) is >> referenced once in the symbol table (attached to the name "a"), and is >> referenced again when its value is copied as an argument to (7}). So its >> reference count is 2 when (7}) is executed. On the other hand, in >> (2 (7}) a+1), the array (a+1) does not appear in the symbol table, so >> its reference count is one. J keeps a reference count so it can free the >> memory for an array when its count hits zero, but we also know that if >> an array's count is one when it is passed to a verb, then it can be >> reused. Dyalog APL, K, and probably other APLs already do this. >> >> With J there are complications. In some cases a reference to an object >> is not counted, so arrays need a special signal to indicate that none of >> those cases apply. However, it seems that Henry has overcome these >> difficulties, and now J has some level of array reuse. The result for >> the user is just that some operations are much faster. J's semantics >> don't change, but its execution speed does. In many cases this can make >> a difference even to the asymptotic runtime of J programs, since >> something like in-place amend or append takes constant time but the same >> operation with a copy would have taken time proportional to the size of >> the argument array. >> >> Marshall >> >> On Sat, Oct 01, 2016 at 12:06:15PM +0200, Erling Hellenäs wrote: >>> >>> Hi all ! >>> >>> As I am sure most people here know, functional programmers prefer to >>> use non-mutable data, very often lists. There are also non-mutable >>> arrays. Now, in J development, we talk about operations in place, >>> which seems to go in opposite direction, from the mainly non-mutable >>> arrays we have to mutable arrays. Is there an analysis which shows >>> that this is the right way to go? >>> >>> Another option would be to use non-mutable arrays, specifically >>> array classes structured in such a way that you can create a copy >>> which reuses the old unchanged content and then change the contents >>> of this copy. Usually you can create a mutable array and define its >>> content, then make it non-mutable before you return it. >>> >>> I tried non-mutable array in F#, and they seem slow compared to >>> ordinary arrays, but on some of them a copy operation was very fast. >>> I am not sure of how using such arrays would affect the performance >>> of our systems. >>> >>> Cheers, >>> >>> Erling Hellenäs >>> >>> ---------------------------------------------------------------------- >>> For information about J forums see http://www.jsoftware.com/forums.htm >> >> ---------------------------------------------------------------------- >> For information about J forums see http://www.jsoftware.com/forums.htm > > > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
