Re: Re: Schema for data structures

2009-10-01 Thread Emeka
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

2009-09-27 Thread Miron Brezuleanu

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

2009-09-26 Thread Daniel Werner

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

2009-09-26 Thread Artyom Shalkhakov

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

2009-09-26 Thread Daniel Renfer

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

2009-09-25 Thread Miron Brezuleanu

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

2009-09-24 Thread tmountain

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

2009-09-24 Thread Miron Brezuleanu

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

2009-09-24 Thread Constantine Vetoshev

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

2009-09-24 Thread Richard Newman

 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
-~--~~~~--~~--~--~---