Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!CS.WASHINGTON.EDU!wgg From: wgg@CS.WASHINGTON.EDU (William Griswold) Newsgroups: comp.lang.icon Subject: Re: table initialization Message-ID: <9002012226.AA27239@june.cs.washington.edu> Date: 1 Feb 90 22:26:50 GMT Sender: daemon@ucbvax.BERKELEY.EDU Distribution: inet Organization: The Internet Lines: 94 >From: cargo@tardis.cray.com (David S. Cargo) >To: icon-group@cs.arizona.edu >Subject: table initialization > >I was looking at implementing some Icon code to initialize font width >tables. Naturally I thought about using tables to do this. I then >realized that while most other structures can be initialized with >constants, there doesn't seem to be a convenient way to do this with >tables. Or is there something I'm missing. > >What I will probably wind up doing is either using lists indexed by >character values (using ord(s)) or using two constant lists to >initialize a table, char_val and char_width are the two lists: > >every i := 1 to n do width[char_val[i]] := char_width[i] > >Eventually I'll probably want to know which is faster to use, a >character width table or and array indexed using ord(s)) > >string_width := 0 # for either case >every string_width +:= char_width[ord(!s)] # for a list >every string_width +:= char_width[!s] # for a table > >It would seem to be a trade between ease of access and creation >of temporaries. > >Has anybody tried anything like this already and found an answer >to which is better speed-wise? > You might want to think about storing your character set and font widths in an external file, so that if the values (i.e., font) change, you won't have to change your program. Then the code for tables vs. lists is not so different: Your input: a 5 b 5 ... m 8 ... z 6 the processing code: # e.g., for tables table := width() while line := read(font-file) do line ? width[move(1)] := integer((tab(many(' \t')) & tab(0))) As for performance, there are several things you can try. It is likely that the ord(s) function will be faster, since the hashing and chaining used to implement tables will be avoided. If you want to hide which type you are using, use a procedure. Procedure call is pretty cheap, so you don't have to worry much about the cost: # for tables procedure width(char) static width-table initial width-table := table() return width-table[char] end # for lists procedure width(char) static width-list initial width-list := list(256) return width-list[ord(char)] end Note that since I didn't dereference the return variable, they can be assigned to by the input function: while line := read(font-file) do line ? width(move(1)) := integer((tab(many(' \t')) & tab(0))) Thus even the font width reader doesn't need to know the representation you are using. One thing that just occurred to me is that with the table representation (or some hybrid enscapsulated in a procedure) you could look-up word widths as well as character widths, probably at little extra effort (say, if you stored the widths of the 2000 most commonly used words) and some performance benefit. You could even use a history scheme, in which you remember the widths of words already computed in the current document. It seems like overkill, but it gives you some idea of the flexibility of Icon. Bill Griswold