find list index of lookup result?

Freeform discussion about anything related to modding Transcendence.
Post Reply
User avatar
alterecco
Fleet Officer
Fleet Officer
Posts: 1658
Joined: Wed Jan 14, 2009 3:08 am
Location: Previously enslaved by the Iocrym

Hi George (again),

Lookup is an awesome new function to have, but I keep finding myself in a situation where I need to find the position of the list that lookup returns (eg. when you need to lnkReplace the content).

This often leads to:

Code: Select all

(block (res index)
  (setq res (lookup somelist 'findme 0))
  (setq index (find somelist res))
  ;; change res
  (setq somelist (lnkReplace somelist index res))
)
Now, for a simple case this is not much of a problem, but I many times have lists that contain lists of functions, or lists of lists of lists etc, and I can not imagine that a find with such a target is in any way performant...

So, I was hoping we could come up with a function or a lookup syntax that allowed me to get the list index in the same way lookup works. Perhaps an optional argument to to lookup which makes it return the index instead of the list, or a lookupIndex with the same syntax as lookup...
george moromisato
Developer
Developer
Posts: 2998
Joined: Thu Jul 24, 2003 9:53 pm
Contact:

That's perfectly reasonable; feel free to add a Trac ticket for it.

Also, the "lisp" way of doing that might be to use a higher-level abstraction. For example, imagine that we had a function called "transmute"

(transmute someList theItem someCode) -> transmuted list

Transmute would iterate over someList and set theItem to each successive item in the list. Then it would call someCode. The result of someCode would be a modified version of the list item.

E.g.:

Code: Select all

(transmute '(1 2 3 4) var
   (multiply var var)
   )

=

'(1 4 9 16)
Or:

Code: Select all

(transmute '(1 2 3 4) var
   (if (eq var 3) 17 var)
   )

=

'(1 2 17 4)
Think of this as a variant of the (filter) function.
User avatar
alterecco
Fleet Officer
Fleet Officer
Posts: 1658
Joined: Wed Jan 14, 2009 3:08 am
Location: Previously enslaved by the Iocrym

That looks like what I know as a map function... would be very handy...

The thing I like about lookup is that it gives me quick access to large lists... Mostly I just need access to the data stored at a given index, and the knowledge of what index that is, so that I can modify it if neccessary. While transmute would be able to do what I do in one block, it would still require enumerating the entire list, match only one item, and then transmute it in place (all of this in tscript, not in the core). For a list that could potentially grow large that seems like a costly way of doing things.

So, would you suggest a ticket for a lookup that returns the index (it could perhaps be called `index'), or that we use something like transmute?
User avatar
alterecco
Fleet Officer
Fleet Officer
Posts: 1658
Joined: Wed Jan 14, 2009 3:08 am
Location: Previously enslaved by the Iocrym

After talking quite a lot on IRC with Betel about this, I must admit I see no super clear solution. There are a couple of options as I see it, each with their issues, so I am hoping I have missed something :)

The one I am most inclined to see happen is:

Code: Select all

(index source target keyIndex) -> index
It's only downside is that it is rather narrow in it's application, and still requires two calls, one to get the data and one to get the index

Betel suggests this one instead, as a more versatile version:

Code: Select all

(index source expression) -> index
The idea is that it will return the index of the first element in source where the expression evaluates to non Nil.
The problem I see with this is the speed hit of using an expression. Otherwise a nice function.

Then there is a version which does it all in one go:

Code: Select all

(index source target keyIndex) -> '(index '(data))
or
(lookup source target keyIndex -> '(index '(data))
Well... even though this is the version I would find most useful, it is probably also the one furthest from the lisp way. I will leave you or Betel to chop the rest of this one down :)

The last idea addresses my problem with transmute, having to enum over all elements in tscript

Code: Select all

(lookupTransmute source target keyIndex expression) -> '(new source)
or
(transmute source target keyIndex expression) -> '(new source)
Now, this is a bit of a mongrel... The idea is that the matching be done in C to take advantage of the speed, but leave the transmuting up to tscript. It would be cool if the expression would be applied to all possible matches of target. Perhaps this is the most powerful of these suggestions, but the function signature is a bit intimidating...

In either case I hope this brings something to the table :)
Post Reply