[Jprogramming] guidelines for writing J code that is
less-dependenton data layout
Miller, Raul D
rdmiller at usatoday.com
Thu Jul 20 06:03:35 HKT 2006
Sashikanth Chandrasekaran wrote:
> Assume that there are N entities each of which has M
> attributes and I save the values as an N*M array. If I
> want to work on the first attribute, it is tempting to
> use {."1 . Similarly, if I want to work on the 3rd
> attribute it is tempting to use 2{"1 and so on. But
> this makes the program dependent on the data layout -
> if I add one more attribute in the middle of the row,
> the program breaks.
On the other hand, nothing breaks if you add the
attribute onto the end.
If you are likely to change the attribute layout, you
should provide a level of abstraction to address that
issue.
One simple approach:
A0=:0
A2=:2
A0 {"1 data
A2 {"1 data
This assumes that when you change the layout the
change is universal.
If you will have different layouts at the same time,
then you should have a reference list associated
with the layout. You can use i. to find the position
of a value in your reference list, and you can use
that index to pull out the attributes you are interested
in.
> Are there any best practices/style guidelines to make
> the code we write less dependent on data layout
> without sacrificing performance?
Best practice says that you don't worry about performance
until you can quantify it.
Beyond that, best practices are very much dependent on
the kind of problem you are trying to address.
That said, if your attribute layout is global you can
do something like:
A0=: 0&{"1
A2=: 2&{"1
Now A0 is a verb, where (A0 data) gives you the
first attributes.
That's about as fast as you're going to get for the
data approach you described.
> I presume that "hiding" data inside a class and using
> trivial get/put functions to access the data is not the
> J style.
Correct -- this approach would tend to break operations
down into scalar chunks. J classes are better applied
at a high level where they do not interfere with
regular operations on data.
> To use a concrete example, I coded a simple solution
> for the so-called Einstein riddle
> (http://www.naute.com/puzzles/puzzle13.phtml) below.
> As you can see the code is completely tied to the
> location of the possible values in the grid - i.e. the
> code will break if I switch 'Red' and 'Green' or
> switch two rows etc. What is the recommended method
> for making it less fragile? Thx, -sashi.
Nifty...
That said, I'm not sure I understand your code. I
started working through it, rephrasing so that
I could understand what was going on, and I got
stuck.
Here is how far I got:
NB. Brute-force solution for Einstein's Riddle
grid =: ;:;._2 (0 : 0)
Brit Sweede Dane German Norwegian
Red Green White Yellow Blue
Dogs Birds Cats Horses Fish
Tea Coffee Milk Beer Water
Pall_Mall Dunhill Blends Blue_Master Prince
)
NB. atom -> gerund of constant function
constF=:3 :'y"_`'''''"0
NB. define above names as attribute index functions
('`',;:inv,grid)=:,constF 5#i.1 5
NB. Table of permutations, copied from J vocabulary page for A..
tap =: i.@! A. i.
NB. The Brit lives in a red house.
h =: (#~ (({: i. Brit) = {. i. Red)"2) ,/ ,:"1"1 _~tap 5
NB. The Swede keeps dogs as pets.
h =: ,/ h ,"_ 1"2 (({. ~: Sweede)"2 h) #^:_1"1"1 _ >:tap 4
I'm pretty sure I mis-understood that line of code
(among other thing, I'm not using 'Dogs' in it).
Note that if you're going to wind up adjusting positions
throughout the calculation simple arithmetic is probably
the best way to deal with that (Fish-3:)
--
Raul
More information about the Programming
mailing list