   [number-of-elements exponent]
   (new ZipfDistribution number-of-elements exponent))
 
-
-(defprotocol univariate-real
-  (cdf [d] [d x])
+(defprotocol probability-function
+  (P [d] [d x]))
+(extend-protocol probability-function
+  IntegerDistribution
+  (P
+    ([d] (fn [x] (.probability d x)))
+    ([d x] (.probability d x)))
+  RealDistribution
+  (P
+    ([d] (fn [x] (.probability d x)))
+    ([d x] (.probability d x)))
+  )
+
+(defprotocol density-function
   (pdf [d] [d x])
-  (log-pdf [d] [d x])
-  (mean [d])
-  (variance [d])
-  (support-lower-bound [d])
-  (support-upper-bound [d])
-  (icdf [d] [d x])
-  (support-connected [d])
-  (sample [d] [d n]))
-
-(extend-type RealDistribution
-  univariate-real
-  (cdf
-    ([d x] (.cumulativeProbability d x))
-    ([d] (fn [x] (cdf d x))))
+  (log-pdf [d] [d x]))
+(extend-protocol density-function
+  RealDistribution
   (pdf
     ([d x] (.density d x))
     ([d] (fn [x] (pdf d x))))
   (log-pdf
     ([d x] (.logDensity d x))
-    ([d] (fn [x] (log-pdf d x))))
-  (mean [d] (.getNumericalMean d))
-  (variance [d] (.getNumericalVariance d))
-  (support-lower-bound [d] (.getSupportLowerBound d))
-  (support-upper-bound [d] (.getSupportUpperBound d))
-  (icdf
-    ([d x] (.inverseCumulativeProbability d x))
-    ([d] (fn [x] (icdf d x))))
-  (sample
-    ([d] (.sample d))
-    ([d n] (take n (repeatedly #(sample d)))))
-  )
-
-(extend-type AbstractRealDistribution
-  univariate-real
-  (cdf
-    ([d x] (.cumulativeProbability d x))
-    ([d] (fn [x] (cdf d x))))
-  (pdf
-    ([d x] (.density d x))
-    ([d] (fn [x] (pdf d x))))
-  (log-pdf
-    ([d x] (.logDensity d x))
-    ([d] (fn [x] (log-pdf d x))))
-  (mean [d] (.getNumericalMean d))
-  (variance [d] (.getNumericalVariance d))
-  (support-lower-bound [d] (.getSupportLowerBound d))
-  (support-upper-bound [d] (.getSupportUpperBound d))
-  (icdf
-    ([d x] (.inverseCumulativeProbability d x))
-    ([d] (fn [x] (icdf d x))))
-  (sample
-    ([d] (.sample d))
-    ([d n] (take n (repeatedly #(sample d)))))
-  )
-
-(defprotocol univariate-integer
-  (cdf [d] [d x])
+    ([d] (fn [x] (log-pdf d x)))))
+
+(defprotocol mass-function
   (pmf [d] [d x])
-  (log-pmf [d] [d x])
-  (mean [d])
-  (variance [d])
-  (support-lower-bound [d])
-  (support-upper-bound [d])
-  (icdf [d] [d x])
-  (support-connected [d])
-  (sample [d] [d n]))
-
-(extend-type IntegerDistribution
-  univariate-integer
-  (cdf
-    ([d x] (.cumulativeProbability d x))
-    ([d] (fn [x] (cdf d x))))
+  (log-pmf [d] [d x]))
+(extend-protocol mass-function
+  IntegerDistribution
   (pmf
     ([d x] (if (integer? x)
              (.probability d x)

    ([d x] (if (integer? x)
             (.logProbability d x)
             Double/NEGATIVE_INFINITY))
    ([d] (fn [x] (log-pdf d x))))
  (mean [d] (.getNumericalMean d))
  (variance [d] (.getNumericalVariance d))
  (support-lower-bound [d] (.getSupportLowerBound d))
  (support-upper-bound [d] (.getSupportUpperBound d))
  (icdf
    ([d x] (.inverseCumulativeProbability d x))
    ([d] (fn [x] (icdf d x))))
  (sample
    ([d] (.sample d))
    ([d n] (take n (repeatedly #(sample d)))))
  )

(extend-type AbstractIntegerDistribution
  univariate-integer
  (cdf
    ([d x] (.cumulativeProbability d x))
    ([d] (fn [x] (cdf d x))))
  (pmf
    ([d x] (if (integer? x)
             (.probability d x)
             0))
    ([d] (fn [x] (pdf d x))))
  (log-pmf
    ([d x] (if (integer? x)
             (.logProbability d x)
             Double/NEGATIVE_INFINITY))
    ([d] (fn [x] (log-pdf d x))))
  (mean [d] (.getNumericalMean d))
  (variance [d] (.getNumericalVariance d))
  (support-lower-bound [d] (.getSupportLowerBound d))
  (support-upper-bound [d] (.getSupportUpperBound d))
  (icdf
    ([d x] (.inverseCumulativeProbability d x))
    ([d] (fn [x] (icdf d x))))
  (sample
    ([d] (.sample d))
    ([d n] (take n (repeatedly #(sample d)))))
  )

(defprotocol exponential-family
  (natural-parameters [dist] )
  (play [dist] (.getMean dist)))

  (new GumbelDistribution location scale))
(defn hypergeometric
  [population-size number-successes sample-size]
  (new HypergeometricDistribution population-size number-successes sample-size))
(defn laplace
  [location scale]
  (new LaplaceDistribution location scale))
