Message-ID: <423E1EE7.1080203 at rftp.com> Date: Sun, 20 Mar 2005 17:09:59 -0800 From: Robert Roessler Organization: Robert's High-performance Software MIME-Version: 1.0 To: Jacques Garrigue CC: lablgtk at math.nagoya-u.ac.jp Subject: Re: Simple marshaller "style" question References: <423B9762.5020006 at rftp.com> <20050320.090343.112301197.garrigue at math.nagoya-u.ac.jp> In-Reply-To: <20050320.090343.112301197.garrigue at math.nagoya-u.ac.jp> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Jacques Garrigue wrote: > From: Robert Roessler > >>So, given that marshal2 or whatever I do is being used via a "partial >>application" (I think that is what you types call it) that goes into >>the GtkSignal.t record, is there a more "HOF style" way of reusing >>marshal2 but processing the argument(s) *before* the callback is >>invoked, or is the custom version of marshal2 the best I can do? > > > You just have to create your own data_conv, by modifying one of those > available in Gobject.Data. > No that you say it, it would also be easy to provide a general way > to do this composition. That is provide a function: > val wrap_conv : > inj:('a -> 'b) -> proj:('b -> 'a) -> 'b data_conv -> 'a data_conv > I just never realized there was a need for that. Whipping up my own data_conv seems too much like using my own version of marshal2 - just not as bad. :) So I did something like your "general" composition (I am familiar with the term, I just don't think that way yet) - here is where I started: A "usual" LablGTK signal processing intermediary module: module S = struct open GtkSignal open Gobject.Data (* callback: int -> int -> Gpointer.boxed option -> unit *) let command = (* ... *) (* callback: int -> scnotification -> unit *) let notify = (* ... *) end Initially, I just had "adjusted" versions of GtkSignal.marshal2 to operate on the args before going to the callback(s). Changing to a style which a) allows me to use the built-in marshal2 and b) apply arbitrary transforms on the args to the callback (including their number), we have: let marshal_command f argv = let g f ev_id bp = f (ev_id land 0xffff) (ev_id lsr 16) bp in marshal2 int pointer "command" (g f) argv let command = { name="command"; classe=`scintilla; marshaller=marshal_command} let marshal_notify f argv = let g f id bp = f id (scn_from_boxed_pointer bp) in marshal2 int pointer "sci-notify" (g f) argv let notify = { name="sci-notify"; classe=`scintilla; marshaller=marshal_notify} While there is likely more abstracting that *could* be done (which would be closer to what you suggested), this accomplished what I wanted and is still "human-readable". :) Thanks for the help! Robert Roessler robertr@rftp.com http://www.rftp.com