The realm definitions for active-data are possible in detail with examples

Starting with the project, I missed a short explanation of how to define realms to make it easier for everyone starting to use àctive-data. I'd like to give a short overview:

The annotated defn below comes from active.data.realm.attach. Evaluate these imports before the examples:

(ns yatestenv.realm-examples
  (:refer-clojure :exclude [defn])
  (:require [active.data.realm :as realm]
            [active.data.realm.attach :refer [defn]]
            [active.data.record :as ad]
            [active.data.realm.validation :as validation]
            [clojure.pprint :refer [pprint]])
  (:import [java.util UUID]))

Primitive realms:

(defn my-fun-str :- realm/any ;;function can return any value type 
  [out-string :- realm/string] ;; the argument is only accepted if it is a string 
  (print "I am the out string:" out-string) ;; print the argument
  true)
(my-fun-str "I am a computer scientist")
(defn my-fun-int :- realm/integer ;;function returns an integer value 
  [label :- realm/string
   op1 :- realm/integer
   op2 :- realm/integer] ;; the argument is only accepted if it is an integer
  (let [result (* op1 op2)]
    (print "I am the op1 %d and op2 %d:" op1 op2) ;; print the arguments
    (print label ": %d" result)
    result))
(my-fun-int "Product" 7 8)
(defn my-fun-num :- realm/number ;;function returns a number value 
  [op1 :- realm/number
   op2 :- realm/number] ;; the argument is only accepted if it is a number
  (let [result (* op1 op2)]
    (print "I am the op1 %d and op2 %d:" op1 op2) ;; print the arguments
    (print "Result of multiplication: %d" result)
    result)) 
(defn my-fun-nat :- realm/natural ;;function returns a natural number value 
  [op1 :- realm/natural
   op2 :- realm/natural] ;; the argument is only accepted if it is a natural number
  (let [result (* op1 op2)]
    (print "I am the op1 %d and op2 %d:" op1 op2) ;; print the arguments
    (print "Result of multiplication: %d" result)
    result)) 
(defn my-fun-real :- realm/real ;;function returns a real number value 
  [op1 :- realm/real
   op2 :- realm/real] ;; the arguments are only accepted if they are real numbers
  (let [result (* op1 op2)]
    (print "I am the op1 %d and op2 %d:" op1 op2) ;; print the arguments
    (print "Result of multiplication: %d" result)
    result))
(my-fun-real 0.98 6.78)
(defn my-fun-bool :- realm/boolean ;;function returns a boolean value 
  [op1 :- realm/boolean ;; boolean value false / true
   op2 :- realm/boolean] ;; the argument is only accepted if it is a boolean
  (let [result (or (not op1) op2)]
    (print "I am the op1 %s and op2 %s:" op1 op2) ;; print the arguments
    (print "Result of logical operation: %s" result) ;; print result
    result))
(my-fun-bool true true)
(defn my-fun-sym :- realm/symbol ;;function returns a symbol value 
  [fun-sym :- realm/symbol] ;; the argument is only accepted if it is a symbol
  (let [result (= fun-sym 'my-fun)]
    (pprint result) ;; pretty print the result
    (pprint fun-sym) ;; pretty print the given symbol
    fun-sym))

(my-fun-sym 'any-sym)
(defn my-fun-keyword :- realm/keyword ;;function returns a keyword value 
  [fun-key :- realm/keyword] ;; the argument is only accepted if it is a keyword
  (let [result (= fun-key :my-fun)]
    (pprint result) ;; pretty print the result
    (pprint fun-key) ;; pretty print the given key
    fun-key))
(my-fun-keyword :any-key)
(import (java.util UUID))
(defn my-fun-uuid :- realm/uuid ;;function returns a UUID value 
  [key-id :- realm/uuid] ;; the argument is only accepted if it is a valid UUID  
  (pprint key-id) ;; pretty print the UUID argument
  key-id)
(my-fun-uuid (UUID/randomUUID))

Tuple/Enum definition:

(defn test-enum :- realm/boolean
      [input :- (realm/enum :start :resume :finish :exit)] 
  ;; the argument is only accepted if the value is in the range of the enum
  (let [result (= input :exit)]
    result))
(test-enum :resume) ;; correct call with enum
(defn test-tuple :- realm/boolean
  [input :- (realm/tuple realm/string realm/integer)] 
  ;; argument is only accepted if it is a tuple -> tuple(string, integer)
  (pprint input) ;; pretty print the tuple
  false
  )
(test-tuple ["myint" 23]) 
;; correct call - like a sequence but always two members with 
;; specified realms

Collection enums:

(defn setof-fun :- realm/any
    [the-set :- (realm/set-of (realm/enum :here :there :then :when))] 
  ;; only valid and accepted if the argument is a set of this enum given 
  (pprint the-set) ;; print the given set
  )
(setof-fun #{:here :there}) ;; a correct call
(defn seqof-fun :- realm/any
  [the-seq :- (realm/sequence-of realm/real)]
  ;; only valid and accepted if, in this case, the argument is a sequence of real numbers.
  (pprint the-seq))
(seqof-fun [3.56 7.987]) ;; a correct call
(defn mapof-fun :- realm/any
  [the-map :- (realm/map-of realm/integer (realm/set-of realm/string))]
  ;; only accepted if the argument is a map with a key type of integer and a value type, 
  ;; of a set of strings
  (pprint the-map) 
  )
(mapof-fun {5 #{"hello" "that" "is" "cool"}})

Record realm

(ad/def-record Person
  [person-name :- realm/string
   person-age  :- realm/natural])

(def ada
  (validation/checking
    (Person person-name "Ada"
            person-age 36)))

(person-name ada) ;; => "Ada"
(person-age ada)  ;; => 36
(ad/is-a? Person ada) ;; => true

(def older-ada
  (validation/checking
    (person-age ada 37)))

(person-age older-ada) ;; => 37
(person-age ada)       ;; => 36 (the original is unchanged)

;; With validation enabled, a negative age is rejected.
(try
  (validation/checking
    (Person person-name "Ada"
            person-age -1))
  (catch Exception _
    :invalid-age)) ;; => :invalid-age

Function realm

(defn function-fun :- realm/number 
  [op-fun :- (realm/function realm/number realm/number -> realm/number)
   op1 :- realm/number
   op2 :- realm/number]
  (op-fun op1 op2))
(defn plus :- realm/number
  [op1 :- realm/number
   op2 :- realm/number]
  (+ op1 op2))
(function-fun plus 9.8 7.7)

NOTE: Copyright statement