Thread: [F-Script-talk] Methods in F-Script.
Brought to you by:
pmougin
From: Massimiliano G. <mg...@ma...> - 2005-07-13 11:37:14
|
Hi, recently I wrote some code which allows to override an arbitrary objc methods by sending the corresponding NSInvocation to a delegate for handling. My purpose is to use this technique to extend objc classes from an external language (Io, in my case). However I think that such a mechanism can be also useful in F-Script to replace native methods with scripts (and ultimately to be able to define ObjC classes in F- Script). You can find the code for the MXMethodOverride class which implements the technique (within an example application) at http://www.ing.unipi.it/~d9615/homepage/mac.html It is a beta version but works as expected. Comments are welcome. best, Massimiliano Gubinelli |
From: Marcel W. <ma...@me...> - 2005-07-13 11:55:28
|
On 13 Jul 2005, at 12:36, Massimiliano Gubinelli wrote: > recently I wrote some code which allows to override an arbitrary > objc methods by sending the corresponding NSInvocation to a > delegate for handling. Cool. I wrote something very similar for Objective-Smalltalk, which I haven't been able to work much on recently. > My purpose is to use this technique to extend objc classes from an > external language (Io, in my case). However I think that such a > mechanism can be also useful in F-Script to replace native methods > with scripts (and ultimately to be able to define ObjC classes in F- > Script). Yup. -- Marcel Weiher Metaobject Software Technologies ma...@me... www.metaobject.com Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc. 1d480c25f397c4786386135f8e8938e4 |
From: Todd B. <tbl...@ma...> - 2005-07-14 05:15:00
|
Huh, seems like a theme. I've been working on an app based on integrating the following components: CoreData - basic object modeling and persistence CLIPS - see http://www.ghg.net/clips/CLIPS.html - constraints/ intelligence/rules FScript - actions and predicates from CLIPS. (Yes Philippe - this is based on the thing I showed you at the Paris Squeaknic a couple years ago). CLIPS is pretty pluggable - you can install new functions into the interpreter by handing it a C function pointer and registering it. You can also register a custom parser to parse the rest of the function line. I registered a function named '[' and in the parser I just scan to the matching ']' and then pick out the variables in the expression and bind them in the FScript symbol table. With this you can write predicates in FScript. So you could write the clips rule: (defrule event-is-active ?event<-(Event (startDate ?start&:([NSDate date > ?start])) (endDate ? end&:([NSDate date < endDate])) (status ~active)) => ([?event setStatus: 'active'])) Which says - match any Event with a startDate later than now, an endDate earlier than now, and status not set to active => (then) set the status to active. The CoreData/CLIPS integration allows you to assert CoreData objects as 'facts' in the CLIPS knowledge base so the rules can match them. This is why the above rule even works. Each core data object has a 'fact' that shadows the values. KVO allows me to keep the fact sync'd with the object. Lately I've been wishing I could have derived attributes that are calculated based on other attributes. This is useful for binding table columns and such. To do this, I override valueForKey: in KBManagedObject (my NSManagedObject subclass) to look up the userInfo on the attribute description and look for a key called "value". This should be an FScript expression that I toss into a block and evaluate. I'm using this to model a Week object where I just have one real persistent attribute 'sunday'. The 'monday', 'tuesday' etc are transient attributes that have FScript expressions like 'self sunday dateByAddingDays: 1'. I slap this into a template that looks like '[:self | %@ ]' and evaluate it as a block with the managed object as an argument. I've also notice that the latest FScript has a special case for NSManagedObject's and "fakes" zero argument message sends that are the same name as an attribute and calls valueForKey: I've extended it to include mutator support as well. So even if you are using vanilla managed objects, you can still do setFoo: val instead of setValue: val forKey: 'Foo' This little combination has proven really powerful. I've build a working project management app with just clips rules, IB bindings, and a CoreData model. It works OK but its pretty vanilla. I've been working on sexing up the UI and this is rapidly turning into a black hole. But for quickie apps based on calculations and constraints, this little framework is da bomb. I added the following to ExecEngine.m static NSString* keyFromMutator(NSString* key) { if([key hasPrefix: @"set"]) { key = [[[key substringWithRange: NSMakeRange(3,1)] lowercaseString] stringByAppendingString: [key substringWithRange: NSMakeRange(4,[key length]-5)]]; } return key; } and changed the special case for NSMangedObject in sendMsgNoPattern to read: else if (![receiver isProxy] && [receiver isKindOfClass:NSClassFromString(@"NSManagedObject")] && [[[[receiver entity] propertiesByName] allKeys] containsObject:keyFromMutator (selectorStr)]) // We don't support proxy here because it will crash when the isKindOfClass:NSClassFromString(@"NSManagedObject") message is executed on Mac OS X < 10.4 { if([selectorStr hasPrefix: @"set"] && [selectorStr hasSuffix: @":"] && numbersOfArguments == 3) { return [receiver performSelector:@selector(setValue:forKey:) withObject: args[2] withObject: keyFromMutator(selectorStr)]; } else { return [receiver performSelector:@selector(valueForKey:) withObject:selectorStr]; } } On Jul 13, 2005, at 4:55 AM, Marcel Weiher wrote: > > On 13 Jul 2005, at 12:36, Massimiliano Gubinelli wrote: > > >> recently I wrote some code which allows to override an arbitrary >> objc methods by sending the corresponding NSInvocation to a >> delegate for handling. >> > > Cool. I wrote something very similar for Objective-Smalltalk, > which I haven't been able to work much on recently. > > >> My purpose is to use this technique to extend objc classes from an >> external language (Io, in my case). However I think that such a >> mechanism can be also useful in F-Script to replace native methods >> with scripts (and ultimately to be able to define ObjC classes in >> F-Script). >> > > Yup. > > > -- > > Marcel Weiher Metaobject Software Technologies > ma...@me... www.metaobject.com > Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc. > 1d480c25f397c4786386135f8e8938e4 > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by the 'Do More With Dual!' webinar > happening > July 14 at 8am PDT/11am EDT. We invite you to explore the latest in > dual > core and dual graphics technology at this free one hour event > hosted by HP,AMD, and NVIDIA. To register visit http://www.hp.com/ > go/dualwebinar > _______________________________________________ > F-Script-talk mailing list > F-S...@li... > https://lists.sourceforge.net/lists/listinfo/f-script-talk > |
From: Marcel W. <ma...@me...> - 2005-07-14 08:12:38
|
Hi Todd! On 14 Jul 2005, at 02:07, Todd Blanchard wrote: > Huh, seems like a theme. Sure does! :-) > I've been working on an app based on integrating the following > components: > > CoreData - basic object modeling and persistence > CLIPS - see http://www.ghg.net/clips/CLIPS.html - constraints/ > intelligence/rules > FScript - actions and predicates from CLIPS. Well, one of the motives for developing Objective-Smalltalk is to act as a "language workbench", so that it becomes possible to define, for example, sublanguages. One I've done just recently is a very simple one-way constraint solver, which adds just 280 lines of code to the project because it can reuse capabilities of the base system. One of the motivations for ObSt was the realization that things like script languages, constraint systems, rule-systems, DSLs etc. are actually very similar, and can be expressed as differences in a few key concepts (this was later confirmed by "Concepts, Techniques, and Models of Computer Programming", http://www2.info.ucl.ac.be/people/ PVR/book.html ). And what's great for capturing such differences? Yup. Instead, we typically have these fairly monolithic beasts that we then have to yoke together, but after writing a couple of bridges myself I got a bit tired of that, it seemed quite wasteful and was never really satisfactory. Marcel |
From: Philippe M. <pm...@ac...> - 2005-07-15 12:33:33
|
Tood, this is quite interesting. Are you going to release this CLIPS/=20 F-Script/Cocoa integration in some form? About the automatic translation from setValue:val forKey:'foo' to =20 setFoo:val for managed objects, this is something I'm considering =20 adding to F-Script but I want to be sure it will be useful and is not =20= going to cause unintended problems. Did you encountered any problem =20 with it ? Do you think it's worth adding to the main F-Script =20 distribution ? One problem I see with this kind of stuff is that the =20 more you have such "special case" behavior, the more the language is =20 complex and difficult to master for its users. Cheers, Philippe Le 14 juil. 05 =E0 03:07, Todd Blanchard a =E9crit : > Huh, seems like a theme. I've been working on an app based on =20 > integrating the following components: > > CoreData - basic object modeling and persistence > CLIPS - see http://www.ghg.net/clips/CLIPS.html - constraints/=20 > intelligence/rules > FScript - actions and predicates from CLIPS. > > (Yes Philippe - this is based on the thing I showed you at the =20 > Paris Squeaknic a couple years ago). > > CLIPS is pretty pluggable - you can install new functions into the =20 > interpreter by handing it a C function pointer and registering it. =20= > You can also register a custom parser to parse the rest of the =20 > function line. I registered a function named '[' and in the parser =20= > I just scan to the matching ']' and then pick out the variables in =20 > the expression and bind them in the FScript symbol table. With =20 > this you can write predicates in FScript. So you could write the =20 > clips rule: > > (defrule event-is-active > ?event<-(Event (startDate ?start&:([NSDate date > ?start])) =20 > (endDate ?end&:([NSDate date < endDate])) (status ~active)) > =3D> > ([?event setStatus: 'active'])) > > Which says - match any Event with a startDate later than now, an =20 > endDate earlier than now, and status not set to active > =3D> (then) > set the status to active. > > The CoreData/CLIPS integration allows you to assert CoreData =20 > objects as 'facts' in the CLIPS knowledge base so the rules can =20 > match them. This is why the above rule even works. Each core data =20= > object has a 'fact' that shadows the values. KVO allows me to keep =20= > the fact sync'd with the object. > > Lately I've been wishing I could have derived attributes that are =20 > calculated based on other attributes. This is useful for binding =20 > table columns and such. To do this, I override valueForKey: in =20 > KBManagedObject (my NSManagedObject subclass) to look up the =20 > userInfo on the attribute description and look for a key called =20 > "value". This should be an FScript expression that I toss into a =20 > block and evaluate. I'm using this to model a Week object where I =20 > just have one real persistent attribute 'sunday'. The 'monday', =20 > 'tuesday' etc are transient attributes that have FScript =20 > expressions like 'self sunday dateByAddingDays: 1'. I slap this =20 > into a template that looks like '[:self | %@ ]' and evaluate it as =20 > a block with the managed object as an argument. > > I've also notice that the latest FScript has a special case for =20 > NSManagedObject's and "fakes" zero argument message sends that are =20 > the same name as an attribute and calls valueForKey: I've extended =20= > it to include mutator support as well. So even if you are using =20 > vanilla managed objects, you can still do setFoo: val instead of =20 > setValue: val forKey: 'Foo' > > This little combination has proven really powerful. I've build a =20 > working project management app with just clips rules, IB bindings, =20 > and a CoreData model. It works OK but its pretty vanilla. I've =20 > been working on sexing up the UI and this is rapidly turning into a =20= > black hole. But for quickie apps based on calculations and =20 > constraints, this little framework is da bomb. > > I added the following to ExecEngine.m > > static NSString* keyFromMutator(NSString* key) > { > if([key hasPrefix: @"set"]) > { > key =3D [[[key substringWithRange: NSMakeRange(3,1)] =20 > lowercaseString] > stringByAppendingString: [key substringWithRange: =20 > NSMakeRange(4,[key length]-5)]]; > } > return key; > } > > and changed the special case for NSMangedObject in sendMsgNoPattern =20= > to read: > > else if (![receiver isProxy] && [receiver =20 > isKindOfClass:NSClassFromString(@"NSManagedObject")] && =20 > [[[[receiver entity] propertiesByName] allKeys] =20 > containsObject:keyFromMutator(selectorStr)]) > // We don't support proxy here because it will crash when the =20 > isKindOfClass:NSClassFromString(@"NSManagedObject") message is =20 > executed on Mac OS X < 10.4 > { > if([selectorStr hasPrefix: @"set"] && [selectorStr hasSuffix: =20= > @":"] && numbersOfArguments =3D=3D 3) > { > return [receiver performSelector:@selector=20 > (setValue:forKey:) withObject: args[2] withObject: keyFromMutator=20 > (selectorStr)]; > } > else > { > return [receiver performSelector:@selector(valueForKey:) =20 > withObject:selectorStr]; > } > } > > > On Jul 13, 2005, at 4:55 AM, Marcel Weiher wrote: > >> >> On 13 Jul 2005, at 12:36, Massimiliano Gubinelli wrote: >> >> >>> recently I wrote some code which allows to override an arbitrary =20= >>> objc methods by sending the corresponding NSInvocation to a =20 >>> delegate for handling. >>> >> >> Cool. I wrote something very similar for Objective-Smalltalk, =20 >> which I haven't been able to work much on recently. >> >> >>> My purpose is to use this technique to extend objc classes from =20 >>> an external language (Io, in my case). However I think that such =20 >>> a mechanism can be also useful in F-Script to replace native =20 >>> methods with scripts (and ultimately to be able to define ObjC =20 >>> classes in F-Script). >>> >> >> Yup. >> >> >> --=20 >> >> Marcel Weiher Metaobject Software Technologies >> ma...@me... www.metaobject.com >> Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc. >> 1d480c25f397c4786386135f8e8938e4 >> >> >> >> >> ------------------------------------------------------- >> This SF.Net email is sponsored by the 'Do More With Dual!' webinar =20= >> happening >> July 14 at 8am PDT/11am EDT. We invite you to explore the latest =20 >> in dual >> core and dual graphics technology at this free one hour event =20 >> hosted by HP,AMD, and NVIDIA. To register visit http://www.hp.com/=20= >> go/dualwebinar >> _______________________________________________ >> F-Script-talk mailing list >> F-S...@li... >> https://lists.sourceforge.net/lists/listinfo/f-script-talk >> > |
From: Todd B. <tbl...@ma...> - 2005-07-16 06:40:10
|
Yes, I'm working on building a little application with it to make =20 sure it is practical and I think I will release it at the end of summer. As for the special case behavior - I noticed that you already added =20 half (valueForKey:). I added the other half. :-) I spent some time trying to make NSManagedObject work with message =20 sends by overriding repondsToSelector: forwardInvocation: and =20 methodSignatureForSelector:. NSManagedObject didn't like this at all =20= and I found myself with a hung program and completely unresponsive =20 debugger. For what I'm doing, the special case is nice because before I did it, =20= all the rules had to use setValue:forKey: and this began to feel kind =20= of ugly. I can't decide yet if its worth the added complexity. I =20 got a very boring but useful application working very quickly using =20 coredata, IB, and clips rules, but I an now stuck in Hell with =20 various bits of AppKit as I try to get some custom UI working. I'll have a firmer opinion with more experience with it. On Jul 15, 2005, at 5:37 AM, Philippe Mougin wrote: > > Tood, this is quite interesting. Are you going to release this =20 > CLIPS/F-Script/Cocoa integration in some form? > About the automatic translation from setValue:val forKey:'foo' to =20 > setFoo:val for managed objects, this is something I'm considering =20 > adding to F-Script but I want to be sure it will be useful and is =20 > not going to cause unintended problems. Did you encountered any =20 > problem with it ? Do you think it's worth adding to the main F-=20 > Script distribution ? One problem I see with this kind of stuff is =20 > that the more you have such "special case" behavior, the more the =20 > language is complex and difficult to master for its users. > > Cheers, > > Philippe > > Le 14 juil. 05 =E0 03:07, Todd Blanchard a =E9crit : > >> Huh, seems like a theme. I've been working on an app based on =20 >> integrating the following components: >> >> CoreData - basic object modeling and persistence >> CLIPS - see http://www.ghg.net/clips/CLIPS.html - constraints/=20 >> intelligence/rules >> FScript - actions and predicates from CLIPS. >> >> (Yes Philippe - this is based on the thing I showed you at the =20 >> Paris Squeaknic a couple years ago). >> >> CLIPS is pretty pluggable - you can install new functions into the =20= >> interpreter by handing it a C function pointer and registering =20 >> it. You can also register a custom parser to parse the rest of =20 >> the function line. I registered a function named '[' and in the =20 >> parser I just scan to the matching ']' and then pick out the =20 >> variables in the expression and bind them in the FScript symbol =20 >> table. With this you can write predicates in FScript. So you =20 >> could write the clips rule: >> >> (defrule event-is-active >> ?event<-(Event (startDate ?start&:([NSDate date > ?start])) =20 >> (endDate ?end&:([NSDate date < endDate])) (status ~active)) >> =3D> >> ([?event setStatus: 'active'])) >> >> Which says - match any Event with a startDate later than now, an =20 >> endDate earlier than now, and status not set to active >> =3D> (then) >> set the status to active. >> >> The CoreData/CLIPS integration allows you to assert CoreData =20 >> objects as 'facts' in the CLIPS knowledge base so the rules can =20 >> match them. This is why the above rule even works. Each core =20 >> data object has a 'fact' that shadows the values. KVO allows me =20 >> to keep the fact sync'd with the object. >> >> Lately I've been wishing I could have derived attributes that are =20 >> calculated based on other attributes. This is useful for binding =20 >> table columns and such. To do this, I override valueForKey: in =20 >> KBManagedObject (my NSManagedObject subclass) to look up the =20 >> userInfo on the attribute description and look for a key called =20 >> "value". This should be an FScript expression that I toss into a =20= >> block and evaluate. I'm using this to model a Week object where I =20= >> just have one real persistent attribute 'sunday'. The 'monday', =20 >> 'tuesday' etc are transient attributes that have FScript =20 >> expressions like 'self sunday dateByAddingDays: 1'. I slap this =20 >> into a template that looks like '[:self | %@ ]' and evaluate it as =20= >> a block with the managed object as an argument. >> >> I've also notice that the latest FScript has a special case for =20 >> NSManagedObject's and "fakes" zero argument message sends that are =20= >> the same name as an attribute and calls valueForKey: I've =20 >> extended it to include mutator support as well. So even if you =20 >> are using vanilla managed objects, you can still do setFoo: val =20 >> instead of setValue: val forKey: 'Foo' >> >> This little combination has proven really powerful. I've build a =20 >> working project management app with just clips rules, IB bindings, =20= >> and a CoreData model. It works OK but its pretty vanilla. I've =20 >> been working on sexing up the UI and this is rapidly turning into =20 >> a black hole. But for quickie apps based on calculations and =20 >> constraints, this little framework is da bomb. >> >> I added the following to ExecEngine.m >> >> static NSString* keyFromMutator(NSString* key) >> { >> if([key hasPrefix: @"set"]) >> { >> key =3D [[[key substringWithRange: NSMakeRange(3,1)] =20 >> lowercaseString] >> stringByAppendingString: [key substringWithRange: =20 >> NSMakeRange(4,[key length]-5)]]; >> } >> return key; >> } >> >> and changed the special case for NSMangedObject in =20 >> sendMsgNoPattern to read: >> >> else if (![receiver isProxy] && [receiver =20 >> isKindOfClass:NSClassFromString(@"NSManagedObject")] && =20 >> [[[[receiver entity] propertiesByName] allKeys] =20 >> containsObject:keyFromMutator(selectorStr)]) >> // We don't support proxy here because it will crash when the =20 >> isKindOfClass:NSClassFromString(@"NSManagedObject") message is =20 >> executed on Mac OS X < 10.4 >> { >> if([selectorStr hasPrefix: @"set"] && [selectorStr =20 >> hasSuffix: @":"] && numbersOfArguments =3D=3D 3) >> { >> return [receiver performSelector:@selector=20 >> (setValue:forKey:) withObject: args[2] withObject: keyFromMutator=20 >> (selectorStr)]; >> } >> else >> { >> return [receiver performSelector:@selector(valueForKey:) =20 >> withObject:selectorStr]; >> } >> } >> >> >> On Jul 13, 2005, at 4:55 AM, Marcel Weiher wrote: >> >>> >>> On 13 Jul 2005, at 12:36, Massimiliano Gubinelli wrote: >>> >>> >>>> recently I wrote some code which allows to override an =20 >>>> arbitrary objc methods by sending the corresponding NSInvocation =20= >>>> to a delegate for handling. >>>> >>> >>> Cool. I wrote something very similar for Objective-Smalltalk, =20 >>> which I haven't been able to work much on recently. >>> >>> >>>> My purpose is to use this technique to extend objc classes from =20 >>>> an external language (Io, in my case). However I think that such =20= >>>> a mechanism can be also useful in F-Script to replace native =20 >>>> methods with scripts (and ultimately to be able to define ObjC =20 >>>> classes in F-Script). >>>> >>> >>> Yup. >>> >>> >>> --=20 >>> >>> Marcel Weiher Metaobject Software Technologies >>> ma...@me... www.metaobject.com >>> Metaprogramming for the Graphic Arts. HOM, IDEAs, MetaAd etc. >>> 1d480c25f397c4786386135f8e8938e4 >>> >>> >>> >>> >>> ------------------------------------------------------- >>> This SF.Net email is sponsored by the 'Do More With Dual!' =20 >>> webinar happening >>> July 14 at 8am PDT/11am EDT. We invite you to explore the latest =20 >>> in dual >>> core and dual graphics technology at this free one hour event =20 >>> hosted by HP,AMD, and NVIDIA. To register visit http://=20 >>> www.hp.com/go/dualwebinar >>> _______________________________________________ >>> F-Script-talk mailing list >>> F-S...@li... >>> https://lists.sourceforge.net/lists/listinfo/f-script-talk >>> >> > |
From: Philippe M. <pm...@ac...> - 2005-07-15 12:16:10
|
Thanks Massimiliano, this is the kind of stuff we want to have for F-=20 Script. I'll have a look at it. Cheers, Philippe Le 13 juil. 05 =E0 13:36, Massimiliano Gubinelli a =E9crit : > Hi, > recently I wrote some code which allows to override an arbitrary =20 > objc methods by sending the corresponding NSInvocation to a =20 > delegate for handling. > My purpose is to use this technique to extend objc classes from an =20 > external language (Io, in my case). However I think that such a =20 > mechanism can be also useful in F-Script to replace native methods =20 > with scripts (and ultimately to be able to define ObjC classes in F-=20= > Script). > > You can find the code for the MXMethodOverride class which =20 > implements the technique (within an example application) at > http://www.ing.unipi.it/~d9615/homepage/mac.html > > It is a beta version but works as expected. Comments are welcome. > > best, > Massimiliano Gubinelli > > > > > > > > ------------------------------------------------------- > This SF.Net email is sponsored by the 'Do More With Dual!' webinar =20 > happening > July 14 at 8am PDT/11am EDT. We invite you to explore the latest in =20= > dual > core and dual graphics technology at this free one hour event =20 > hosted by HP,AMD, and NVIDIA. To register visit http://www.hp.com/=20 > go/dualwebinar > _______________________________________________ > F-Script-talk mailing list > F-S...@li... > https://lists.sourceforge.net/lists/listinfo/f-script-talk > > |