REBOL 3.0

Comments on: Definition of FIND on an OBJECT

Carl Sassenrath, CTO
REBOL Technologies
6-Jun-2008 21:57 GMT

Article #0139
Main page || Index || Prior Article [0138] || Next Article [0140] || 11 Comments || Send feedback

R3 2.100.13 adds both select and find actions (datatype function methods) to the OBJECT datatype. But, we still have a decision to make and soon! Here's the situation...

Select is similar to the idiom get in. It returns the value bound to the word within the object's context:

>> obj: make object! [a: 10 b: none]
>> select obj 'a
== 10
>> select obj 'b
== none
>> select obj 'c
== none

For many years I avoided adding this usage of select, but I've recently been writing code where both the object and the selector word can optionally be NONE, and I don't want to wrap everything with extra conditional checks or all blocks. So, I caved-in and finally added it. Yell loudly if you think it's a mistake. (My inclination is that this is fine, but I'm not sure I'm as smart as I was in 2000. Maybe it is the red wine.)

The last two cases above highlight a long-standing minor issue with objects: you cannot detect the existence of a word via selection (you must use either in or the words-of function). It's not a big problem and in fact can be considered a feature because it has its uses.

However, with that in mind, find has been defined to work this way:

>> find obj 'a
== true
>> find obj 'b
== true
>> find obj 'c
== none

Here find tells you that the word is defined in the context, even though its value is NONE.

Of course, you can do roughly the same thing with the in function:

>> in obj 'b
== b
>> in obj 'c
== none

So the bigger question becomes: is there some other find feature that we may want to use on objects? For example, would it be more useful for find to search the value part of an object, as in:

>> find obj '10
== a
>> find obj "test"
== none
Must be decided now...

To avoid compatibility problems, we need to decide on this issue before the release of 2.100.14.

Please post your thoughts on this here in the comments section. Thanks.

11 Comments

Comments:

Paul
6-Jun-2008 20:37:24
I have concerns in this area. 'Find is one of those functions that is highly utilized and used greatly in loops over large series. Wouldn't the additional code being poured into 'find cause a performance hit? Seems we can already accomplish these tasks with a bit more code but I would rather do it with more code then to take a performance hit with 'find.

Brian Tiffin
6-Jun-2008 22:11:26
I'll add a half ditto to Paul's concern. I, for one, am going to greatly appreciate the none-transparency of FIND. It'll just save a layer of wrapper I always add (or forget until some untrapped error is triggered by some poor unfortunate user I inflict code on). This removal of wrapper test will no doubt make (I'll add a my) code faster in the general case even if the FIND native is a tad bit slower.

Re the scan of value to return the set-word!, I'd double think that if FIND was slowed in the general case. FIND REVERSE BODY-OF obj can be used for that example feature. And with the complications that would be inherent if there were duplicate values anyway. If there is no discernible slowing of the general case then it will just be another great feature of REBOL. :)

Carl Read
6-Jun-2008 23:19:21
I'd think searching the values in objects would be used much more than searching for the object words. And if used, a find/deep would also be useful for searching within values when they're series.
Jerry Tsai
7-Jun-2008 0:41:26
obj: make object! [ 
  type: 'TEXT   ; = TEXT is a value
  TEXT: "OK"    ; = TEXT is a word
]
find obj 'TEXT ; < == TEXT is value or word?
Robert
7-Jun-2008 3:31:32
If we can search for VALUES a block of words needs to be returned. It's not sure that only one word with the search value exists.
Anton Rolls
7-Jun-2008 13:59:24
I think FIND as just an alias of IN is worthless and I would remove it.
Much more useful is searching for values in the object.
[Returning a set of values is cool, but maybe not for FIND, perhaps "FINDS"?]
But if a single value is returned, how do we specify to skip past the previous result for our next search ? We can't say NEXT object can we, so...
Oldes
9-Jun-2008 6:48:52
Is this needed at all? Try this:
>> dt [loop 100000 [select obj 'a]]
== 0:00:00.031
>> dt [loop 100000 [obj/('a)]]
== 0:00:00.016
What version you would use?
Gary Hurst
10-Jun-2008 0:54:42
It would be very useful for FIND to search for an item inside of a block of OBJECTS.

for example:

>> find/in obj-block "what-to-find" 'field-name
== none
(if not found)
>> find/in obj-block "what-to-find" 'field-name
== obj-block/25
(or whatever item was found -- points to the object containing the match)
Gary Hurst
10-Jun-2008 1:07:24
This is how I have done it in the past... But it would be nice to have this as native.
find-it: func ["Find any item in a series of objects, searchable by field name"
data "Block of data objects" search field [word!]
/any "Allows wildcards"][
  forall data [
    either any [
      if attempt [find data/1/:field search] [return data/1]
    ][
      if attempt [= data/1/:field search] [return data/1]
  ]
]
return none]
Brian Hawley
10-Jun-2008 15:00:47
Normally I would be go for consistency, but in this case the most useful behavior would be to have find search for the value and return the (bound?) key, the opposite of select. You could have map! behave the same way (without the binding). We still have in for key screening.

Oldes, your code fails if the key isn't in the object.

Gary, please no type-specific refinements to find like /in. Carl Read's suggestion of a find/deep is interesting, though you would almost certainly lose track of exactly which series, object or map in the hierarchy you found the value in.

Anton, objects and maps aren't series (or shouldn't be) so they don't have a position or index. For that matter they don't really have an innate ordering. It makes sense that the usage patterns would be different.

Paul, action functions like find are already datatype specific without any additional overhead. The implementation of find for objects has no effect on the implementation for series types.

maxim olivier-adlhoch
11-Jun-2008 3:24:34
I'll say that the find/deep idea is a great one, for all types.

and find, if it returns only one value, really should return the word, but its easy to do an object find in R2 already, like so:

 
my-obj: context [
  a: "aye"
  b: "bee"
  c: "see"
]
back find third my-obj  "bee" 
== [b: "bee" c: "see"] 

maybe this behavior could be an alternative to the previous ideas.

I guess if find just implied that the spec is searched then we woundn't need to add 'THIRD, and we could use the returned block to traverse the object.

as anton said, we already have 'IN to detect object words, so 'FIND shouldn't just be a less usefull version of 'IN

Post a Comment:

You can post a comment here. Keep it on-topic.

Name:

Blog id:

R3-0139


Comment:


 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote
 
 

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

REBOL 3.0
Updated 28-Jun-2017 - Edit - Copyright REBOL Technologies - REBOL.net