On 12 Dez., 11:30, "Xcriber51" <k...@[EMAIL PROTECTED]
> wrote:
> Hi everyone
>
> I'm trying to write a very simple module with a handful of quantifiers
and
> similar set-theoretic constructs, and I'm trying to figure out how one
can
> do this best with Objective-C.
>
> Functional languages make this very easy. For example, with Q, you can
> write...
>
> > any (<0) [5,6,9,-3]
>
> true
>
> > all (<>-3) [5,6,9,-3]
>
> false
>
> The predicate(s) ("<0", "<>-3") are nicely applied to each of the
members,
> and as the quantifiers are [most probably] defined with a "reduce"
function
> as...
>
> any = reduce (or) false;
> all = reduce (and) true;
>
> ..you get the result with very elegant code.
>
> (NB: "Elegant" stands NOT for "fa****onably smart-dressed" but for
> "ingenuously simple and effective." <End of insulting fellow coders'
> intellect.>)
>
> However, the tricky parts here are
>
> - the curried syntax of the predicate(s);
> - the type-generality of their application domain
>
> ..neither of which are sup****ted by Objective-C. (Ok, maybe "id" can be
> used for the second but that's not a type derived from say a protocol
like
> -- to use a Java/Eiffel analogy -- "Comparable"; it's probably a "(void
*)"
> or something. <End of Objective-C-ignorant remark.>)
>
> I'm a novice to Objective-C, so I first tried this with integers as
> follows.
>
> I used a function pointer called "Predicate" to define the simple
> relations of equal, less than, greater than, etc.
>
> // "Predicate.h"
>
> typedef BOOL (*Predicate)(int lhs, int rhs);
>
> BOOL eq (int lhs, int rhs) { return (lhs == rhs); }
> BOOL lt (int lhs, int rhs) { return (lhs < rhs); }
> BOOL gt (int lhs, int rhs) { return (lhs > rhs); }
> BOOL le (int lhs, int rhs) { return (lhs <= rhs); }
> BOOL ge (int lhs, int rhs) { return (lhs >= rhs); }
> BOOL ne (int lhs, int rhs) { return (lhs != rhs); }
>
> // These macros are only for convenience, to save the
> // client from having to use the address-of op '&'.
>
> #define equalTo &eq
> #define lessThan <
> #define greaterThan >
> #define lessThanEqualTo &le
> #define greaterThanEqualTo &ge
> #define notEqualTo &ne
>
> Then I used a category named "Quantifying" on the NSSet type (since I
> expect these to be used primarily on sets) (the implementations are just
> the first trials and some are naive in algorithm):
>
> // "Quantifying.h"
>
> #im****t <Foundation/Foundation.h>
> #im****t "Predicate.h"
>
> @[EMAIL PROTECTED]
NSSet (Quantifying);
> -(BOOL) any: (Predicate) pred : (int) rhs;
> -(BOOL) all: (Predicate) pred : (int) rhs;
> -(BOOL) none: (Predicate) pred : (int) rhs;
> -(BOOL) most: (Predicate) pred : (int) rhs;
> -(BOOL) few: (Predicate) pred : (int) rhs;
> @[EMAIL PROTECTED]
>
> @[EMAIL PROTECTED]
NSSet (Quantifying);
>
> // Could be implemented with binary search to speed up
> -(BOOL) any: (Predicate) pred : (int) rhs
> {
> int i = [self count]-1;
> NSEnumerator *ns = [self objectEnumerator];
>
> while ((i >= 0) && ! pred([[ns nextObject] intValue], rhs))
> i--;
>
> return (i > 0);
>
> }
>
> -(BOOL) all: (Predicate) pred : (int) rhs
> {
> int i = [self count]-1;
> NSEnumerator *ns = [self objectEnumerator];
>
> while ((i >= 0) && pred([[ns nextObject] intValue], rhs))
> i--;
>
> return (i < 0);
>
> }
>
> -(BOOL) none: (Predicate) pred : (int) rhs
> {
> int i = [self count]-1;
> NSEnumerator *ns = [self objectEnumerator];
>
> while ((i >= 0) && ! pred([[ns nextObject] intValue], rhs))
> i--;
>
> return (i < 0);
>
> }
>
> // Could exit once it determines 1 item more than half
> // of the set fulfills the predicate
> -(BOOL) most: (Predicate) pred : (int) rhs
> {
> int i = [self count]-1;
> int q = i/2, r = i%2, e = 0;
>
> NSEnumerator *ns = [self objectEnumerator];
>
> while (i >= 0) {
> if (! pred([[ns nextObject] intValue], rhs))
> e++;
> i--;
> }
>
> return (e < q+r);
>
> }
>
> // Likewise, could exit once it determines more than
> // half of the items fail to fulfill the predicate
> -(BOOL) few: (Predicate) pred : (int) rhs
> {
> int i = [self count]-1;
> int q = i/2, r = i%2, e = 0;
>
> NSEnumerator *ns = [self objectEnumerator];
>
> while (i >= 0) {
> if (! pred([[ns nextObject] intValue], rhs))
> e++;
> i--;
> }
>
> return (e > q+r);
>
> }
>
> @[EMAIL PROTECTED]
>
> You may ask "what exactly are the 'none', 'most', and 'few' dudes doing
> there?" but never mind that. They are just for convenience -- I can
> imagine problems where they could come in handy (with which you're free
to
> disagree, but that's a different topic :)).
>
> And then a very simple workout:
>
> // "main.m"
>
> #im****t <Foundation/Foundation.h>
> #im****t "Quantifying.h"
>
> #define _I(v) [NSNumber numberWithInt: v]
>
> int main(int argc, char *argv[])
> {
> NSAutoreleasePool *pool = [NSAutoreleasePool new];
> NSSet *ns = [NSSet setWithObjects: _I(5), _I(6), _I(9), _I(-3),
nil];
>
> printf("ns = { 5, 6, 9, -3 } :\n" \
> " any < 0 = %c\n" \
> " all != -3 = %c\n" \
> " none == -4 = %c\n" \
> " most > 0 = %c\n" \
> " few >= 9 = %c\n\n",
> [ns any: lessThan : 0] ? 'Y' : 'N',
> [ns all: notEqualTo : -3] ? 'Y' : 'N',
> [ns none: equalTo : -4] ? 'Y' : 'N',
> [ns most: greaterThan : 0] ? 'Y' : 'N',
> [ns few: greaterThanEqualTo : 9] ? 'Y' : 'N'
> );
>
> [pool release];
>
> return 0;
>
> }
>
> (NB: This was compiled on a Windows MinGW environment using the GNUstep
> implementation of the Foundation cl*****.)
>
> Here's the output (the compile file is "qntf"):
>
> $ qntf
> ns = { 5, 6, 9, -3 } :
> any < 0 = Y
> all != -3 = N
> none == -4 = Y
> most > 0 = Y
> few >= 9 = Y
>
> --
>
> Now, my question(s):
>
> - Do you know a more concise and/or elegant way of doing this?
> - How would you code this so that I could send not only integers but any
> kind of data (chars, strings, complex numbers) to it?
>
> When you're replying, please make sure you...
>
> - do NOT provide the full text of the solution you suggest (I'd like to
> solve this myself);
> - do NOT reply with "you dufus, module/type X of library A already
> provides this";
> - if possible, rather than suggesting something yourself, direct me to a
> resource that may inspire that idea;
> - preferably only discuss, or hint at, the characteristic principles of
> Objective-C coding that I should ponder on when I'm trying to find the
> solution.
>
> Thanks for reading this long-winded message (my server doesn't allow me
to
> attach files, so I had to include the code in the message), and thanks
in
> advance for your reply.
>
> Cheers
> -- K
>
> --
> Message posted
usinghttp://www.talkaboutprogramming.com/group/comp.lang.objective-c/
> More information athttp://www.talkaboutprogramming.com/faq.html
Just some ideas:
You can put your objects into NSNumbers. They all have a compare: and
an isEqual: method. Well, this returns NO when comparing numbers with
strings...
And, you can put these objects into NSArray or NSSet. Then, define
some reduce-operators working on sets or arrays. Similar to the -
makeObjectsPerformSelector: method which applies a method call to all
elements.
So, it could look like
[[NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber
numberWithInt:2], nil] sum];
To do it, you have to add new methods to NSArray (by an Obj-C
Category) that loop through all elements and e.g. sum them up. Or
check for truth values.
Or, alternatively, please look to NSPredicate - which you can also
apply to a given NSArray. But - we are leaving discussion of Objective-
C since this are features of the (Apple/Cocoa or GNUstep) Foundation
cl***** which is not part of the language.
-- hns


|