On Thu, Apr 30, 2009 at 10:55 PM, Darren Duncan <dar...@darrenduncan.net> wrote: > John Napiorkowski wrote: >> >> Just curious, how would you feel about an implimentation of dependent >> types where the functional element was predefined and more explicit, such as >> (syntax hypothetical and only partly implemented...) > > <snip> > > I am fine with one being able to create, change, and delete the definitions > of data types at runtime, and in fact in the general case of a long-running > program I would expect to be able to do so. > > What I expect is that the set of (allowed) member values of a data type is > invariant except by changing the definition of the data type. > > And so, a value selector ("object constructor" / "new()") routine, whose > existence and definition automatically falls out of its type's definition > (that is, the act of defining a type also declares that routine), must be a > pure function (that can't invoke 'now'), so that for the entire time that > the actual definition of the type does not change, neither does the set of > values / objects allowed to be selected / constructed of that type. > > However, you are free to create or alter or delete the actual data type > definitions themselves as often as you like, and the process of doing that > can of course be dynamic, where runtime-derived values such as the current > result of 'now' can be used as a parameter to the definition of the type. > > The way I like to think about things is that, while internally the step of > making or changing a type definition, and selecting values of that type, are > internally atomic, they are mutually discrete steps in time. > > For example, here are numbered steps in time: > > 0. No Foo type or Foo values exist. > 1. Fetch current datetime and store in $now variable. > 2. Declare type Foo (and its selector/constructor) using the value in $now > in its definition. > 3. Work with type Foo, selecting and using its values in other variables > etc. > 4. Fetch current datetime into $now. > 5. Alter definition of type Foo using current value of $now. > 6. Work with type Foo. > 7. Repeat steps 4-6 often as you like. > 8. Delete type Foo when done with it. > > My key point here is that any impure activity like updating $now with the > current date is done *outside* of either the act of defining or using the > Foo type. > > Keeping a program defined like this, with separated pure and impure actions, > where the two are associated sequentially in discrete points in time, allows > for cleaner and more deterministic coding. You can effectively have your > DateInThePast type from the perspective of users, but with my proposed > design above, you control exactly when the concept of 'now' changes. The > idea here is that doing it my way will ensure that the concept of 'now' will > never vary within an operation over whose life it is expected to be a > constant. And also, the pure sections can be easier to optimize or memoize > because they can safely assume that things one expects to stay constant will > do so, until you explicitly change them at controlled times. Using 'now' > directly everywhere you want to test for the current date is uncontrolled, > especially if you invoke it multiple times in the same value or constraint > expression. > > Now, this all said, I think the concept of a DateInThePast type still sounds > rather like a bad program design and should be avoided. While you should be > able to alter types at runtime, there are more practical scenarios where > that would be done, and typically doing so would be infrequent (such as a > type representing a list of valid status codes, or representing the format > of what is considered a well-formed address). But I mentioned DateInThePast > as an example because that is what was used before. In practice one should > still just have a Date type and just have appropriate is-in-past > conditionals in the main program where it actually matters. >
I concur all you've said here - I just wanted to add that I've sent the original email after a conversation at #moose about a type constraint checking if a file is existing (or readable etc.). I changed that example into a DateInThePast - so that it was simpler - but this original example might be even better in supporting my thesis that dropping Type in TypeConstraints is what is really needed. -- Zbigniew Lukasiak http://brudnopis.blogspot.com/ http://perlalchemy.blogspot.com/