Re: Re: Schema for data structures
Artyom, (provide/contract [interp (- AE? number?)]) ;; interpret an arithmetical expression yielding a number (define (interp exp) ;; type-case is very much like a case ... of in Haskell/ML (type-case AE exp (num (n) n) (plus (l r) (+ (interp l) (interp r))) (sub (l r) (- (interp l) (interp r) It also looks like clojure condp. Emeka Contracts work only between module boundaries though. Cheers, Artyom Shalkhakov. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
Hi, On Sat, Sep 26, 2009 at 3:36 PM, Daniel Werner daniel.d.wer...@googlemail.com wrote: On Sep 24, 10:14 am, Miron Brezuleanu mbr...@gmail.com wrote: about). The degree of typing can be varied (i.e. a person is any map with a :name key, or any map with only a :name key, or any map with a :name key which is nil or string etc.) You may be interested in Konrad Hinsen's (algebraic) data type support in clojure.contrib.types. As far as I've discovered from toying with it, it doesn't seem to cover your vector of persons use case, but it does support matching maps by the keys they contain and the keys' values, but not their types. adt/match co aren't what I need right now, but I missed them when browsing clojure.contrib and they look very useful as type definition tools. Thank you for the pointer. It is very nice to see how much one can learn about related concepts when asking a question. I am amazed at the quality of the Clojure 'platform' (language, libraries, people). Since good deeds don't go unpunished, I guess this means I'll keep asking questions :-) Thank you again, -- Miron Brezuleanu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
On Sep 24, 10:14 am, Miron Brezuleanu mbr...@gmail.com wrote: about). The degree of typing can be varied (i.e. a person is any map with a :name key, or any map with only a :name key, or any map with a :name key which is nil or string etc.) You may be interested in Konrad Hinsen's (algebraic) data type support in clojure.contrib.types. As far as I've discovered from toying with it, it doesn't seem to cover your vector of persons use case, but it does support matching maps by the keys they contain and the keys' values, but not their types. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Fwd: Re: Schema for data structures
Ooops, sent it to the wrong address. -- Forwarded message -- From: Artyom Shalkhakov artyom.shalkha...@gmail.com Date: 2009/9/25 Subject: Re: Schema for data structures To: clojure group nore...@googlegroups.com Hello Miron, is there a way to check if a data structure complies to a given schema? (e.g. people is a vector of persons). I'm using C# a lot and maybe the static typing has changed the way I think. I feel like adding type checks in unit tests and being able to say something like: (is-type (people (vector person))) sounds like a neat way to check types (I know 'vector' is a 'taken' name, I'm just trying to illustrate the kind of syntax I'm thinking about). The degree of typing can be varied (i.e. a person is any map with a :name key, or any map with only a :name key, or any map with a :name key which is nil or string etc.) You might be looking for something akin to contracts of PLT Scheme: http://pre.plt-scheme.org/docs/html/guide/contracts.html there are also define-type and type-case macros (again for Scheme, specifically PLAI language, but I guess they can be translated to Clojure easily), which I find very handy. Can't post the link ATM because PLaneT seems to be down or something though. Here's an example of define-type/type-case in Scheme: (require (planet main.ss (plai plai.plt 1 3))) ;; arithmetical expressions (define-type AE ;; distinguish various cases, ;; very much like a union in C but with an explicit type tag ;; (one of num, plus, sub) ;; not we enforce a contract on each member (num (n number?)) (plus (l AE?) (r AE?)) (sub (l AE?) (r AE?))) (provide/contract [interp (- AE? number?)]) ;; interpret an arithmetical expression yielding a number (define (interp exp) ;; type-case is very much like a case ... of in Haskell/ML (type-case AE exp (num (n) n) (plus (l r) (+ (interp l) (interp r))) (sub (l r) (- (interp l) (interp r) Contracts work only between module boundaries though. Cheers, Artyom Shalkhakov. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
One of the things I'm doing in my application is I modified clj-record to attach metadata about the record's type to each record when find- records is used. I am then able to have a function that checks that metadata which can be used as a predicate. It gets even better because I can then write multi-methods that dispatch on the type of record I have. You will have to take care that your multimethods will only work if you have the metadata attached, so you'll have to take care to with-meta any records you create yourself. my fork of clj-record is on github On Sep 24, 2009, at 4:14 AM, Miron Brezuleanu wrote: Hello, is there a way to check if a data structure complies to a given schema? (e.g. people is a vector of persons). I'm using C# a lot and maybe the static typing has changed the way I think. I feel like adding type checks in unit tests and being able to say something like: (is-type (people (vector person))) sounds like a neat way to check types (I know 'vector' is a 'taken' name, I'm just trying to illustrate the kind of syntax I'm thinking about). The degree of typing can be varied (i.e. a person is any map with a :name key, or any map with only a :name key, or any map with a :name key which is nil or string etc.) I browsed through clojure.test (which is clojure.contrib.test-is integrated into Clojure, right?) but couldn't find something like this. Thank you, -- Miron Brezuleanu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
Hi, thanks for the suggestions about writing an alternate defstruct. I tried to turn the wishful thinking from my initial email into code. Results here: http://github.com/mbrezu/beak-check Testing structures with beak-check requires some code, but it allows to test nested structures and testing the type of the structure members. I welcome any thoughts/ideas/critiques. Thanks again, On Thu, Sep 24, 2009 at 7:39 PM, Richard Newman holyg...@gmail.com wrote: Use it just like you use defstruct, e.g.: (defstruct* person :first- name :last-name :age), but it will also create a little type-checker function: is-person? Here are some tests to see how it works: Note that your type checker will give false positives if you're intending to use accessors: an ordinary map with the same keys will match the predicate, but accessor calls will fail. (I also have a defstruct*, but it defines accessors and a struct-map coercion, not a predicate :)) -- Miron Brezuleanu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
You might be looking for the instance? function. It can be used to determine if something is an instance of a particular class. user= (instance? java.lang.Integer 5) true user= (instance? java.lang.Integer 5) false To apply that to a data structure, you'd need to walk your structure and compare the elements contained within against the desired type. Depending on the structure, you could do something similar to this. (defn exclusively-contains-type? [datatype coll] (every? true? (map #(instance? datatype %1) coll))) (def my-data [1 2 3]) (println (exclusively-contains-type? java.lang.Integer my-data)) true (println (exclusively-contains-type? java.lang.Integer [1 2 3 a])) false This being said, Clojure is dynamically typed for a reason. It's best not to enforce types with an iron fist unless you absolutely have to. I've written large amounts of code without ever worrying about the explicit concrete type working behind the scenes, but if it gives you warm fuzzies, then by all means ;-). -Travis On Sep 24, 4:14 am, Miron Brezuleanu mbr...@gmail.com wrote: Hello, is there a way to check if a data structure complies to a given schema? (e.g. people is a vector of persons). I'm using C# a lot and maybe the static typing has changed the way I think. I feel like adding type checks in unit tests and being able to say something like: (is-type (people (vector person))) sounds like a neat way to check types (I know 'vector' is a 'taken' name, I'm just trying to illustrate the kind of syntax I'm thinking about). The degree of typing can be varied (i.e. a person is any map with a :name key, or any map with only a :name key, or any map with a :name key which is nil or string etc.) I browsed through clojure.test (which is clojure.contrib.test-is integrated into Clojure, right?) but couldn't find something like this. Thank you, -- Miron Brezuleanu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
Hello, On Thu, Sep 24, 2009 at 5:09 PM, tmountain tinymount...@gmail.com wrote: To apply that to a data structure, you'd need to walk your structure and compare the elements contained within against the desired type. Depending on the structure, you could do something similar to this. (defn exclusively-contains-type? [datatype coll] (every? true? (map #(instance? datatype %1) coll))) Thanks for the suggestions, walking the structure seems like the way to go. This being said, Clojure is dynamically typed for a reason. It's best not to enforce types with an iron fist unless you absolutely have to. I've written large amounts of code without ever worrying about the explicit concrete type working behind the scenes, but if it gives you warm fuzzies, then by all means ;-). Well, I only want to enforce duck-typing :-) - for instance, make sure via unit tests that a function that should return a data structure with certain properties always returns such a data structure. I'll try to formalize my fuzzy ideas as code. Thanks for giving me some starting points. -- Miron Brezuleanu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
On Sep 24, 10:59 am, Miron Brezuleanu mbr...@gmail.com wrote: Well, I only want to enforce duck-typing :-) - for instance, make sure via unit tests that a function that should return a data structure with certain properties always returns such a data structure. Not exactly what you asked for, but I added a defstruct* helper to my utils.clj. I'm still not entirely sure it's a good idea, but here it is: (defmacro defstruct* Wrapper for defstruct which also creates a simple duck type checking function. [name slots] `(do (defstruct ~name ~...@slots) (defn ~(symbol (str is- name ?)) [x#] (if (map? x#) (let [sample# (struct ~name)] (empty? (clojure.set/difference (set (keys sample#)) (set (keys x#) false Use it just like you use defstruct, e.g.: (defstruct* person :first- name :last-name :age), but it will also create a little type-checker function: is-person? Here are some tests to see how it works: (defstruct* duck-typed-struct :a :b :c) (deftest duck-typed-predicates (let [dt1 (struct duck-typed-struct 1 2 3) dt2 {:a 4 :b 5 :c 6} dt3 (struct duck-typed-struct 1 2) dt4 {:a 4 :b 5 :c nil} not-dt1 {:a 4 :b 5} not-dt2 {:d 7 :e 8} not-dt3 {:a 4 :b 5 :d 7}] (is (is-duck-typed-struct? dt1)) (is (is-duck-typed-struct? dt2)) (is (is-duck-typed-struct? dt3)) (is (is-duck-typed-struct? dt4)) (is (not (is-duck-typed-struct? not-dt1))) (is (not (is-duck-typed-struct? not-dt2))) (is (not (is-duck-typed-struct? not-dt3) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Schema for data structures
Use it just like you use defstruct, e.g.: (defstruct* person :first- name :last-name :age), but it will also create a little type-checker function: is-person? Here are some tests to see how it works: Note that your type checker will give false positives if you're intending to use accessors: an ordinary map with the same keys will match the predicate, but accessor calls will fail. (I also have a defstruct*, but it defines accessors and a struct-map coercion, not a predicate :)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---