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 C4CBE7EE51 for ; Fri, 5 Apr 2013 21:55:25 +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=209.85.215.171; 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 209.85.215.171 as permitted sender) identity=mailfrom; client-ip=209.85.215.171; 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-ea0-f171.google.com) identity=helo; client-ip=209.85.215.171; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="anthony.tavener@gmail.com"; x-sender="postmaster@mail-ea0-f171.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ai0CAMUrX1HRVderjWdsb2JhbABBCoM8rw+JY4gzgQUIFg4BAQEBBwsLCRIGJIIfAQEEARoNGQEbEgsBAwELBgULAwoNDAIFDiEBAREBBQEKEgYTEgmHZgEDCQYMo2WML4J7SIQIChknAwpZPohAAQUMjD2BBhAEgTQEBycCgxcDiHyMEoFggSCKUoM5FimETR2BER0CBxc X-IPAS-Result: Ai0CAMUrX1HRVderjWdsb2JhbABBCoM8rw+JY4gzgQUIFg4BAQEBBwsLCRIGJIIfAQEEARoNGQEbEgsBAwELBgULAwoNDAIFDiEBAREBBQEKEgYTEgmHZgEDCQYMo2WML4J7SIQIChknAwpZPohAAQUMjD2BBhAEgTQEBycCgxcDiHyMEoFggSCKUoM5FimETR2BER0CBxc X-IronPort-AV: E=Sophos;i="4.87,416,1363129200"; d="scan'208";a="12035742" Received: from mail-ea0-f171.google.com ([209.85.215.171]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 05 Apr 2013 21:55:24 +0200 Received: by mail-ea0-f171.google.com with SMTP id b15so1527592eae.16 for ; Fri, 05 Apr 2013 12:55:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=hLtfmEK2xcdzjlvwzSfIIr+J77ynvbDJpJe2SOTzSiw=; b=ib5H9wuCuHcdgSDorrn01/pVUQ4lC4uRMGlLUFKvsEtbCEaNsJst6wtRPvJROVwj6s nyMmzcE3ZKE8y33uDUrNaDFz9w4RDWFpekUd7dV5qCknx4Mz7VeHdhuPklGozIGKBZRk O87ZbiiRuQ7hT8Rx7LcjM/u1JYZBNJMyaHBB7ZqwuaD/U0RY1di+HUC45BEUXZGvpfec jA2C6ba5Lk33sJvhWbW5DsRaFgcJ+r3boNSbYAJ9uniLle+z4yHkwFGjCgiEhdLzrOGy rp5vytG4fDMD+Blte24rxEeMB30l2Gzjk+brqjwfFxLWVNYQy1biqAPEisY9gzayB7ZE rfWA== MIME-Version: 1.0 X-Received: by 10.15.24.14 with SMTP id i14mr22055877eeu.25.1365191723559; Fri, 05 Apr 2013 12:55:23 -0700 (PDT) Received: by 10.14.2.198 with HTTP; Fri, 5 Apr 2013 12:55:23 -0700 (PDT) In-Reply-To: References: Date: Fri, 5 Apr 2013 13:55:23 -0600 Message-ID: From: Anthony Tavener To: Yaron Minsky Cc: "caml-list@inria.fr" Content-Type: multipart/alternative; boundary=089e0160c9bebbdef404d9a2771a Subject: Re: [Caml-list] Heterogeneous dictionary --089e0160c9bebbdef404d9a2771a Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Hmm... that is some food for thought. I wasn't really considering the creation of modules which might only hold a few keys. Sometimes we overlook simple things. :) You've convinced me enough to work with it and see how it fits -- it sounds like you've had similar cases, and turning out "prettily" is appealing. I do have a pattern of Module.t. I remember thinking that was an odd idiom, at first, and used an "appropriate" full name. Once I really started using modules, and especially functors, I saw the light. Is there a design patterns for OCaml, somewhere? :) Thank-you for wading through my walls of text and still offering advice, Yaron! On Fri, Apr 5, 2013 at 12:51 PM, Yaron Minsky wrote: > On Fri, Apr 5, 2013 at 2:27 PM, Anthony Tavener > wrote: > >> Sure, but there's nothing that requires these to be stored together. > >> They can be scattered to the four winds, and yet all used to keep > >> things in the same Univ_map.t. > > > > I was working with a universal type, but that was exactly the > > problem I encountered: I need to create the keys and hold them > > somewhere. My original post might have been unclear, sorry. This is > > what I meant by having to pre-create the inj/proj pair and house > > them somewhere... where a single file would create a bottleneck of > > types, or scattered becomes a "mess". Scattered would prove > > confusing I think... with hundreds of keys that have no sensible > > "home" module. Well, some might make sense, but most of these keys > > are interstitial -- between modules, somewhat like messages. I was > > trying to map out where various keys would live and it wasn't > > obvious and would continue to be unclear when I wanted to use a > > key. There would be cognitive burden of deciding home modules for > > things which don't fit into the modular namespace. > > My experience with this kind of design is that this isn't that much of > a problem. You can create multiple modules that house keys for > different concerns. Indeed, in such designs I've historically created > modules with typeful interfaces that back-end on such keys, but simply > expose a typeful way of getting access to the properties in question, > which I think turns out quite prettily. > > > So, a universal type with "keys" does solve the problem, for some > > definition of solved. My concern is that the solution is too > > cumbersome and confusing in this use-case. Very much like arguments > > for polymorphic variants versus variants. Unfortunately I don't see > > any way to "embed type" in a polymorphic variant (I did check > > whether hashes could match between different function > > implementations of same type-signature... which was kind of silly > > because I'm pretty sure the function address would be used in the > > hashvalue). Although I imagine types do have hashvalues at some > > point in the compiler! > > Again, If you create wrapper modules for accessing and working with > these properties, I think everything will work smoothly. Indeed, if > you have a module T for a given type of thing to be stored in one of > these maps, you can build your typeful accessors for T.t into module > T. You just need to follow the design pattern of having one module > per type you define. > > > Another (failed?) possibility I mentioned as a pipe-dream: if "keys" > > could be left open "to trust", and then verified that all trusted > > usages lined up at link-time. After you're first reply (Yaron), I > > thought for a moment that monomorphic types might work like that -- > > resolved at link time. Of course, they're not, as a test quickly > > confirmed. :( But... that's why I asked the wise body of OCamlers if > > you have ideas -- I don't have a complete grasp of the language and > > might be missing something or have a false assumption. It's a > > complex type-system! I like it a lot though. > > > > Thinking more about this, and formulating these replies, I've > > realized there's a common idiom in game development -- and maybe > > software in general? It's use of string-hashes to create flexible > > associations... from code to code, or code to data (I think that's > > how it starts... you need to share "IDs" between code and data -- > > and then the technique spreads). Messages, names of special points > > in artwork (eg "primary-grip"), effects, things accessible by > > script... But with such extensive usage, you need tools to verify > > correct usage as much as possible. C, of course, provides few > > guarantees of anything, so you write your own tools. OCaml is > > tantalizing with its rich typesystem -- and polymorphic variants are > > like built-in string-hash support. So I kept trying to figure out a > > way to get OCaml to do the heavy lifting... for idioms I might be > > unreasonably stuck on. ;) > > Maybe. My intuition is that the design pattern you're talking about > is a good one, and really can be made to work well in OCaml. > > y > > > On Fri, Apr 5, 2013 at 10:37 AM, Yaron Minsky > > wrote: > >> > >> On Thu, Apr 4, 2013 at 2:48 PM, Anthony Tavener > >> wrote: > >> > The problem here... > >> > > >> > module Keys : sig > >> > val recovery : int Univ_map.Key.t > >> > val resist_pain : float Univ_map.Key.t > >> > ... > >> > > >> > Would be that Keys would now have dependence on types spanning the > >> > codebase. > >> > >> Sure, but there's nothing that requires these to be stored together. > >> They can be scattered to the four winds, and yet all used to keep > >> things in the same Univ_map.t. > >> > >> It's honestly very much like using a dynamic language, where you get > >> to declare new items at will that can be cast in and out from a > >> universal type. > >> > >> It's probably worth reading over the Univ module in Core as well, > >> since Univ_map is built on it, and if Univ_map doesn't quite do what > >> you want, you can probably built what you need precisely on top of > >> Univ. > >> > >> > Say these modifiers use Wounds.t, Fatigue.t, Ability.Score.t, ... > There > >> > are > >> > a > >> > lot of types, which mostly have a limited scope (their own module and > a > >> > few > >> > others). Wouldn't it be a problem to have all types brought into this > >> > one > >> > module, which every other module also becomes dependent on? Maybe it > >> > just > >> > feels like a problem but it's just an aesthetic -- Would you do this? > A > >> > few > >> > hundred keys involving types from half the modules of the codebase? > >> > > >> > > >> > I'm trying to use these "modifiers" for code organisation -- declari= ng > >> > snippets of functionality (all of signature 'a -> 'a... to return > >> > modified > >> > input) in a lightweight manner, which can be applied elsewhere. > >> > > >> > For example, the Virtue module can add a lot of modifers to an entity > >> > (UID). > >> > Say one entity has virtues of Agility, Inspirational, and Sun-cyclic > >> > Magic, > >> > which each adding a few modifier functions keyed to various contexts > >> > (sun-cyclic magic: "Casting" is +3 while the sun is up). The > associated > >> > modifiers would be picked up in code spread throughout the > application. > >> > Rules > >> > for combat, spellcasting, even character dialog... > >> > > >> > Rather than having character dialog checking for "does he have this > >> > virtue, > >> > or > >> > that one? How about this ability? Spell-effects? Reputations? ..." I > >> > want to > >> > apply all appropriate/active modifiers for entity and situation which > >> > come > >> > from other rules. So, dialog code might have a current_value, then... > >> > eg. > >> > let modified_value =3D apply_modifiers_for_context entity `CharmRo= ll > >> > current_value > >> > > >> > There is a lot of work on my project which I've been avoiding because > >> > the > >> > direct approach is building hairy nests of checks which call out to > code > >> > everywhere... effectively splitting logic between the point of origin > of > >> > a > >> > rule, and the point of application of it. I'd rather declare the > >> > individual > >> > rules, each in one piece, and "magically" apply the aggregate of > rules. > >> > > >> > > >> > In a way, what I'm looking for is having a grand-central lookup, whi= ch > >> > *trusts* that I'm using the right keys at the right time (where the > keys > >> > are > >> > purely symbolic with no type info)... but it would be nice if once t= he > >> > whole > >> > program is compiled it could identify whether that trust was broken > >> > afterall. > >> > A bit of a pipe-dream, and maybe even flawed logic. :) > >> > > >> > It might sound like I'm being too picky or even whiney... that > declaring > >> > keys > >> > throughout the code is unacceptable, or having a file dependent on a= ll > >> > types > >> > is problematic... maybe I am? The first seems disorganised and adds a > >> > mental burden to deciding and knowing where keys live; the second is= a > >> > problem, isn't it? > >> > > >> > Dynamic languages can do what I want at the cost of typesafety. So I > >> > might > >> > just prefer to make that same tradeoff for one mechanism in my code.= .. > >> > "famous > >> > last words"? I hope not. I hope it just works and I don't have > >> > nightmares > >> > about lurking segfaults. :) > >> > > >> > > >> > On Thu, Apr 4, 2013 at 3:04 AM, David House > >> > wrote: > >> >> > >> >> I don't quite understand the problem. Here's an example of how one > >> >> might use univ_map: > >> >> > >> >> open Core.Std > >> >> > >> >> module Keys : sig > >> >> val recovery : int Univ_map.Key.t > >> >> val resist_pain : float Univ_map.Key.t > >> >> end =3D struct > >> >> let recovery =3D Univ_key.Key.create "recovery" Int.sexp_of_t > >> >> let resist_pain =3D Univ_key.Key.create "resist_pain" Float.sexp_= of_t > >> >> end > >> >> > >> >> (In practice this might be two files: keys.ml with the > implementation > >> >> and keys.mli with the signature.) You can then add things as follow= s: > >> >> > >> >> let add map ~key ~data =3D Univ_map.add_exn map key data in > >> >> let map =3D > >> >> Univ_map.empty > >> >> |> add ~key:Keys.recovery ~data:4 > >> >> |> add ~key:Keys.resist_pain ~data:10. > >> >> in > >> >> ... > >> >> > >> >> On 4 April 2013 09:37, Anthony Tavener > >> >> wrote: > >> >> > Thank-you for the advice and pointers, folks... > >> >> > > >> >> > Well, the common problem is still the same one I've been struggli= ng > >> >> > with: > >> >> > "creating keys", and having to access them. > >> >> > > >> >> > I can't create keys "type-free" in a common module. As I figured.= .. > >> >> > having > >> >> > "modifier.ml" with a bunch of Key.create will have monomorphic > types > >> >> > which > >> >> > can't be resolved since with no usage in that module to make the > type > >> >> > concrete. I had a nagging feeling I'd need a "whole-program" > >> >> > compiler... > >> >> > > >> >> > Instead I'd have to create keys in modules where they are used... > but > >> >> > then I > >> >> > might have a mess of keys like Wounds.recovery, Combat.resist_pai= n, > >> >> > ... > >> >> > the > >> >> > problem being that only a fraction of these keys actually make > sense > >> >> > being > >> >> > associated to a particular module, and it gets confusing to know > >> >> > which > >> >> > (of > >> >> > several candidates) I decided to stash them into. This was the > >> >> > attraction to > >> >> > polymorphic variants (which I rarely use) -- they give a > pre-ordained > >> >> > unique > >> >> > ID based on a simple name... no declaration, and no module > prefixing, > >> >> > which > >> >> > seems important to me for this case. > >> >> > > >> >> > Note that I have a "database" of tables with different types > >> >> > (implemented by > >> >> > first-class modules!), and it works great for the bulk of my > >> >> > game-state, > >> >> > but > >> >> > each table is well-populated and heavily used in consistent manne= r. > >> >> > These > >> >> > modifiers though... they're a bit like ad-hoc message passing, > where > >> >> > I > >> >> > can > >> >> > submit any message and anywhere else add a snippet of code to > >> >> > interpret > >> >> > it > >> >> > (not that I have any of that going on, otherwise it might hold the > >> >> > solution!). > >> >> > > >> >> > > >> >> > > >> >> > On Thu, Apr 4, 2013 at 1:38 AM, Rapha=EBl Proust < > raphlalou@gmail.com> > >> >> > wrote: > >> >> >> > >> >> >> On Thu, Apr 4, 2013 at 1:45 AM, Anthony Tavener > >> >> >> wrote: > >> >> >> > [=85] > >> >> >> > >> >> >> And yet-another-solution, Ocsigen's Polytable: > >> >> >> http://ocsigen.org/ocsigenserver/api/Polytables > >> >> >> > >> >> >> > >> >> >> Cheers, > >> >> >> -- > >> >> >> ______________ > >> >> >> Rapha=EBl Proust > >> >> > > >> >> > > >> > > >> > > > > > > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > --089e0160c9bebbdef404d9a2771a Content-Type: text/html; charset=windows-1252 Content-Transfer-Encoding: quoted-printable
Hmm... that is some food for thought. I wasn't really = considering
the creation of modules which might only hold a few k= eys.
Sometimes we overlook simple things. :) You've con= vinced me
enough to work with it and see how it fits -- it sounds like you= 've
had similar cases, and turning out "prettily&q= uot; is appealing.

I do have a pattern= of Module.t. I remember thinking that was
an odd idiom, at first, and used an "appropriate"= ; full name. Once
I really started using modules, and espec= ially functors, I saw the
light. Is there a design patterns= for OCaml, somewhere? :)

Thank-you for wading through my walls = of text and still offering
advice, Yaron!


On Fri, Apr 5, 2013= at 12:51 PM, Yaron Minsky <yminsky@janestreet.com> wro= te:
My experience with this kind of design is that this isn't that mu= ch of
a problem. =A0You can create multiple modules that house keys for
different concerns. =A0Indeed, in such designs I've historically create= d
modules with typeful interfaces that back-end on such keys, but simply
expose a typeful way of getting access to the properties in question,
which I think turns out quite prettily.

> So, a universal type with "keys" does solve the problem, for= some
> definition of solved. My concern is that the solution is too
> cumbersome and confusing in this use-case. Very much like arguments
> for polymorphic variants versus variants. Unfortunately I don't se= e
> any way to "embed type" in a polymorphic variant (I did chec= k
> whether hashes could match between different function
> implementations of same type-signature... which was kind of silly
> because I'm pretty sure the function address would be used in the<= br> > hashvalue). Although I imagine types do have hashvalues at some
> point in the compiler!

Again, If you create wrapper modules for accessing and working with these properties, I think everything will work smoothly. =A0Indeed, if
you have a module T for a given type of thing to be stored in one of
these maps, you can build your typeful accessors for T.t into module
T. =A0You just need to follow the design pattern of having one module
per type you define.

> Another (failed?) possibility I mentioned as a pipe-dream: if "ke= ys"
> could be left open "to trust", and then verified that all tr= usted
> usages lined up at link-time. After you're first reply (Yaron), I<= br> > thought for a moment that monomorphic types might work like that --
> resolved at link time. Of course, they're not, as a test quickly > confirmed. :( But... that's why I asked the wise body of OCamlers = if
> you have ideas -- I don't have a complete grasp of the language an= d
> might be missing something or have a false assumption. It's a
> complex type-system! I like it a lot though.
>
> Thinking more about this, and formulating these replies, I've
> realized there's a common idiom in game development -- and maybe > software in general? =A0It's use of string-hashes to create flexib= le
> associations... from code to code, or code to data (I think that's=
> how it starts... you need to share "IDs" between code and da= ta --
> and then the technique spreads). =A0Messages, names of special points<= br> > in artwork (eg "primary-grip"), effects, things accessible b= y
> script... =A0But with such extensive usage, you need tools to verify > correct usage as much as possible. C, of course, provides few
> guarantees of anything, so you write your own tools. OCaml is
> tantalizing with its rich typesystem -- and polymorphic variants are > like built-in string-hash support. So I kept trying to figure out a
> way to get OCaml to do the heavy lifting... for idioms I might be
> unreasonably stuck on. ;)

Maybe. =A0My intuition is that the design pattern you're talking = about
is a good one, and really can be made to work well in OCaml.

y

> On Fri, Apr 5, 2013 at 10:37 AM, Yaron Minsky <
yminsky@janestreet.com>
> wrote:
>>
>> On Thu, Apr 4, 2013 at 2:48 PM, Anthony Tavener
>> <anthony.tavener@g= mail.com> wrote:
>> > The problem here...
>> >
>> > =A0 module Keys : sig
>> > =A0 =A0 val recovery : int Univ_map.Key.t
>> > =A0 =A0 val resist_pain : float =A0Univ_map.Key.t
>> > =A0 =A0 ...
>> >
>> > Would be that Keys would now have dependence on types spannin= g the
>> > codebase.
>>
>> Sure, but there's nothing that requires these to be stored tog= ether.
>> They can be scattered to the four winds, and yet all used to keep<= br> >> things in the same Univ_map.t.
>>
>> It's honestly very much like using a dynamic language, where y= ou get
>> to declare new items at will that can be cast in and out from a
>> universal type.
>>
>> It's probably worth reading over the Univ module in Core as we= ll,
>> since Univ_map is built on it, and if Univ_map doesn't quite d= o what
>> you want, you can probably built what you need precisely on top of=
>> Univ.
>>
>> > Say these modifiers use Wounds.t, Fatigue.t, Ability.Score.t,= ... There
>> > are
>> > a
>> > lot of types, which mostly have a limited scope (their own mo= dule and a
>> > few
>> > others). Wouldn't it be a problem to have all types broug= ht into this
>> > one
>> > module, which every other module also becomes dependent on? M= aybe it
>> > just
>> > feels like a problem but it's just an aesthetic -- Would = you do this? A
>> > few
>> > hundred keys involving types from half the modules of the cod= ebase?
>> >
>> >
>> > I'm trying to use these "modifiers" for code or= ganisation -- declaring
>> > snippets of functionality (all of signature 'a -> '= ;a... to return
>> > modified
>> > input) in a lightweight manner, which can be applied elsewher= e.
>> >
>> > For example, the Virtue module can add a lot of modifers to a= n entity
>> > (UID).
>> > Say one entity has virtues of Agility, Inspirational, and Sun= -cyclic
>> > Magic,
>> > which each adding a few modifier functions keyed to various c= ontexts
>> > (sun-cyclic magic: "Casting" is +3 while the sun is= up). The associated
>> > modifiers would be picked up in code spread throughout the ap= plication.
>> > Rules
>> > for combat, spellcasting, even character dialog...
>> >
>> > Rather than having character dialog checking for "does h= e have this
>> > virtue,
>> > or
>> > that one? How about this ability? Spell-effects? Reputations?= ..." I
>> > want to
>> > apply all appropriate/active modifiers for entity and situati= on which
>> > come
>> > from other rules. So, dialog code might have a current_value,= then...
>> > eg.
>> > =A0 let modified_value =3D apply_modifiers_for_context entity= `CharmRoll
>> > current_value
>> >
>> > There is a lot of work on my project which I've been avoi= ding because
>> > the
>> > direct approach is building hairy nests of checks which call = out to code
>> > everywhere... effectively splitting logic between the point o= f origin of
>> > a
>> > rule, and the point of application of it. I'd rather decl= are the
>> > individual
>> > rules, each in one piece, and "magically" apply the= aggregate of rules.
>> >
>> >
>> > In a way, what I'm looking for is having a grand-central = lookup, which
>> > *trusts* that I'm using the right keys at the right time = (where the keys
>> > are
>> > purely symbolic with no type info)... but it would be nice if= once the
>> > whole
>> > program is compiled it could identify whether that trust was = broken
>> > afterall.
>> > A bit of a pipe-dream, and maybe even flawed logic. :)
>> >
>> > It might sound like I'm being too picky or even whiney...= that declaring
>> > keys
>> > throughout the code is unacceptable, or having a file depende= nt on all
>> > types
>> > is problematic... maybe I am? The first seems disorganised an= d adds a
>> > mental burden to deciding and knowing where keys live; the se= cond is a
>> > problem, isn't it?
>> >
>> > Dynamic languages can do what I want at the cost of typesafet= y. So I
>> > might
>> > just prefer to make that same tradeoff for one mechanism in m= y code...
>> > "famous
>> > last words"? I hope not. I hope it just works and I don&= #39;t have
>> > nightmares
>> > about lurking segfaults. :)
>> >
>> >
>> > On Thu, Apr 4, 2013 at 3:04 AM, David House <dhouse@janestreet.com>
>> > wrote:
>> >>
>> >> I don't quite understand the problem. Here's an e= xample of how one
>> >> might use univ_map:
>> >>
>> >> open Core.Std
>> >>
>> >> module Keys : sig
>> >> =A0 val recovery : int Univ_map.Key.t
>> >> =A0 val resist_pain : float =A0Univ_map.Key.t
>> >> end =3D struct
>> >> =A0 let recovery =3D Univ_key.Key.create "recovery&q= uot; Int.sexp_of_t
>> >> =A0 let resist_pain =3D Univ_key.Key.create "resist_= pain" Float.sexp_of_t
>> >> end
>> >>
>> >> (In practice this might be two files: keys.ml with the implementation
>> >> and keys.mli with the signature.) You can then add things= as follows:
>> >>
>> >> let add map ~key ~data =3D Univ_map.add_exn map key data = in
>> >> let map =3D
>> >> =A0 Univ_map.empty
>> >> =A0 |> add ~key:Keys.recovery ~data:4
>> >> =A0 |> add ~key:Keys.resist_pain ~data:10.
>> >> in
>> >> ...
>> >>
>> >> On 4 April 2013 09:37, Anthony Tavener <anthony.tavener@gmail.com>
>> >> wrote:
>> >> > Thank-you for the advice and pointers, folks...
>> >> >
>> >> > Well, the common problem is still the same one I'= ;ve been struggling
>> >> > with:
>> >> > "creating keys", and having to access them= .
>> >> >
>> >> > I can't create keys "type-free" in a c= ommon module. As I figured...
>> >> > having
>> >> > "modifier.ml" with a bunch of Key.create will have monomorphic t= ypes
>> >> > which
>> >> > can't be resolved since with no usage in that mo= dule to make the type
>> >> > concrete. I had a nagging feeling I'd need a &qu= ot;whole-program"
>> >> > compiler...
>> >> >
>> >> > Instead I'd have to create keys in modules where= they are used... but
>> >> > then I
>> >> > might have a mess of keys like Wounds.recovery, Comb= at.resist_pain,
>> >> > ...
>> >> > the
>> >> > problem being that only a fraction of these keys act= ually make sense
>> >> > being
>> >> > associated to a particular module, and it gets confu= sing to know
>> >> > which
>> >> > (of
>> >> > several candidates) I decided to stash them into. Th= is was the
>> >> > attraction to
>> >> > polymorphic variants (which I rarely use) -- they gi= ve a pre-ordained
>> >> > unique
>> >> > ID based on a simple name... no declaration, and no = module prefixing,
>> >> > which
>> >> > seems important to me for this case.
>> >> >
>> >> > Note that I have a "database" of tables wi= th different types
>> >> > (implemented by
>> >> > first-class modules!), and it works great for the bu= lk of my
>> >> > game-state,
>> >> > but
>> >> > each table is well-populated and heavily used in con= sistent manner.
>> >> > These
>> >> > modifiers though... they're a bit like ad-hoc me= ssage passing, where
>> >> > I
>> >> > can
>> >> > submit any message and anywhere else add a snippet o= f code to
>> >> > interpret
>> >> > it
>> >> > (not that I have any of that going on, otherwise it = might hold the
>> >> > solution!).
>> >> >
>> >> >
>> >> >
>> >> > On Thu, Apr 4, 2013 at 1:38 AM, Rapha=EBl Proust <= ;raphlalou@gmail.com>
>> >> > wrote:
>> >> >>
>> >> >> On Thu, Apr 4, 2013 at 1:45 AM, Anthony Tavener<= br> >> >> >> <anthony.tavener@gmail.com> wrote:
>> >> >> > [=85]
>> >> >>
>> >> >> And yet-another-solution, Ocsigen's Polytabl= e:
>> >> >> http://ocsigen.org/ocsigenserver/api/Polytabl= es
>> >> >>
>> >> >>
>> >> >> Cheers,
>> >> >> --
>> >> >> ______________
>> >> >> Rapha=EBl Proust
>> >> >
>> >> >
>> >
>> >
>
>

--
Caml-list mailing list. =A0Subscription management and archives:
ht= tps://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs
--089e0160c9bebbdef404d9a2771a--