From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 0827E7EE5E for ; Thu, 4 Apr 2013 02:46:01 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of anthony.tavener@gmail.com) identity=pra; client-ip=74.125.83.51; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="anthony.tavener@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of anthony.tavener@gmail.com designates 74.125.83.51 as permitted sender) identity=mailfrom; client-ip=74.125.83.51; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="anthony.tavener@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-ee0-f51.google.com) identity=helo; client-ip=74.125.83.51; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="postmaster@mail-ee0-f51.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ai0CAIHMXFFKfVMzk2dsb2JhbABDxToIFg4BAQEBBwsLCRQEJIJNGQEbHgMSEF0BEQEFASIuh2YBAw+fSIJyjC+Ce4RHChknDVmIfAEFDJJUA4h6iiuDRo8pFimETR0 X-IPAS-Result: Ai0CAIHMXFFKfVMzk2dsb2JhbABDxToIFg4BAQEBBwsLCRQEJIJNGQEbHgMSEF0BEQEFASIuh2YBAw+fSIJyjC+Ce4RHChknDVmIfAEFDJJUA4h6iiuDRo8pFimETR0 X-IronPort-AV: E=Sophos;i="4.87,404,1363129200"; d="scan'208";a="11683504" Received: from mail-ee0-f51.google.com ([74.125.83.51]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 04 Apr 2013 02:45:53 +0200 Received: by mail-ee0-f51.google.com with SMTP id c4so839045eek.38 for ; Wed, 03 Apr 2013 17:45:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:date:message-id:subject:from:to :content-type; bh=BCLcSYohRAKkvFvr1ZqrrjALkOvefs+WlEKePq1wgMw=; b=Uf7fyW0uaXBhfF2ChkPDuukzTUVXJsLargGDT087/+7wWNDISBJWzZHBIWnhYTO/rE jeSo3Tp8mbKrlGYUPJ4+eM87JBR4KowK23AcKo38VzLXUUUcChaJsQoav4OkW1JDQfCi 6OMKoynam7U/nZlkEQXT48xzNCJgnNwkMOv6PDF+MG0lEwyQ9dHeOhtZO4J3QrVeezNj yIQj4pLbfEUb7WHYkwzGwcjRm7oRmyK+2aL1QWi+SUhSLQWXnm5P7rSe2ihvfMNlkjKC zq4y6tMzC7HqYAKflVjvYKZ5njRH4G6KKY2R6jDOYXhjDfDXStJPwbIz+o6yiduVWgJg 3cew== MIME-Version: 1.0 X-Received: by 10.14.173.67 with SMTP id u43mr6927336eel.22.1365036352523; Wed, 03 Apr 2013 17:45:52 -0700 (PDT) Received: by 10.14.2.198 with HTTP; Wed, 3 Apr 2013 17:45:52 -0700 (PDT) Date: Wed, 3 Apr 2013 18:45:52 -0600 Message-ID: From: Anthony Tavener To: "caml-list@inria.fr" Content-Type: multipart/alternative; boundary=047d7b621fbae5f2ec04d97e4a89 Subject: [Caml-list] Heterogeneous dictionary --047d7b621fbae5f2ec04d97e4a89 Content-Type: text/plain; charset=ISO-8859-1 I think I might be up against a brick wall. But maybe there's a door I don't see, without Obj.magicing myself through the wall. (I haven't had to use magic for anything yet!) :) I want to stash values under a key, and retrieve them by that key. All values bound to a given key are of the same type, but the type will differ between keys. Basically like a hashtable you'd find in a dynamic language. (* modifier-additions like this would be scattered across the code-base *) contribute `RecoveryRoll (fun (a,b) -> a+3,b) contribute `RecoveryRoll (fun (a,b) -> a,b-1) contribute `ResistPain (fun a -> a+1) contribute `MagicResistance (fun a -> match a with None -> None | Some x -> Some(x+3)) contribute `MagicResistance (fun a -> match a with None -> Some 7 | Some x -> Some(x+7)) (* example of applying modifiers... *) let modified = fold `RecoveryRoll (4,1) in ... (There are details I've left out here, like the need for 'contribute' returning an id by which to remove a modifier, as well as control over order-of-application.) Now I think the type signature of these functions would be: val contribute: a'. 'a key -> ('a -> 'a) -> unit val fold: 'a. 'a key -> 'a -> 'a And the thorn in my side would be that the key must be "keyed" to the type, or is there an escape? At one point I tried a universal type to "hide" the signature of the function-list, but I also stashed the inj/proj under the key -- well, of course the inj/proj functions had different types per entry in a hashtable, so that worked as well as not having a universal type involved. :) If I provide the inj/proj functions at each invocation then I need to pre-create these and house them somewhere (which could create a bottleneck of type-dependencies) -- Imagine several hundred modifiers like `RecoveryRoll; some might use types that only need visibility in one module. Trying to place each modifier in suitable modules also seems a mess... a lot of them conceptually exist "in the spaces between modules". So I keep trying to create an airy light-weight "implied" association to connect modifiers to use-sites... but to satisfy typing it seems I need to be explicit at some point. Does anyone have any ideas? I'm often surprised at the gymnastics OCaml's type-system can accomplish under the guidance of some smart folks. If anyone's made a heterogenous dictionary/hashtable that doesn't need types explicity declared, that would probably be what I'm looking for. Note that I've had this problem surface several times and managed to find solutions that suited the specific problem, but each problem can have it's subtle details. In this case, the large number of keys and functions, combined with their spread across codebase and the sparse nature of their use (a game-entity might have a few dozen modifiers out of hundreds)... really seems to push for association-by-name-only. At least that's all my brain gravitates toward. -Tony --047d7b621fbae5f2ec04d97e4a89 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
I think I might be up against a brick wall. But maybe= there's a door I don't
see, without Obj.magicing mys= elf through the wall. (I haven't had to use magic
for anythin= g yet!) :)

I want to stash values under a key, and retrieve them b= y that key. All values
bound to a given key are of the same type,= but the type will differ between
keys. Basically like a hashtabl= e you'd find in a dynamic language.

=A0 (* modifier-additions like this would be scattered = across the code-base *)
=A0 contribute `RecoveryRoll (fun (a,b) -= > a+3,b)
=A0 contribute `RecoveryRoll (fun (a,b) -> a,b-1)<= /div>
=A0 contribute `ResistPain (fun a -> a+1)
=A0 contribute = `MagicResistance (fun a -> match a with None -> None | Some x -> S= ome(x+3))
=A0 contribute `MagicResistance (fun a -> match a wi= th None -> Some 7 | Some x -> Some(x+7))

=A0 (* example of applying modifiers... *)
= =A0 let modified =3D fold `RecoveryRoll (4,1) in
=A0 ...

(There are details I've left out here, like the need f= or 'contribute' returning an id
by which to remove a modifier, as well as control over order-of-applic= ation.)

Now I think the type signature of these fu= nctions would be:

=A0 val contribute: a'. '= ;a key -> ('a -> 'a) -> unit
=A0 val fold: 'a. 'a key -> 'a -> 'a
<= br>
And the thorn in my side would be that the key must be "= keyed" to the type, or
is there an escape? At one point I tr= ied a universal type to "hide" the
signature of the function-list, but I also stashed the inj/proj under = the key
-- well, of course the inj/proj functions had different t= ypes per entry in a
hashtable, so that worked as well as not havi= ng a universal type involved. :)

If I provide the inj/proj functions at each invocation = then I need to
pre-create these and house them somewhere (which c= ould create a bottleneck of
type-dependencies) -- Imagine several= hundred modifiers like `RecoveryRoll;
some might use types that only need visibility in one module. Trying t= o place
each modifier in suitable modules also seems a mess... a = lot of them
conceptually exist "in the spaces between module= s".

So I keep trying to create an airy light-weight "i= mplied" association to
connect modifiers to use-sites... but= to satisfy typing it seems I need to be
explicit at some point.<= /div>

Does anyone have any ideas? I'm often surprised at = the gymnastics OCaml's
type-system can accomplish under the g= uidance of some smart folks. If anyone's
made a heterogenous = dictionary/hashtable that doesn't need types explicity
declared, that would probably be what I'm looking for.
<= br>

Note that I've had this problem surface se= veral times and managed to find
solutions that suited the specifi= c problem, but each problem can have it's
subtle details. In this case, the large number of keys and functions,<= /div>
combined with their spread across codebase and the sparse nature = of their
use (a game-entity might have a few dozen modifiers out = of hundreds)... really
seems to push for association-by-name-only. At least that's all my= brain
gravitates toward.

-Tony

--047d7b621fbae5f2ec04d97e4a89--