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 mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 7CF717EE51 for ; Fri, 5 Apr 2013 18:37:17 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of yminsky@janestreet.com) identity=pra; client-ip=38.105.200.229; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yminsky@janestreet.com"; x-sender="yminsky@janestreet.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of yminsky@janestreet.com designates 38.105.200.229 as permitted sender) identity=mailfrom; client-ip=38.105.200.229; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yminsky@janestreet.com"; x-sender="yminsky@janestreet.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@tot-dmz-mxout1.janestreet.com) identity=helo; client-ip=38.105.200.229; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yminsky@janestreet.com"; x-sender="postmaster@tot-dmz-mxout1.janestreet.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhEBANz8XlEmacjlmWdsb2JhbABBCoM8wR+BBB4OAQEBAQEGDQsHFCiCHwEBBAEnGQEBNwEECwsLDS4hARIBBQEcBhMbh2cDCQYDCaMsim+EOwEFhRMNiVcGjEmBFgSBBTMHg0CVEYFggSCKUoM5FimESoFO X-IPAS-Result: AhEBANz8XlEmacjlmWdsb2JhbABBCoM8wR+BBB4OAQEBAQEGDQsHFCiCHwEBBAEnGQEBNwEECwsLDS4hARIBBQEcBhMbh2cDCQYDCaMsim+EOwEFhRMNiVcGjEmBFgSBBTMHg0CVEYFggSCKUoM5FimESoFO X-IronPort-AV: E=Sophos;i="4.87,415,1363129200"; d="scan'208";a="9964052" Received: from mx5.janestreet.com (HELO tot-dmz-mxout1.janestreet.com) ([38.105.200.229]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 05 Apr 2013 18:37:15 +0200 Received: from tot-oib-smtp1.delacy.com ([172.27.22.15] helo=tot-smtp) by tot-dmz-mxout1.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1UO9dZ-0000fN-HL for caml-list@inria.fr; Fri, 05 Apr 2013 12:37:13 -0400 Received: from tot-dmz-mxgoog1.delacy.com ([172.27.224.14] helo=mxgoog2.janestreet.com) by tot-smtp with esmtps (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1UO9dZ-0001N0-G3 for caml-list@inria.fr; Fri, 05 Apr 2013 12:37:13 -0400 Received: from mail-ea0-f197.google.com ([209.85.215.197]) by mxgoog2.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1UO9dZ-0004Nz-BA for caml-list@inria.fr; Fri, 05 Apr 2013 12:37:13 -0400 Received: by mail-ea0-f197.google.com with SMTP id b15so5646143eae.4 for ; Fri, 05 Apr 2013 09:37:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=janestreet.com; s=google; h=x-received:mime-version:x-received:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=ZpL8LMwhb6f80VZHBWUsk2G4wZWrQKfBd111/czblm0=; b=qDQVOoKSZbfQfba6rjzTbVEng2LbDNtg5RH19i+EIlQmlIFbFyNzCRx73Ji49vIAAo Oan0g0M+Z6bBnfoG9FII3qCCbkuYNIGMreGQivXnrUQFKARSoYWcFR/NTWm8zY/XRwSb vuTQL5DZ0fW304eoIHzQl7XnbAmH8WTYBNWQo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:mime-version:x-received:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding:x-gm-message-state; bh=ZpL8LMwhb6f80VZHBWUsk2G4wZWrQKfBd111/czblm0=; b=PkkiKxL+ct9/hYfxpBDNgdxeQRUxnXnquhyMN7R5Yd0hBq2WwVMxe93As/AgYONu08 BhyXWiJO+peGOFe1i01/d5NFEi6OIDQhSm6+pRZmDUsoksqp2Kq4lGzcWIC6sf+kqMR1 DZ9+NqHAFKIIdF6YvO/Skv7Z/oathQrCnbePA3Q5tI79dLx4bJMmOKGc0ctLqn3RO0m6 5RV8vZWX190ZK5T7SCgeE2hp109DGhNlAzmw0E7SIpN6hiB4wxr8YAdGveqZ7tT4i2QJ y0LGT60/AbTe8f279sB6Gg7168owGO/Ai+XR4xbKojve30xgSDX0vVVjUmB4v/6prP+5 cFZQ== X-Received: by 10.205.108.72 with SMTP id eb8mr7289680bkc.111.1365179832687; Fri, 05 Apr 2013 09:37:12 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.205.108.72 with SMTP id eb8mr7289678bkc.111.1365179832524; Fri, 05 Apr 2013 09:37:12 -0700 (PDT) Received: by 10.204.226.78 with HTTP; Fri, 5 Apr 2013 09:37:12 -0700 (PDT) In-Reply-To: References: Date: Fri, 5 Apr 2013 12:37:12 -0400 Message-ID: From: Yaron Minsky To: Anthony Tavener Cc: David House , "caml-list@inria.fr" Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable X-Gm-Message-State: ALoCoQk5WwrMpBcTmX+AE4nIUKCyeptYo2O/bOBfuUFCU+DKwXabPd1hYx+enLQ6rUZD1vdiKQulBlAEOIHHdF7+7q7XewLF8Y3vR4G9217yPSf+0/DyPZC0lNNxN8c9adcpxZGw09r4Vs75pawNmYrnLnZ2+yTNDQ== Subject: Re: [Caml-list] Heterogeneous dictionary 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 codeba= se. 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 a= re > a > lot of types, which mostly have a limited scope (their own module and a f= ew > 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 f= ew > hundred keys involving types from half the modules of the codebase? > > > I'm trying to use these "modifiers" for code organisation -- declaring > 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 (UI= D). > Say one entity has virtues of Agility, Inspirational, and Sun-cyclic Magi= c, > 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 virtu= e, > 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 `CharmRoll > 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 individu= al > 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 wh= ole > 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 all ty= pes > 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 follows: >> >> 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 struggling >> > 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_pain, ... >> > 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-stat= e, >> > but >> > each table is well-populated and heavily used in consistent manner. >> > 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 >> > 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 >> > >> > > >