答:
To expand on @KarlBielefeldt's answer, here's a full example of how to implement Vectors - lists with a statically-known number of elements - in Haskell. Hold on to your hat...

```<code>{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}

import Prelude hiding (foldr, zipWith)
import qualified Prelude
import Data.Type.Equality
import Data.Foldable
import Data.Traversable
</code>```

As you can see from the long list of LANGUAGE directives, this'll only work with a recent version of GHC.

We need a way of representing lengths within the type system. By definition, a natural number is either zero (Z) or it's the successor of some other natural number (S n). So, for example, the number 3 would be written S (S (S Z)).

```<code>data Nat = Z | S Nat
</code>```

With the DataKinds extension, this data declaration introduces a kind called Nat and two type constructors called S and Z - in other words we have type-level natural numbers. Note that the types S and Z don't have any member values - only types of kind * are inhabited by values.

Now we introduce a GADT representing vectors with a known length. Note the kind signature: Vec requires a type of kind Nat (ie a Z or an S type) to represent its length.

```<code>data Vec :: Nat -> * -> * where
    VNil :: Vec Z a
    VCons :: a -> Vec n a -> Vec (S n) a
deriving instance (Show a) => Show (Vec n a)
deriving instance Functor (Vec n)
deriving instance Foldable (Vec n)
deriving instance Traversable (Vec n)
</code>```

The definition of vectors is similar to that of linked lists, with some extra type-level information about its length. A vector is either VNil, in which case it has a length of Z(ero), or it's a VCons cell adding an item to another vector, in which case its length is one more than the other vector (S n). Note that there's no constructor argument of type n. It's just used at compile time to track lengths, and will be erased before the compiler generates machine code.

We've defined a vector type which carries around static knowledge of its length. Let's query the type of a few Vecs to get a feel for how they work:

```<code>ghci> :t (VCons 'a' (VCons 'b' VNil))
(VCons 'a' (VCons 'b' VNil)) :: Vec ('S ('S 'Z)) Char  -- (S (S Z)) means 2
ghci> :t (VCons 13 (VCons 11 (VCons 3 VNil)))
(VCons 13 (VCons 11 (VCons 3 VNil))) :: Num a => Vec ('S ('S ('S 'Z))) a  -- (S (S (S Z))) means 3
</code>```

The dot product proceeds just as it would for a list:

```<code>-- note that the two Vec arguments are declared to have the same length
vap :: Vec n (a -> b) -> Vec n a -> Vec n b
vap VNil VNil = VNil
vap (VCons f fs) (VCons x xs) = VCons (f x) (vap fs xs)

zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c
zipWith f xs ys = fmap f xs `vap` ys

dot :: Num a => Vec n a -> Vec n a -> a
dot xs ys = foldr (+) 0 $ zipWith (*) xs ys
</code>```

vap, which 'zippily' applies a vector of functions to a vector of arguments, is Vec's applicative <*>; I didn't put it in an Applicative instance because it gets messy. Note also that I'm using the foldr from the compiler-generated instance of Foldable.

Let's try it out:

```<code>ghci> let v1 = VCons 2 (VCons 1 VNil)
ghci> let v2 = VCons 4 (VCons 5 VNil)
ghci> v1 `dot` v2
13
ghci> let v3 = VCons 8 (VCons 6 (VCons 1 VNil))
ghci> v1 `dot` v3
<interactive>:20:10:
    Couldn't match type ‘'S 'Z’ with ‘'Z’
    Expected type: Vec ('S ('S 'Z)) a
      Actual type: Vec ('S ('S ('S 'Z))) a
    In the second argument of ‘dot’, namely ‘v3’
    In the expression: v1 `dot` v3
</code>```

Great! You get a compile-time error when you try to dot vectors whose lengths don't match.

Here's an attempt at a function to concatenate vectors together:

```<code>-- This won't compile because the type checker can't deduce the length of the returned vector
-- VNil +++ ys = ys
-- (VCons x xs) +++ ys = VCons x (concat xs ys)
</code>```

The length of the output vector would be the sum of the lengths of the two input vectors. We need to teach the type checker how to add Nats together. For this we use a type-level function:

```<code>type family (n :: Nat) :+: (m :: Nat) :: Nat where
    Z :+: m = m
    (S n) :+: m = S (n :+: m)
</code>```

This type family declaration introduces a function on types called :+: - in other words, it's a recipe for the type checker to calculate the sum of two natural numbers. It's defined recursively - whenever the left operand is greater than Zero we add one to the output and reduce it by one in the recursive call. (It's a good exercise to write a type function which multiplies two Nats.) Now we can make +++ compile:

```<code>infixr 5 +++
(+++) :: Vec n a -> Vec m a -> Vec (n :+: m) a
VNil +++ ys = ys
(VCons x xs) +++ ys = VCons x (concat xs ys)
</code>```

Here's how you use it:

```<code>ghci> VCons 1 (VCons 2 VNil) +++ VCons 3 (VCons 4 VNil)
VCons 1 (VCons 2 (VCons 3 (VCons 4 VNil)))
</code>```

So far so simple. What about when we want to do the opposite of concatenation and split a vector in two? The lengths of the output vectors depend on the runtime value of the arguments. We'd like to write something like this:

```<code>data Nat = Z | S Nat
</code>```0

but unfortunately Haskell won't let us do that. Allowing the value of the n argument to appear in the return type (this is commonly called a dependent function or pi type) would require "full-spectrum" dependent types, whereas DataKinds only gives us promoted type constructors. To put it another way, the type constructors S and Z don't appear at the value level. We'll have to settle for singleton values for a run-time representation of a certain Nat.*

```<code>data Nat = Z | S Nat
</code>```1

For a given type n (with kind Nat), there is precisely one term of type Natty n. We can use the singleton value as a run-time witness for n: learning about a Natty teaches us about its n and vice versa.

```<code>data Nat = Z | S Nat
</code>```2

Let's take it for a spin:

```<code>ghci> split (Sy (Sy Zy)) (VCons 1 (VCons 2 (VCons 3 VNil)))
(VCons 1 (VCons 2 VNil), VCons 3 VNil)
ghci> split (Sy (Sy Zy)) (VCons 3 VNil)
<interactive>:116:21:
    Couldn't match type ‘'S ('Z :+: m)’ with ‘'Z’
    Expected type: Vec ('S ('S 'Z) :+: m) a
      Actual type: Vec ('S 'Z) a
    Relevant bindings include
      it :: (Vec ('S ('S 'Z)) a, Vec m a) (bound at <interactive>:116:1)
    In the second argument of ‘split’, namely ‘(VCons 3 VNil)’
    In the expression: split (Sy (Sy Zy)) (VCons 3 VNil)
</code>```

In the first example, we successfully split a three-element vector at position 2; then we got a type error when we tried to split a vector at a position past the end. Singletons are the standard technique for making a type depend on a value in Haskell.

* The singletons library contains some Template Haskell helpers to generate singleton values like Natty for you.

Last example. What about when you don't know the dimensionality of your vector statically? For example, what if we're trying to build a vector from run-time data in the form of a list? You need the type of the vector to depend on the length of the input list. To put it another way, we can't use foldr VCons VNil to build a vector because the type of the output vector changes with each iteration of the fold. We need to keep the length of the vector a secret from the compiler.

```<code>data AVec a = forall n. AVec (Natty n) (Vec n a)
deriving instance (Show a) => Show (AVec a)

fromList :: [a] -> AVec a
fromList = Prelude.foldr cons nil
    where cons x (AVec n xs) = AVec (Sy n) (VCons x xs)
          nil = AVec Zy VNil
</code>```

AVec is an existential type: the type variable n does not appear in the return type of the AVec data constructor. We're using it to simulate a dependent pair: fromList can't tell you the length of the vector statically, but it can return something you can pattern-match on to learn the length of the vector - the Natty n in the first element of the tuple. As Conor McBride puts it in a related answer, "You look at one thing, and in doing so, learn about another".

This is a common technique for existentially quantified types. Because you can't actually do anything with data for which you don't know the type - try writing a function of data Something = forall a. Sth a - existentials often come bundled up with GADT evidence which allows you to recover the original type by performing pattern-matching tests. Other common patterns for existentials include packaging up functions to process your type (data AWayToGetTo b = forall a. HeresHow a (a -> b)) which is a neat way of doing first-class modules, or building-in a type class dictionary (data AnOrd = forall a. Ord a => AnOrd a) which can help emulate subtype polymorphism.

```<code>ghci> fromList [1,2,3]
AVec (Sy (Sy (Sy Zy))) (VCons 1 (VCons 2 (VCons 3 Nil)))
</code>```

Dependent pairs are useful whenever the static properties of data depend on dynamic information not available at compile time. Here's filter for vectors:

```<code>filter :: (a -> Bool) -> Vec n a -> AVec a
filter f = foldr (\x (AVec n xs) -> if f x
                                    then AVec (Sy n) (VCons x xs)
                                    else AVec n xs) (AVec Zy VNil)
</code>```

To dot two AVecs, we need to prove to GHC that their lengths are equal. Data.Type.Equality defines a GADT which can only be constructed when its type arguments are the same:

```<code>data (a :: k) :~: (b :: k) where
    Refl :: a :~: a  -- short for 'reflexivity'
</code>```

When you pattern-match on Refl, GHC knows that a ~ b. There are also a few functions to help you work with this type: we'll be using gcastWith to convert between equivalent types, and TestEquality to determine whether two Nattys are equal.

To test the equality of two Nattys, we're going to need to make use of the fact that if two numbers are equal, then their successors are also equal (:~: is congruent over S):

```<code>congSuc :: (n :~: m) -> (S n :~: S m)
congSuc Refl = Refl
</code>```

Pattern matching on Refl on the left-hand side lets GHC know that n ~ m. With that knowledge, it's trivial that S n ~ S m, so GHC lets us return a new Refl right away.

Now we can write an instance of TestEquality by straightforward recursion. If both numbers are zero, they are equal. If both numbers have predecessors, they are equal iff the predecessors are equal. (If they're not equal, just return Nothing.)

```<code>instance TestEquality Natty where
    -- testEquality :: Natty n -> Natty m -> Maybe (n :~: m)
    testEquality Zy Zy = Just Refl
    testEquality (Sy n) (Sy m) = fmap congSuc (testEquality n m)  -- check whether the predecessors are equal, then make use of congruence
    testEquality Zy _ = Nothing
    testEquality _ Zy = Nothing
</code>```

Now we can put the pieces together to dot a pair of AVecs of unknown length.

```<code>data Vec :: Nat -> * -> * where
    VNil :: Vec Z a
    VCons :: a -> Vec n a -> Vec (S n) a
deriving instance (Show a) => Show (Vec n a)
deriving instance Functor (Vec n)
deriving instance Foldable (Vec n)
deriving instance Traversable (Vec n)
</code>```0

First, pattern match on the AVec constructor to pull out a runtime representation of the vectors' lengths. Now use testEquality to determine whether those lengths are equal. If they are, we'll have Just Refl; gcastWith will use that equality proof to ensure that dot u v is well-typed by discharging its implicit n ~ m assumption.

```<code>data Vec :: Nat -> * -> * where
    VNil :: Vec Z a
    VCons :: a -> Vec n a -> Vec (S n) a
deriving instance (Show a) => Show (Vec n a)
deriving instance Functor (Vec n)
deriving instance Foldable (Vec n)
deriving instance Traversable (Vec n)
</code>```1

Note that, since a vector without static knowledge of its length is basically a list, we've effectively re-implemented the list version of dot :: Num a => [a] -> [a] -> Maybe a. The difference is that this version is implemented in terms of the vectors' dot. Here's the point: before the type checker will allow you to call dot, you must have tested whether the input lists have the same length using testEquality. I am prone to getting if-statements the wrong way round, but not in a dependently-typed setting!

You can't avoid using existential wrappers at the edges of your system, when you're dealing with runtime data, but you can use dependent types everywhere inside your system and keep the existential wrappers at the edges, when you perform input validation.

Since Nothingis not very informative, you could further refine the type of dot' to return a proof that the lengths aren't equal (in the form of evidence that their difference is not 0) in the failure case. This is pretty similar to the standard Haskell technique of using Either String a to possibly return an error message, although a proof term is far more computationally useful than a string!

Thus ends this whistle-stop tour of some of the techniques that are common in dependently-typed Haskell programming. Programming with types like this in Haskell is really cool, but really awkward at the same time. Breaking up all your dependent data into lots of representations which mean the same thing - Nat the type, Nat the kind, Natty n the singleton - is really quite cumbersome, despite the existence of code-generators to help with the boilerplate. There are also presently limitations on what can be promoted to the type level. It's tantalising though! The mind boggles at the possibilities - in the literature there are examples in Haskell of strongly typed printf, database interfaces, UI layout engines...

If you want some further reading, there's a growing body of literature about dependently typed Haskell, both published and on sites like Stack Overflow. A good starting point is the Hasochism paper - the paper goes through this very example (among others), discussing the painful parts in some detail. The Singletons paper demonstrates the technique of singleton values (such as Natty). For more information about dependent typing in general, the Agda tutorial is a good place to start; also, Idris is a language in development that's (roughly) designed to be "Haskell with dependent types".

Title: Is it possible to "bake dimension into a type" in haskell?

Body:
Suppose I want to write a library that deals with vectors and matrices. Is it possible to bake the dimensions into the types, so that operations of incompatible dimensions generate an error at compile time?

For example I would like the signature of dot product to be something like

```<code>dotprod :: Num a, VecDim d => Vector a d -> Vector a d -> a
</code>```

where the d type contains a single integer value (representing the dimension of these Vectors).

I suppose this could be done by defining (by hand) a separate type for each integer, and group them in a type class called VecDim. Is there some mechanism to "generate" such types?

Or perhaps some better/simpler way of achieving the same thing?

Body:
To expand on @KarlBielefeldt's answer, here's a full example of how to implement Vectors - lists with a statically-known number of elements - in Haskell. Hold on to your hat...

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}

import Prelude hiding (foldr, zipWith)
import qualified Prelude
import Data.Type.Equality
import Data.Foldable
import Data.Traversable

As you can see from the long list of LANGUAGE directives, this'll only work with a recent version of GHC.

We need a way of representing lengths within the type system. By definition, a natural number is either zero (Z) or it's the successor of some other natural number (S n). So, for example, the number 3 would be written S (S (S Z)).

data Nat = Z | S Nat

With the DataKinds extension, this data declaration introduces a kind called Nat and two type constructors called S and Z - in other words we have type-level natural numbers. Note that the types S and Z don't have any member values - only types of kind * are inhabited by values.

Now we introduce a GADT representing vectors with a known length. Note the kind signature: Vec requires a type of kind Nat (ie a Z or an S type) to represent its length.

data Vec :: Nat -> * -> * where
    VNil :: Vec Z a
    VCons :: a -> Vec n a -> Vec (S n) a
deriving instance (Show a) => Show (Vec n a)
deriving instance Functor (Vec n)
deriving instance Foldable (Vec n)
deriving instance Traversable (Vec n)

The definition of vectors is similar to that of linked lists, with some extra type-level information about its length. A vector is either VNil, in which case it has a length of Z(ero), or it's a VCons cell adding an item to another vector, in which case its length is one more than the other vector (S n). Note that there's no constructor argument of type n. It's just used at compile time to track lengths, and will be erased before the compiler generates machine code.

We've defined a vector type which carries around static knowledge of its length. Let's query the type of a few Vecs to get a feel for how they work:

ghci> :t (VCons 'a' (VCons 'b' VNil))
(VCons 'a' (VCons 'b' VNil)) :: Vec ('S ('S 'Z)) Char  -- (S (S Z)) means 2
ghci> :t (VCons 13 (VCons 11 (VCons 3 VNil)))
(VCons 13 (VCons 11 (VCons 3 VNil))) :: Num a => Vec ('S ('S ('S 'Z))) a  -- (S (S (S Z))) means 3

The dot product proceeds just as it would for a list:

-- note that the two Vec arguments are declared to have the same length
vap :: Vec n (a -> b) -> Vec n a -> Vec n b
vap VNil VNil = VNil
vap (VCons f fs) (VCons x xs) = VCons (f x) (vap fs xs)

zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c
zipWith f xs ys = fmap f xs `vap` ys

dot :: Num a => Vec n a -> Vec n a -> a
dot xs ys = foldr (+) 0 $ zipWith (*) xs ys

vap, which 'zippily' applies a vector of functions to a vector of arguments, is Vec's applicative <*>; I didn't put it in an Applicative instance because it gets messy. Note also that I'm using the foldr from the compiler-generated instance of Foldable.

Let's try it out:

ghci> let v1 = VCons 2 (VCons 1 VNil)
ghci> let v2 = VCons 4 (VCons 5 VNil)
ghci> v1 `dot` v2
13
ghci> let v3 = VCons 8 (VCons 6 (VCons 1 VNil))
ghci> v1 `dot` v3
<interactive>:20:10:
    Couldn't match type ‘'S 'Z’ with ‘'Z’
    Expected type: Vec ('S ('S 'Z)) a
      Actual type: Vec ('S ('S ('S 'Z))) a
    In the second argument of ‘dot’, namely ‘v3’
    In the expression: v1 `dot` v3

Great! You get a compile-time error when you try to dot vectors whose lengths don't match.

Here's an attempt at a function to concatenate vectors together:

-- This won't compile because the type checker can't deduce the length of the returned vector
-- VNil +++ ys = ys
-- (VCons x xs) +++ ys = VCons x (concat xs ys)

The length of the output vector would be the sum of the lengths of the two input vectors. We need to teach the type checker how to add Nats together. For this we use a type-level function:

type family (n :: Nat) :+: (m :: Nat) :: Nat where
    Z :+: m = m
    (S n) :+: m = S (n :+: m)

This type family declaration introduces a function on types called :+: - in other words, it's a recipe for the type checker to calculate the sum of two natural numbers. It's defined recursively - whenever the left operand is greater than Zero we add one to the output and reduce it by one in the recursive call. (It's a good exercise to write a type function which multiplies two Nats.) Now we can make +++ compile:

infixr 5 +++
(+++) :: Vec n a -> Vec m a -> Vec (n :+: m) a
VNil +++ ys = ys
(VCons x xs) +++ ys = VCons x (concat xs ys)

Here's how you use it:

ghci> VCons 1 (VCons 2 VNil) +++ VCons 3 (VCons 4 VNil)
VCons 1 (VCons 2 (VCons 3 (VCons 4 VNil)))

So far so simple. What about when we want to do the opposite of concatenation and split a vector in two? The lengths of the output vectors depend on the runtime value of the arguments. We'd like to write something like this:

-- this won't work because there aren't any values of type `S` and `Z`
-- split :: (n :: Nat) -> Vec (n :+: m) a -> (Vec n a, Vec m a)

but unfortunately Haskell won't let us do that. Allowing the value of the n argument to appear in the return type (this is commonly called a dependent function or pi type) would require "full-spectrum" dependent types, whereas DataKinds only gives us promoted type constructors. To put it another way, the type constructors S and Z don't appear at the value level. We'll have to settle for singleton values for a run-time representation of a certain Nat.*

data Natty (n :: Nat) where
    Zy :: Natty Z  -- pronounced 'zed-y'
    Sy :: Natty n -> Natty (S n)  -- pronounced 'ess-y'
deriving instance Show (Natty n)

For a given type n (with kind Nat), there is precisely one term of type Natty n. We can use the singleton value as a run-time witness for n: learning about a Natty teaches us about its n and vice versa.

split :: Natty n ->
         Vec (n :+: m) a ->  -- the input Vec has to be at least as long as the input Natty
         (Vec n a, Vec m a)
split Zy xs = (Nil, xs)
split (Sy n) (Cons x xs) = let (ys, zs) = split n xs
                           in (Cons x ys, zs)

Let's take it for a spin:

ghci> split (Sy (Sy Zy)) (VCons 1 (VCons 2 (VCons 3 VNil)))
(VCons 1 (VCons 2 VNil), VCons 3 VNil)
ghci> split (Sy (Sy Zy)) (VCons 3 VNil)
<interactive>:116:21:
    Couldn't match type ‘'S ('Z :+: m)’ with ‘'Z’
    Expected type: Vec ('S ('S 'Z) :+: m) a
      Actual type: Vec ('S 'Z) a
    Relevant bindings include
      it :: (Vec ('S ('S 'Z)) a, Vec m a) (bound at <interactive>:116:1)
    In the second argument of ‘split’, namely ‘(VCons 3 VNil)’
    In the expression: split (Sy (Sy Zy)) (VCons 3 VNil)

In the first example, we successfully split a three-element vector at position 2; then we got a type error when we tried to split a vector at a position past the end. Singletons are the standard technique for making a type depend on a value in Haskell.

* The singletons library contains some Template Haskell helpers to generate singleton values like Natty for you.

Last example. What about when you don't know the dimensionality of your vector statically? For example, what if we're trying to build a vector from run-time data in the form of a list? You need the type of the vector to depend on the length of the input list. To put it another way, we can't use foldr VCons VNil to build a vector because the type of the output vector changes with each iteration of the fold. We need to keep the length of the vector a secret from the compiler.

data AVec a = forall n. AVec (Natty n) (Vec n a)
deriving instance (Show a) => Show (AVec a)

fromList :: [a] -> AVec a
fromList = Prelude.foldr cons nil
    where cons x (AVec n xs) = AVec (Sy n) (VCons x xs)
          nil = AVec Zy VNil

AVec is an existential type: the type variable n does not appear in the return type of the AVec data constructor. We're using it to simulate a dependent pair: fromList can't tell you the length of the vector statically, but it can return something you can pattern-match on to learn the length of the vector - the Natty n in the first element of the tuple. As Conor McBride puts it in a related answer, "You look at one thing, and in doing so, learn about another".

This is a common technique for existentially quantified types. Because you can't actually do anything with data for which you don't know the type - try writing a function of data Something = forall a. Sth a - existentials often come bundled up with GADT evidence which allows you to recover the original type by performing pattern-matching tests. Other common patterns for existentials include packaging up functions to process your type (data AWayToGetTo b = forall a. HeresHow a (a -> b)) which is a neat way of doing first-class modules, or building-in a type class dictionary (data AnOrd = forall a. Ord a => AnOrd a) which can help emulate subtype polymorphism.

ghci> fromList [1,2,3]
AVec (Sy (Sy (Sy Zy))) (VCons 1 (VCons 2 (VCons 3 Nil)))

Dependent pairs are useful whenever the static properties of data depend on dynamic information not available at compile time. Here's filter for vectors:

filter :: (a -> Bool) -> Vec n a -> AVec a
filter f = foldr (\x (AVec n xs) -> if f x
                                    then AVec (Sy n) (VCons x xs)
                                    else AVec n xs) (AVec Zy VNil)

To dot two AVecs, we need to prove to GHC that their lengths are equal. Data.Type.Equality defines a GADT which can only be constructed when its type arguments are the same:

data (a :: k) :~: (b :: k) where
    Refl :: a :~: a  -- short for 'reflexivity'

When you pattern-match on Refl, GHC knows that a ~ b. There are also a few functions to help you work with this type: we'll be using gcastWith to convert between equivalent types, and TestEquality to determine whether two Nattys are equal.

To test the equality of two Nattys, we're going to need to make use of the fact that if two numbers are equal, then their successors are also equal (:~: is congruent over S):

congSuc :: (n :~: m) -> (S n :~: S m)
congSuc Refl = Refl

Pattern matching on Refl on the left-hand side lets GHC know that n ~ m. With that knowledge, it's trivial that S n ~ S m, so GHC lets us return a new Refl right away.

Now we can write an instance of TestEquality by straightforward recursion. If both numbers are zero, they are equal. If both numbers have predecessors, they are equal iff the predecessors are equal. (If they're not equal, just return Nothing.)

instance TestEquality Natty where
    -- testEquality :: Natty n -> Natty m -> Maybe (n :~: m)
    testEquality Zy Zy = Just Refl
    testEquality (Sy n) (Sy m) = fmap congSuc (testEquality n m)  -- check whether the predecessors are equal, then make use of congruence
    testEquality Zy _ = Nothing
    testEquality _ Zy = Nothing

Now we can put the pieces together to dot a pair of AVecs of unknown length.

dot' :: Num a => AVec a -> AVec a -> Maybe a
dot' (AVec n u) (AVec m v) = fmap (\proof -> gcastWith proof (dot u v)) (testEquality n m)

First, pattern match on the AVec constructor to pull out a runtime representation of the vectors' lengths. Now use testEquality to determine whether those lengths are equal. If they are, we'll have Just Refl; gcastWith will use that equality proof to ensure that dot u v is well-typed by discharging its implicit n ~ m assumption.

ghci> let v1 = fromList [1,2,3]
ghci> let v2 = fromList [4,5,6]
ghci> let v3 = fromList [7,8]
ghci> dot' v1 v2
Just 32
ghci> dot' v1 v3
Nothing  -- they weren't the same length

Note that, since a vector without static knowledge of its length is basically a list, we've effectively re-implemented the list version of dot :: Num a => [a] -> [a] -> Maybe a. The difference is that this version is implemented in terms of the vectors' dot. Here's the point: before the type checker will allow you to call dot, you must have tested whether the input lists have the same length using testEquality. I am prone to getting if-statements the wrong way round, but not in a dependently-typed setting!

You can't avoid using existential wrappers at the edges of your system, when you're dealing with runtime data, but you can use dependent types everywhere inside your system and keep the existential wrappers at the edges, when you perform input validation.

Since Nothingis not very informative, you could further refine the type of dot' to return a proof that the lengths aren't equal (in the form of evidence that their difference is not 0) in the failure case. This is pretty similar to the standard Haskell technique of using Either String a to possibly return an error message, although a proof term is far more computationally useful than a string!

Thus ends this whistle-stop tour of some of the techniques that are common in dependently-typed Haskell programming. Programming with types like this in Haskell is really cool, but really awkward at the same time. Breaking up all your dependent data into lots of representations which mean the same thing - Nat the type, Nat the kind, Natty n the singleton - is really quite cumbersome, despite the existence of code-generators to help with the boilerplate. There are also presently limitations on what can be promoted to the type level. It's tantalising though! The mind boggles at the possibilities - in the literature there are examples in Haskell of strongly typed printf, database interfaces, UI layout engines...

If you want some further reading, there's a growing body of literature about dependently typed Haskell, both published and on sites like Stack Overflow. A good starting point is the Hasochism paper - the paper goes through this very example (among others), discussing the painful parts in some detail. The Singletons paper demonstrates the technique of singleton values (such as Natty). For more information about dependent typing in general, the Agda tutorial is a good place to start; also, Idris is a language in development that's (roughly) designed to be "Haskell with dependent types".


问:
What are useful metrics for source code?
What are useful metrics to capture for source code?

How can metrics, like for example (Executable?) Lines of Code or Cyclomatic Complexity help with quality assurance or how are they beneficial in general for the software development process?

答: Since source code is simply a combination of sequence, selection, and repetition. If I were to describe the most optimal piece of software that we could ever reasonably expect to produce it would be as follows. Software with nearly 100% testing code coverage using the least amount of lines of code necessary to do the job and yet flexible enough to withstand changes.</p>

ContentLicense: CC BY-SA 2.5


问:
Design ideas - validation based on conditions outside of the domain
I am facing a very interesting problem here, and I'd like to see some design ideas from domain driven design perspective.

To make it easier to express what I need I have following hypothetical situation. I have a bounded-context named Customer, which is used to handle create new customer, update customer, searching customer and so on. I have a customer class look like

```<code>public class Customer
{
    public int Id { get; set ; }
    public int SocialInsuranceNumber { get; set ; }

    public bool IsValid()
    {
        // my logic to validate social insurance number
    }
}
</code>```

So I have a straightforward logic in my entity to validate the data. The Canadian Social Insurance Number validation rule indicates all values begins with 0 should not be used, but Canadian government might use it for some reason. So there are possible 2 validation rules here now.

The business has the requirement of one single application - for majority of the situations when user enters a social insurance number we have to make sure the value cannot start with 0 and the value must be a valid SIN, but in some unique situation we must allow a valid SIN starting with 0.

My domain service code looks like

```<code>public class CustomerService
{
    public void AddCustomer(Customer customer)
    {
        if (customer.IsValid())
        {
            // save to database
        }
    }
}
</code>```

If I add a boolean parameter to Customer class's IsValid() function to make to look like IsValid(bool allowLeadingZero), I could make the code work. But I think it looks ugly.

From design perspective how would you suggest a more elegant way to deal with such requirement?

答:
I suggest that you should separate the Customer and SocialInsuranceNumber entities into their own classes, as clearly both contain data and have behaviour:

Create a SocialInsuranceNumber class, and move the isValid() method into this class as a static method isValid(int CandidateSIN). It could be a member function, but that means it is possible to create invalid instances, which would probably not be wise. The SocialInsuranceNumber constructor should prohibit this.

Add an instance of SocialInsuranceNumber to your customer. Only populate this if the you have a valid SIN.

To handle the Canadian case, consider using a more general constructor and validation method like SocialInsuranceNumber(int SIN, String CountryCode) and isValid(int CandidateSIN, String CountryCode). Then you can bury the validation rules inside the SocialInsuranceNumber class.

The Customer class could have an isValid() method, but in the future this might need to handle (for instance) deceased or insolvent customers. If you need a hasValidSIN() method, then it only needs to check if the SIN is not null.

Slightly off topic, but the int type is not a good choice for a field that is optional. For instance, overseas customers may not have SINs.

ContentLicense: CC BY-SA 3.0


问:
Should abstract classes be used to prevent instantiation
Is preventing the instantiation of a class a valid reason to make it abstract? For example, if I have a class called Gauge which has subclasses HeadingIndicator and AirSpeedIndicator, is it a good idea to make Gauge abstract? Because instances of Gauge are pretty useless on their own, but might be useful as references to its subclasses.

答:
It depends on why you want to prevent instantiation.

If you want to have control over instances e.g. the singleton pattern then you would hide/encapsulate the constructor.

If the class is a  generalisation that in its self could never be an instance then it makes more sense for it to be an abstract class.


问:
New PHP Project - Should I still be supporting PHP 5.2?
I'm about to start working on a new commercial PHP project with a friend that will be licensed and sold as a script to run on your own shared hosting account or server.

Looking at the statistics (http://w3techs.com/technologies/details/pl-php/5/all) 50.3% of PHP 5 installations are still PHP 5.2 or lower (43.5% being php 5.2). With this in mind, is it wise to ensure new software still supports PHP 5.2 given that such a high proportion of installations arent going to support modern PHP features such as namespacing and the likes of Composer.

答: I would say use the latest php5.5 as they are continuously developing so why not use the latest one plus you need to keep in mind MySQL are developing too. MySQL is about to be terminated and MySQLi and PDO comes into place and php5.5 supports both of them plus it comes with phar all you need to install pear to use other people's code </p>


问:
How come the computer doesn't have to read the entire table when the column is indexed?
Let's say a table with two columns has 100 quadrillion records. And I want to find a record that has column #2 equal something.

If column #2 is indexed it returns the result immediately, but if it's not the computer has to read the entire table so it takes a long time.

How come the computer doesn't have to read the entire table when the column is indexed? How does it know what the result is without reading the table?

答:
binary beans

You have a bunch of red jelly beans and a bunch of blue jelly beans.

You put the red jelly beans to the left and the blue ones to the right.

Now in the left-hand-side-world of red jelly beans you separate the ones that have no freckles to the left, the ones that have many freckles to the right.

So now you have something like

```<code>                    Root
              Reds/     \ Blues
           /     \
no freckles     freckles
</code>```

You can keep branching your tree on different attributes and eventually if you want to find a red jelly bean with freckles you only have to take 2 steps, you don't have to pick up every single bean and check, put it back, and grab a new one until you reach a freckled red bean.

No matter how many jelly beans you have, finding a red one or a blue one is very simple.

A tree works a similar way (binary tree, B+tree, trie, etc.) by branching differences in data.

princess hotel

Indexing is just another way of exploiting patterns in data for efficiency.

Say you have a hotel and you put all the VIPs on the top floor, all the princesses on the 3rd floor, all the kings on the 2nd floor, etc.

Then you don't have to search through every room when you want to find a princess, you just go to the 3rd floor.  It cuts down your seek time by a lot.

Now imagine doing that with your data.

An index is therefore not all the data, it's just a map that tells you where all the data is.  If your data has some nice patterns that can be exploited, then your index will make your searching very efficient.

Body:
binary beans

You have a bunch of red jelly beans and a bunch of blue jelly beans.

You put the red jelly beans to the left and the blue ones to the right.

Now in the left-hand-side-world of red jelly beans you separate the ones that have no freckles to the left, the ones that have many freckles to the right.

So now you have something like

                    Root
              Reds/     \ Blues
           /     \
no freckles     freckles

You can keep branching your tree on different attributes and eventually if you want to find a red jelly bean with freckles you only have to take 2 steps, you don't have to pick up every single bean and check, put it back, and grab a new one until you reach a freckled red bean.

No matter how many jelly beans you have, finding a red one or a blue one is very simple.

A tree works a similar way (binary tree, B+tree, trie, etc.) by branching differences in data.

princess hotel

Indexing is just another way of exploiting patterns in data for efficiency.

Say you have a hotel and you put all the VIPs on the top floor, all the princesses on the 3rd floor, all the kings on the 2nd floor, etc.

Then you don't have to search through every room when you want to find a princess, you just go to the 3rd floor.  It cuts down your seek time by a lot.

Now imagine doing that with your data.

An index is therefore not all the data, it's just a map that tells you where all the data is.  If your data has some nice patterns that can be exploited, then your index will make your searching very efficient.


答:
Won't this "source code metrics" crap EVER die?

Raw source lines of code (SLOC) is the oldest, easiest, most basic metric there is.

Halstead originally proposed a whole bunch of metrics.  Lots of people were having lots of fun writing measurement programs until some spoilsport did the obvious study, and demonstrated that each and every single Halstead metric was strongly directly correlated with SLOC.

At that point, Halstead's metrics were abandoned, because SLOC is always easier to measure.

Title: What are useful metrics for source code?

Body:
What are useful metrics to capture for source code?

How can metrics, like for example (Executable?) Lines of Code or Cyclomatic Complexity help with quality assurance or how are they beneficial in general for the software development process?


答:
The "index" of a book is not a great metaphor, IMO. A better metaphor is trying to look up a word in a dictionary. Imagine that you want to look up a word in the Oxford English Dictionary (OED), which is a massive dictionary that comprises multiple volumes.

The words in the OED are sorted alphabetically, of course, to make it easy to look up a word. But what if the words were not sorted? What if they were added to the dictionary in random order?

Let's do a thought experiment where we want to look up the word "quadrillion" in this hypothetical, unsorted dictionary, and compare that to looking up the same word in a normal, sorted dictionary.

Let's assume the dictionary has 10,000 pages and there is exactly 1 word on each page.

Unsorted Dictionary

To find the word "quadrillion" in a dictionary that isn't alphabetically sorted, you would need to start at one end (say page 1). If the word on page 1 is "quadrillion", then congratulations, you're done! Of course, since the dictionary is random, odds are that "quadrillion" is not on the first page, which means you need to check the next page, and then the page after that, etc. until you find "quadrillion".

How many pages do you need to look at (in the worst case) to find the word "quadrillion"? Well, potentially all of them... "quadrillion" could by chance be the very last word in the dictionary, so you'd need to look at all 10,000 pages in the worst case scenario.

This would be an excruciatingly tedious task, and its analogous to a database looking at every single row of a table.

Sorted Dictionary

Fortunately, dictionaries are sorted alphabetically, which is why we can look up a word in minutes, not weeks. We all know how to find a word in the dictionary, but pretend for a moment that you had to write an algorithm to do it. How would that algorithm work?

Open the dictionary up to the middle page (5,000) and read the word on that page: "mellifluous".

This word is higher (alphabetically) than quadrillion, so we know that quadrillion must be somewhere between pages 5,001 and 10,000.

Next, we go to to page 7,500, which is the midpoint of 5,001 and 10,000.

The word on this page is "sacrosanct". This is lower than "quadrillion", so now we know quadrillion is between pages 5,001 and 7,500.

Now we flip to 6,250, which is the midpoint of 5,001 and 7,500.

...

We can repeat this process of dividing the remaining pages in half and figuring out which half the word is in until, eventually, we'll open to the page that contains "quadrillion", and we're done!

How efficient is this compared to the unsorted dictionary algorithm? We still probably had to look at a lot of pages, right?

We can compute the efficiency by noticing that at each step we are eliminating half of the pages. So by counting the number of pages that are left, we can count how many steps it takes to get to any word:

Start with 10,000 pages.

Narrow it down to 5,000 pages.

Then 2,500.

1,250

625

312 (we'll round down if there are any decimal places)

156

78

39

19

9

4

2

1

By the time we get to 1 page remaining, we know with certainty that we've either found the word we were looking for, or it doesn't exist in the dictionary. We can count the number of steps and see that we only had to look at 14 pages — in the worst case — to find any word. That's a huge improvement over looking at all 10,000 pages!

More generally, the worst-case lookup time is log2(n), where n is the number of pages in the dictionary. (Try computing it yourself to see if your answer agrees with mine.) This is a very desirable property for an algorithm, because the log function grows very slowly. If the dictionary had a billion pages instead of 10k, it would still only take 30 steps to find any given word in it! (Again, try computing it yourself.)

This is analogous to the database using an index to find a row in a table.

B-Tree

A B-tree is a data structure that allows us to use an algorithm similar to the one we use to find a word in a sorted dictionary. This is a very important data structure in fundamental computer science.

http://en.wikipedia.org/wiki/B-tree

Many database indexes are actually b-trees under the hood.

Pedantry

You said:

If column #2 is indexed it returns the result immediately, but if it's not the computer has to read the entire table so it takes a long time

The "immediately" part isn't really true. It's still an iterative algorithm that takes longer to run the more items that need to be looked at. It's such an efficient algorithm that the results might feel immediate, but it's important to  note that it's not a constant time algorithm.

Body:
Let's say a table with two columns has 100 quadrillion records. And I want to find a record that has column #2 equal something.

If column #2 is indexed it returns the result immediately, but if it's not the computer has to read the entire table so it takes a long time.

How come the computer doesn't have to read the entire table when the column is indexed? How does it know what the result is without reading the table?


问:
Class design for JSON serialization
I've been stuck for some time on a circular reference issue with JSON serialization. I have a card game that I'm pickling to a redis store. As I retrieve the Game state from redis I'm trying to serialize it in JSON so that I can pass it to React.js and render it on screen. I mentioned React.js as my goal is to pass back and forth the entire game state at every change of state.

Below is the simplified code of my class structure. The Game class holds reference to everything. Player holds references to Game and Cards, Cards hold references to Player.

Is this design desperately wrong? Instead of referencing objects should I just be referencing their an ID of the object and then retrieve them separately when I have to render the new state? Any design pattern that could come useful?

If it could be useful to answer the question the stack I'm using is Python, Django, Redis, React

```<code>class Card(object):

    def __init__(self, suit, face):
        self.face = face
        self.suit = suit
        self.is_trump = False
        self.owner = None

class Deck(object):

    def __init__(self):
        self.deck = []

class Player(object):

    def __init__(self, name, autopilot=False):

        self.score = 0
        self.uid = self._new_uid()
        self.name = name
        self.cards = []
        self.is_first = False  # used to determine the winner in case of draw
        self.autopilot = autopilot
        # updated when the game is joined by the Game instance
        self.game = None

class Game(object):

    def __init__(self, players, deck, table):
        self.hands = []
        self.winner = None
        self.players = players
        self.uid = self._new_uid()
        self.deck = deck
        self.table = table
        self.over = False

class Hand(object):

    def __init__(self, carda, cardb, game, simulate=False):

        self._carda = carda
        self._cardb = cardb
        self._first = self._get_first()
        self._winner = self._play()

        # is it a regular hand or a simulation?
        if not simulate:
            self._update_score()
            game.table.clean()
            game.hands.append(self)

class Table(object):

    def __init__(self):
        self.cards = []
        self.played = []
</code>```

答:
To avoid circular references, only a parent node/class should know about it's children.

Accessing Game as the root node should allow you to gather information anywhere you need.

Title: Class design for JSON serialization


问:
Where is "the line" for copyleft licenses
Where exactly is "the line" between needed to copy a copyleft license and not?
For example, I am writing a non GNU GPL program that uses git.
I do not mean that I use git to write it, I mean, git is actually a vital part of what the program does. The code itself calls git.

Can I do this without needing to copyleft?
Can I distribute git with my program? Or do I have to require users to install it separately?

I know that a "fork" of git would be copyleft and just using git to write code does not. What about in-between?

More specifically:
my program uses git to push files to remotes. This is more lightweight then a simple upload cause it only sends a diff.
I don't need to patch git or change at all, but I would like to package git and the Unix libraries it comes with (for windows) simply for simplicity.

答:
It is a grey area (BTW beware I am quite a GPL enthusiast so I am biased); I guess you mean GPLv3 (but perhaps git is GPLv2 and then details are different)

GPLv3 is so called a "viral license" (I dislike that expression because it looks negative,but it is not), or (much better wording) a strong copyleft license. It has a FAQ which answers some of your concerns. GPL is about free -or libre-  software (freedom of speech, not "free as in beer" i.e. freeware or gratis)

I won't repeat the FAQ. What matter is not only how you use GPL, but also somehow your intents. For instance, if you publish a GPLv3 patch to a GPLv3 program which is only designed to communicate -using some unique protocol peculiar to your application!- with a particular program of yours, some people believe that your program should be GPLv3-ed. If the protocol is documented and used by several applications things are different.

So linking (with ld) is not the only way to have some derived work (or covered work) from the point of view of GPL. Things might be more complex.

Ultimately, it is a legal question (so off-topic here), and in several legal systems it has to be specifically tested in a court.

BTW, you could ask your lawyer, and you might ask the FSF. Of course, the FSF has a "biased" (at least strong & specific) view on software, but it also does have experts on the licensing field and it has some lists or forums to discuss that. But read the GPLv3 and its FAQ first.

The point is that your user should keep his/her freedom to upgrade (or improve) git and that should be easy for him/her (so making that easy is your technical concern). At the very least, you should document how your program is exactly using git  and of course provide a mean to replace git by an upgraded version (perhaps installed elsewhere and invoked as a different command than just git, e.g. $HOME/bin/git-patched-by-basile, so at least the command line invoking git  should be somehow user-configurable in a documented way etc...).

If you package git  on some physical media, be sure (for courtesy to your users) to package its source code also. If you are providing some network downloading of your software, again have the courtesy to give the URL to git  and to recommend some version and to explain how your user could upgrade/reconfigure the git  used by your program.

At last, did you consider making your own program some free software? That would solve a lot of questions (especially if you care to choose a license compatible with the GPL version used by git)

If you work for a company, be sure to inform and ask your managers/clients and the lawyers that you do things right. Don't violate the GPL and make them be aware of any issues! Don't even try to interpret the GPL yourself (but explain what you understand about the GPL to managers and lawyers and clients and any responsible stakeholder). Ask the company (owning the software), e.g. your boss/your client/your lawyer. If possible try to explain your boss why making your code a free software under GPL is better for the company. This is a long journey.

I am not a lawyer and you probably are not neither. But you have ethical concerns, you don't want to do illegal things, you don't want to put your comapny in trouble, so you should not hide any potential issues (e.g. from your manager, if you are an employee, or from your client, if you are a consultant).

If you are a developer employed by some company, don't even try to solve licensing issues yourself, and ask your manager! (Details are strongly specific to the legal system of your country, your work contract, etc...) Surely don't hide (neither from your boss, nor from your users) the fact that the program is running git  and make user-configurable the exact name or command-line or path invoking the git program


答: "Measuring software productivity by lines of code is like measuring progress on an airplane by how much it weighs."- Bill Gates</p>


问:
Accessing shared data without blocking in TPL
I am writing a class that contains data. It exposes methods that allow to query the data, while the data is also being updated from an external source (web service, for example).

All the methods expose tasks that are started on a worker thread using the default task scheduler. So the structure of the class is as follows:

```<code>public class A
{
    private object _myLock;

    public Task<int> GetSomeNumber(int aParameter)
    {
        return Task.Run(() =>
        {
            lock (_myLock)
            {
                int result = 0;
                // calculate the result...
                // ...
                return result;
            }
        });
    }

    public Task<string> GetSomeText(int aParameter)
    {
        return Task.Run(() =>
        {
            lock (_myLock)
            {
                string result = "";

                // calculate the result...
                // ...
                return result;
            }
        });
    }
}
</code>```

The methods may be called several multiple times, while the data itself is being updated, so the calculations that require the shared data are surrounded with a lock statement. The problem is that this code blocks the thread in which the task is run. Of course, these are not UI thread, so the UI remains responsive, but it does consume threads and keeps them blocked. I would prefer for the worker threads in the thread pool to remain as available as possible.

Is there a way, a best practice of some sort, that allows to write this code so that the shared data is thread safe and at the same time the tasks are not blocked? If instead of waiting for a lock, the tasks would need to wait for something else to finish (a task), I would use ContinueWith in order to create a continuation task and return it, so that it would be scheduled to run when the first task is completed. Is there a way to do the same with lock, so that the task is only scheduled when the lock is available?

Update
I have done some reading and found out about several possible options that allow for shared data sync. These include: SemaphoreSlim, AsyncLock, and ConcurrentExclusiveSchedulerPair.

I would love to see a recommendation for a best practice, of writing a service class that provides "read only" task methods that can run concurrently with a read lock, and "write" task methods that require write lock.

答:
This answer is based on the additional information about the use case mentioned in the comments.

We have a web service the provides graph nodes. We hold a local copy
  of part of the graph and expose and async API to query the graph. If
  the area that you query is in the cache then we simply calculate and
  return the result, otherwise we start downloading the missing part and
  then perform the calculation and return the result. There is also a
  recurring task in the background that polls the server for changes in
  the node and applies the changes to the local cache.

One should realize that if a request cannot be completed right away because the data needed to fulfill the request is simply not available (e.g. haven't been downloaded or cached), there are only a few choices:

Return a failure right away. This is similar to the TryGet pattern, which does not block - but the task won't succeed.

Return a failure right away, but also indicate that it has started an asynchronous request to fetch data from the external server. This way, the reader won't block, but will have to retry at a later time.

Require the reader to provide a callback function, which will be called later when the data is available. This can be combined with the asynchronous request approach.

Block the reader until the data has been fetched.

Each of the options above has its own set of "best practices" and integration patterns with TPL. It would be too much to discuss all of them here.

Help needed: If anyone knows of good online resource that covers the best practices for these options, please post as comments.

If you decide that blocking the reader is the only choice given the requirements of your application, keep in mind that:

The .NET default thread pool is elastic - meaning that it will launch more worker threads if it senses that some threads are being blocked. This is good. It means that blocking any number of readers will not result in system-wide failure.

If it is not elastic, your application may deadlock due to worker thread starvation (exhaustion).

You must therefore never change the settings on the default thread pool that will cause it to lose the elasticity - unless you are willing to reboot your service whenever that happens.

For example, do not set a maximum number of worker threads.

If you want the concurrent readers to never get stuck (being obstruction free), I think you have several choices:

Multiple buffering

Link to Wikipedia article

The system maintains multiple copies of the graph, and rotate (cycle through) them whenever a modification is needed.

At any point in time, at most one copy will be modified. All other copies will be read-only.

When a modification is taking place, each reader must choose between:

Reading from one of the other read-only, slightly out-of-date copies of the graph. Multiple readers can access it concurrently.

Wait until the modification is complete, to make sure it will have access to the most up-to-date version of the graph.

Concurrent graph update algorithms

The exact details will depend on what operations and algorithms are needed for the application.

Some of them may be lock-free, using the hardware-enabled atomic instructions. Others may use various kinds of locks, but may try to minimize the probability or the length of time where readers might be blocked.

One may either use an existing library or implement one's own.

I'm not familiar with concurrent graph update algorithms, so I can't give much suggestions.


答:
You're already asking yourself the right question: Is a gauge of no specific type useful to anybody? What does it measure? What units does it use? As you've already noticed, it's not.

So clearly a gauge isn't something that needs to be instantiated itself. That means a gauge should probably be either an abstract class or an interface. I usually prefer to make my class interfaces and then if appropriate provide an abstract class implementation of that interface if I need to provide a default implementation of some common behavior.

One thing you should consider, though, is whether or not a gauge should be a type at all, and that all comes down to what specifically you're doing. A lot of 'gauges' don't really do anything common to all gauges. If this is the case, consider loosening up your model a bit and maybe not even having a gauge interface. Let HeadingIndicator and AirspeedIndicator be their own separate, unrelated classes. Or maybe you'd like a uniform way to display these gauges and want an interface with methods like Unit units(), String labe() and double measurement().

I guess the tldr; here is that if it seems to be difficult/awkward to abstract these two entities into an abstract parent, maybe that abstraction isn't needed and can be skipped. Are you going to be writing code that applies to all gauges? If not, skip the parent interface/abstract class. It's easy enough to extract an interface later for the code that will need the interface.

Title: Should abstract classes be used to prevent instantiation

Body: Is preventing the instantiation of a class a valid reason to make it abstract? For example, if I have a class called Gauge which has subclasses HeadingIndicator and AirSpeedIndicator, is it a good idea to make Gauge abstract? Because instances of Gauge are pretty useless on their own, but might be useful as references to its subclasses.


问:
At what point does "constructive" criticism of your code become unhelpful?
I recently started as a junior developer. As well as being one of the least experienced people on the team, I'm also a woman, which comes with all sorts of its own challenges working in a male-dominated environment. I've been having problems lately because I feel like I am getting too much unwarranted pedantic  criticism on my work. Let me give you an example of what happened recently.

Team lead was too busy to push in some branches I made, so he didn't get to them until the weekend. I checked my mail, not really meaning to do any work, and found that my two branches had been rejected on the basis of variable names, making error messages more descriptive, and moving some values to the config file.

I don't feel that rejecting my branch on this basis is useful. Lots of people were working over the weekend, and I had never said that I would be working. Effectively, some people were probably blocked because I didn't have time to make the changes and resubmit. We are working on a project that is very time-sensitive, and it seems to me that it's not helpful to outright reject code based on things that are transparent to the client. I may be wrong, but it seems like these kinds of things should be handled in patch type commits when I have time.

Now, I can see that in some environments, this would be the norm. However, the criticism doesn't seem equally distributed, which is what leads to my next problem. The basis of most of these problems was due to the fact that I was in a codebase that someone else had written and was trying to be minimally invasive. I was mimicking the variable names used elsewhere in the file. When I stated this, I was bluntly told, "Don't mimic others, just do what's right." This is perhaps the least useful thing I could have been told. If the code that is already checked in is unacceptable, how am I supposed to tell what is right and what is wrong? If the basis of the confusion was coming from the underlying code, I don't think it's my responsibility to spend hours refactoring a whole file that someone else wrote (and works perfectly well), potentially introducing new bugs etc.

I'm feeling really singled out and frustrated in this situation. I've gotten a lot better about following the standards that are expected, and I feel frustrated that, for example, when I refactor a piece of code to ADD error checking that was previously missing, I'm only told that I didn't make the errors verbose enough (and the branch was rejected on this basis). What if I had never added it to begin with? How did it get into the code to begin with if it was so wrong? This is why I feel so singled out: I constantly run into this existing problematic code, that I either mimic or refactor. When I mimic it, it's "wrong", and if I refactor it, I'm chided for not doing enough (and if I go all the way, introducing bugs, etc). Again, if this is such a problem, I don't understand how any code gets into the codebase, and why it becomes my responsibility when it was written by someone else, who apparently didn't have their code reviewed.

Anyway, how do I deal with this? Please remember that I said at the top that I'm a woman, and I'm sure these guys don't usually have to worry about decorum when they're reviewing other guys' code, but honestly that doesn't work for me, and it's causing me to be less productive. I'm worried that if I talk to my manager about it, he'll think I can't handled the environment, etc.

答:
I don't feel that rejecting my branch on this basis is useful. Lots of people were working over the weekend, and I had never said that I would be working. Effectively, some people were probably blocked because I didn't have time to make the changes and resubmit. We are working on a project that is very time-sensitive, and it seems to me that it's not helpful to outright reject code based on things that are transparent to the client. I may be wrong, but it seems like these kinds of things should be handled in patch type commits when I have time.

It is hard to say anything useful as someone who neither saw your code nor knows something about your projects schedule. But, if your lead behaves responsibly and does a good job, he knows, that others weren't really blocked and the sprint won't be late. So, do not worry about that. Perhaps you overrate the impact on your commit. Otherwise: if your project is time critical and passes all tests, it would be too picky to reject code, which could be fixed after the release in a blink of an eye.

Make It Work Make It Right Make It Fast

So, if your lead made the decision to reject your commit, as a professional he should know, what he was doing.

Now, I can see that in some environments, this would be the norm. However, the criticism doesn't seem equally distributed, which is what leads to my next problem. The basis of most of these problems was due to the fact that I was in a codebase that someone else had written and was trying to be minimally invasive. I was mimicking the variable names used elsewhere in the file. When I stated this, I was bluntly told, "Don't mimic others, just do what's right."

As a Junior it is hard to find ones way into a companies codebase.

Best: there are documented coding standards - and you will hopefully learn to get grips on them.

Usually: there are undocumented coding standards - and you have to learn via trial and error or should I say commit and _reject? This is oftentimes painful (as in your case). This is sometimes dangerous in terms of code quality and could lead to cargo cult programming, where one not only mimics variable naming, but copies and pastes structures and patterns from the code base in good faith, it has to be done like that. Do not do that! Do not even mimic existing variable naming.

Stick to Clean Code. It is good practice and gives you an easy to defend position. If it is readable, testable and maintainable code, you mostly have won any discussion.

And this leads to another (the last) advice: Follow the boy scout rule!

Always leave the codebase in a better state, than it was. Even if the surrounding code you are working with is nasty, make yours clean - and if you have time fix the surroundings.


答:
Others have given more technical answers, so I will provide an analogy—and I realize this analogy may be a bit old fashioned:

How do you look for a number in a phone book?

Do you start at page one reading every name until you find it? Of course not, you split the huge thing in two, check where you're at then split it again and again, until you converge closer and closer to a page likely to contain the listing.

This is possible because we know the information in the phone book has been sorted alphabetically. Thus we are effectively performing the same steps as a binary-search algorithm.

Related concepts hold true for all books. When you open any book you'll often find an "index" within the first few pages that list relevant sections with pointers to data (page numbers).

Creating a database index for a particular table column is the same concept.

Title: How come the computer doesn't have to read the entire table when the column is indexed?


答:
Nowhere in your post do you mention how others around are treated. You keep repeating that you "feel" you're being "singled out" because you're "a woman".

I think you're being treated like a junior programmer regardless of your gender and you should be thankful for that, because that's what equality means. I also feel you're making a huge fuss over minor, 5-minute-long code aesthetic changes that you're being asked to do now instead of putting them on a to-do list and never getting around to them.

Nowhere in your post did you mention you were ordered to do these things on the weekend. It might be perfectly fine to check in the fixes on Monday morning.

Your team lead might be a little pedantic for my tastes, but from your post I don't see anything wrong with his or her requests.

Please stop playing the gender card for nothing. I feel this is undignified and undermines the concept of gender equality.

Title: At what point does "constructive" criticism of your code become unhelpful?

Body:
I recently started as a junior developer. As well as being one of the least experienced people on the team, I'm also a woman, which comes with all sorts of its own challenges working in a male-dominated environment. I've been having problems lately because I feel like I am getting too much unwarranted pedantic  criticism on my work. Let me give you an example of what happened recently.

Team lead was too busy to push in some branches I made, so he didn't get to them until the weekend. I checked my mail, not really meaning to do any work, and found that my two branches had been rejected on the basis of variable names, making error messages more descriptive, and moving some values to the config file.

I don't feel that rejecting my branch on this basis is useful. Lots of people were working over the weekend, and I had never said that I would be working. Effectively, some people were probably blocked because I didn't have time to make the changes and resubmit. We are working on a project that is very time-sensitive, and it seems to me that it's not helpful to outright reject code based on things that are transparent to the client. I may be wrong, but it seems like these kinds of things should be handled in patch type commits when I have time.

Now, I can see that in some environments, this would be the norm. However, the criticism doesn't seem equally distributed, which is what leads to my next problem. The basis of most of these problems was due to the fact that I was in a codebase that someone else had written and was trying to be minimally invasive. I was mimicking the variable names used elsewhere in the file. When I stated this, I was bluntly told, "Don't mimic others, just do what's right." This is perhaps the least useful thing I could have been told. If the code that is already checked in is unacceptable, how am I supposed to tell what is right and what is wrong? If the basis of the confusion was coming from the underlying code, I don't think it's my responsibility to spend hours refactoring a whole file that someone else wrote (and works perfectly well), potentially introducing new bugs etc.

I'm feeling really singled out and frustrated in this situation. I've gotten a lot better about following the standards that are expected, and I feel frustrated that, for example, when I refactor a piece of code to ADD error checking that was previously missing, I'm only told that I didn't make the errors verbose enough (and the branch was rejected on this basis). What if I had never added it to begin with? How did it get into the code to begin with if it was so wrong? This is why I feel so singled out: I constantly run into this existing problematic code, that I either mimic or refactor. When I mimic it, it's "wrong", and if I refactor it, I'm chided for not doing enough (and if I go all the way, introducing bugs, etc). Again, if this is such a problem, I don't understand how any code gets into the codebase, and why it becomes my responsibility when it was written by someone else, who apparently didn't have their code reviewed.

Anyway, how do I deal with this? Please remember that I said at the top that I'm a woman, and I'm sure these guys don't usually have to worry about decorum when they're reviewing other guys' code, but honestly that doesn't work for me, and it's causing me to be less productive. I'm worried that if I talk to my manager about it, he'll think I can't handled the environment, etc.


答:
...Is this design desperately wrong?

No. You can serialize circular references using JSON

I don't know what's the Python-approach. But from the specification point of view I've heard that json pointer fragment might be the internet search query

Wikipedia → JSON → Object references is not very clear on this subject and emphasizes the implementation used by dojox.json.ref JavaScript toolkit

Newtonsoft's Json.NET library ("standard" in the C# world) supports object references fully using slightly different convention with "$id" and "$ref" special properties.

So in the C#, JavaScript worlds you would not have to flatten or restructure your graph-like data structures at all

...Any design pattern that could come useful?

Use the right tools for the job (stronger programming language or library)

Title: Class design for JSON serialization

Body:
I've been stuck for some time on a circular reference issue with JSON serialization. I have a card game that I'm pickling to a redis store. As I retrieve the Game state from redis I'm trying to serialize it in JSON so that I can pass it to React.js and render it on screen. I mentioned React.js as my goal is to pass back and forth the entire game state at every change of state.

Below is the simplified code of my class structure. The Game class holds reference to everything. Player holds references to Game and Cards, Cards hold references to Player.

Is this design desperately wrong? Instead of referencing objects should I just be referencing their an ID of the object and then retrieve them separately when I have to render the new state? Any design pattern that could come useful?

If it could be useful to answer the question the stack I'm using is Python, Django, Redis, React

```<code>class Card(object):

    def __init__(self, suit, face):
        self.face = face
        self.suit = suit
        self.is_trump = False
        self.owner = None

class Deck(object):

    def __init__(self):
        self.deck = []

class Player(object):

    def __init__(self, name, autopilot=False):

        self.score = 0
        self.uid = self._new_uid()
        self.name = name
        self.cards = []
        self.is_first = False  # used to determine the winner in case of draw
        self.autopilot = autopilot
        # updated when the game is joined by the Game instance
        self.game = None

class Game(object):

    def __init__(self, players, deck, table):
        self.hands = []
        self.winner = None
        self.players = players
        self.uid = self._new_uid()
        self.deck = deck
        self.table = table
        self.over = False

class Hand(object):

    def __init__(self, carda, cardb, game, simulate=False):

        self._carda = carda
        self._cardb = cardb
        self._first = self._get_first()
        self._winner = self._play()

        # is it a regular hand or a simulation?
        if not simulate:
            self._update_score()
            game.table.clean()
            game.hands.append(self)

class Table(object):

    def __init__(self):
        self.cards = []
        self.played = []
</code>```


问:
Detect request coming from iframe
I just had this awesome idea about simulating a single page application using iframes. I am using a framework that uses layouts to display pages. Luckily I can use an empty layout (meaning it has no extra elements apart from the mandatory html tags) to display only the page body inside an iframe once the page has loaded with the original layout.

I think this may have come out a little confusing so basically this is my idea:

User opens up the site, site loads the main layout with the header and navigation and everything. Then the body of the layout is displayed inside an iframe which is getting its content from the same url using the same page but a different layout (empty one).

The problem - how can I differentiate between whether it is an initial request coming in or just another page request?

The solution - If I could somehow detect requests coming from iframes I could simply know when to use the main layout or the empty layout. Is there any way I can detect requests sent from iframes?

I also thought I could have special links for loading page content such as if a user opens the page http://example.com/products then I would return the main layout and in the iframe I would send a request to http://example.com/empty/products. But then I will have to modify all links in all pages to contain /empty/ in them or I will have the main layout appear inside the body of the original request.

答:
You can't detect that an iFrame is making the request directly. You can, of course, pass parameters in the URL to allow you to make the distinction.

Since the use of iFrames is downplayed, if not actively deprecated, you may want to revisit your idea.

Title: Detect request coming from iframe


答:
Sometimes it's a judgement call.  The following are the kinds of questions that will be asked when you get taken to court:

Does your software directly compete with git, or is it incidental to its use?  In other words, is the elevator pitch of your software something like, "It syncs changes to files between different computers?"

Does your software still work, just with reduced functionality, if you didn't install git?

Could a user replace git with, say, a shell script that calls rsync without changing your code?

Can you upgrade your software and git independently?

If the answers to all these questions aren't clearly on the safe side, you need to get lawyers involved.  If your company doesn't want to GPL their software, they understand that incurs the cost of limiting their ability to incorporate GPL software in their products.  You need to clearly spell out the cost of alternatives.  They might surprise you.  Even Microsoft has contributed some open source software.

Title: Where is "the line" for copyleft licenses

Body:
Where exactly is "the line" between needed to copy a copyleft license and not?
For example, I am writing a non GNU GPL program that uses git.
I do not mean that I use git to write it, I mean, git is actually a vital part of what the program does. The code itself calls git.

Can I do this without needing to copyleft?
Can I distribute git with my program? Or do I have to require users to install it separately?

I know that a "fork" of git would be copyleft and just using git to write code does not. What about in-between?

More specifically:
my program uses git to push files to remotes. This is more lightweight then a simple upload cause it only sends a diff.
I don't need to patch git or change at all, but I would like to package git and the Unix libraries it comes with (for windows) simply for simplicity.


问:
What is the origin of the tag property in UI toolkits?
I've seen the tag property in all UI frameworks I worked with: UIKit, Forms, OpenStep, even Delphi 6. Was it in the original Macintosh Toolbox or Xerox's framework? WhAt was the original idea behind it?</p>

答:
Quoting from the docs for UIView...

tag Property

  An integer that you can use to identify view objects in your application.

Assuming you've seen the docs for such attributes, you're probably really asking why people still use them today. They are there as a convenience to developers to use however they want. In an object graph containing multiple objects of the same class (buttons, menu items, etc.), different tag values can be assigned to help identify one button over another. Or they can be used to hold a pointer to some more data (not necessarily a recommended approach), or bit field, or whatever.

Nowadays, memory and CPU resources are such that we can throw in other stuff to help identify things at runtime. The integer tag attribute was used in "the good old days" when memory and CPU resources were more scarce. It doesn't hurt anything to leave the tag attribute in there, and many developers still use it.


问:
Android IRC Connection
I'm developing an app, and am a newbie in terms of development on android. I want to write a script that will automatically connect to an IRC Server, Channel, Port and then when you say something in the text box it will send it to IRC server.

Any ideas on how to go about this? I did some google searches, didn't show up anything very conclusive.

IRC Connection structure:

CONNECT -> IP:PORT

CONNECT -> NICKSERV IDENITFY [username] [password]

CONNECT -> JOIN CHANNEL #bob

Once identified they can join channel and talk.

Thanks for your time.

答:
As far as the TCP socket-based communication goes, doing it on Android should be similar to doing it on desktop computer. Therefore, you can develop your IRC communication code on desktop Java, and then copy the code over to the Android application.

http://developer.android.com/training/basics/network-ops/connecting.html

One thing to keep in mind is that you must give your Android application permissions to use the network. This is done by adding these to the application manifest.

```<code><uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</code>```

However, any program that runs on Android are required to have a graphical user interface - command-line console or text-based interface simply isn't an option on Android. Therefore, you will still have to learn Android GUI programming.

You should follow Android's Getting Started guide. The tools are free, and there is step-by-step instructions to create your first Android application.

By following the guide, you will have a very simple GUI in a short time. You can then add your text interface to the GUI and think about how to integrate this interface with your IRC code.

Title: Android IRC Connection

Body:
As far as the TCP socket-based communication goes, doing it on Android should be similar to doing it on desktop computer. Therefore, you can develop your IRC communication code on desktop Java, and then copy the code over to the Android application.

http://developer.android.com/training/basics/network-ops/connecting.html

One thing to keep in mind is that you must give your Android application permissions to use the network. This is done by adding these to the application manifest.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

However, any program that runs on Android are required to have a graphical user interface - command-line console or text-based interface simply isn't an option on Android. Therefore, you will still have to learn Android GUI programming.

You should follow Android's Getting Started guide. The tools are free, and there is step-by-step instructions to create your first Android application.

By following the guide, you will have a very simple GUI in a short time. You can then add your text interface to the GUI and think about how to integrate this interface with your IRC code.


答: Before data binding was a popular method in UI libraries, the Tag property allowed you to place an Identifier that might be associated with a backend object (in Windows Forms the Tag property was an object, so you could place the entire object into the Tag).                                                                                </p>

Title: What is the origin of the tag property in UI toolkits?

Body: I've seen the tag property in all UI frameworks I worked with: UIKit, Forms, OpenStep, even Delphi 6. Was it in the original Macintosh Toolbox or Xerox's framework? WhAt was the original idea behind it?</p>


问:
Asp.net caching strategy/pattern
In my WebApi controller I have the following (pseudo) code that receives update notifications from Instagrams real-time API:

```<code>[HttpPost]
public void Post(InstagramUpdate instagramUpdate)
{
    var subscriptionId = instagramUpdate.SubscriptionId;
    var lastUpdate = GetLastUpdate(subscriptionId);

    // To avoid breaking my Instagram request limit, do not fetch new images too often.
    if (lastUpdate.AddSeconds(5) < DateTime.UtcNow)
    {
        // More than 5 seconds ago since last update for this subscription. Get new images
        GetNewImagesFromInstagram(subscriptionId);
        UpdateLastUpdate(subscriptionId, DateTime.UtcNow);
    }
}
</code>```

This won't work very well if I receive two update notifications for the same subscription almost simultaneously, since lastUpdate won't have been updated until after the first request has been processed. And even if I update lastUpdate directly, there is a "lag" because of the round trip to the database.

What would be the best way to tackle this problem? I'm thinking of using some kind of cache (that would be faster than the database roundtrip), but I'm not sure how. Is there some kind of best practices for these kind of things? I'm guessing it's a common problem: "receive notification, do something if something hasn't been done recently..."

答:
How about something like this?

```<code>private static readonly object _syncRoot = new object();

[HttpPost]
public void Post(InstagramUpdate instagramUpdate)
{
    var subscriptionId = instagramUpdate.SubscriptionId;
    var lastUpdate = GetLastUpdate(subscriptionId);

    // To avoid breaking my Instagram request limit, do not fetch new images too often.
    if (lastUpdate.AddSeconds(5) < DateTime.UtcNow)
    {
        lock (_syncRoot)
        {
           lastUpdate = GetLastUpdate(subscriptionId);

           if (lastUpdate.AddSeconds(5) < DateTime.UtcNow){
               GetNewImagesFromInstagram(subscriptionId);
               UpdateLastUpdate(subscriptionId, DateTime.UtcNow);
           }
        }
    }
</code>```

}

Title: Asp.net caching strategy/pattern

Body:
How about something like this?

private static readonly object _syncRoot = new object();

[HttpPost]
public void Post(InstagramUpdate instagramUpdate)
{
    var subscriptionId = instagramUpdate.SubscriptionId;
    var lastUpdate = GetLastUpdate(subscriptionId);

    // To avoid breaking my Instagram request limit, do not fetch new images too often.
    if (lastUpdate.AddSeconds(5) < DateTime.UtcNow)
    {
        lock (_syncRoot)
        {
           lastUpdate = GetLastUpdate(subscriptionId);

           if (lastUpdate.AddSeconds(5) < DateTime.UtcNow){
               GetNewImagesFromInstagram(subscriptionId);
               UpdateLastUpdate(subscriptionId, DateTime.UtcNow);
           }
        }
    }

}


问:
What are the real benefits of static code analysis?
Tools like pc-lint or QAC can be used to perform static code analysis on a code base.

In my experience the static analysis often yields a huge amount of noise, i.e. warnings on things that are not real bugs but somehow violate one of the rules in a given rule set. Turning off certain rules (either for good in the rule set or via special comments in the code) can be a real cumbersome process.

What are the real benefits of static code analysis?

答:
Static analyzers are basically machine-assisted code reviews. They'll point-out questionable areas that might be missed during regular testing.

For example, did the author really mean to make an assignment in this conditional?

```<code>if (x = 1) {
    ...
}
</code>```

Or perhaps a rookie confuses lexical casting:

```<code>char* number = "123";
int converted = number;
</code>```

Certainly static analyzers require tweaking. Then again, revision control, wikis, bug trackers, pretty printers and other tools require some set-up as well. The bigger the project, the better the reward for initial labor.

Body:
Static analyzers are basically machine-assisted code reviews. They'll point-out questionable areas that might be missed during regular testing.

For example, did the author really mean to make an assignment in this conditional?

if (x = 1) {
    ...
}

Or perhaps a rookie confuses lexical casting:

char* number = "123";
int converted = number;

Certainly static analyzers require tweaking. Then again, revision control, wikis, bug trackers, pretty printers and other tools require some set-up as well. The bigger the project, the better the reward for initial labor.


问:
How to program thread allocation on multicore processors?
I would like to experiment with threads on a multi-core processor, e.g. to create a program that uses two different threads that are executed by two different processor cores.

However, it is not clear to me at which level the threads get allocated to the different cores. I can imagine the following scenarios (depending on operating system and programming language implementation):

Thread allocation is managed by the operating system. Threads are created using OS system calls and, if the process happens to run on a multi-core processor, the OS automatically tries to allocate / schedule different threads on different cores.

Thread allocation is managed by the programming language implementation. Allocating threads to different core requires special system calls, but the programming language standard thread libraries automatically handle this when I use the standard thread implementation for that language.

Thread allocation must be programmed explicitly. In my program I have to write explicit code to detect how many cores are available and to allocate different threads to different core using, e.g.,  library functions.

To make the question more specific, imagine I have written my multi-threaded application in Java or C++ on Windows or Linux. Will my application magically see and use multiple cores when run on a multi-core processor (because everything is managed either by the operating system or by the standard thread library), or do I have to modify my code to be aware of the multiple cores?

答: I once had a huge SGI IRIX environment. Just for the heck of it, I wrote a small multi-threaded java program(which just did nothing but consume CPU cycles) and created 12 threads in it. The job spanned across 12 CPUs in NUMA architecture. May be I will look up the program and run it on the Dell R910s and check..</p>


问:
How much data from a web service should I expose in a library?
I'm working on a personal project, a library that can access the weather forecasts and other weather related data from it.

However, a lot of the returned data is sometimes quite redundant or simply doesn't make sense to have certain data within that particular XML element etc. Consider this XML data I get from the service, which contains the hourly forecast:

```<code><hour>20</hour>
<hour_padded>20</hour_padded>
<min>00</min>
<min_unpadded>0</min_unpadded>
<sec>0</sec>
<year>2015</year>
<mon>3</mon>
<mon_padded>03</mon_padded>
<mon_abbrev>Mar</mon_abbrev>
<mday>21</mday>
<mday_padded>21</mday_padded>
<yday>79</yday>
<isdst>0</isdst>
<epoch>1426968000</epoch>
<pretty>8:00 PM GMT on March 21, 2015</pretty>
<civil>8:00 PM</civil>
<month_name>March</month_name>
<month_name_abbrev>Mar</month_name_abbrev>
<weekday_name>Saturday</weekday_name>
<weekday_name_night>Saturday Night</weekday_name_night>
<weekday_name_abbrev>Sat</weekday_name_abbrev>
<weekday_name_unlang>Saturday</weekday_name_unlang>
<weekday_name_night_unlang>Saturday Night</weekday_name_night_unlang>
<ampm>PM</ampm>
</code>```

As you can see there is a lot of data that you probably don't need, because you can calculate/convert the time/date information into a simple DateTime etc. Another useless series of fields is the "padded" ones. There a lot of other examples of this redundancy with other types of weather data as well.

So how should I approach this, have literally every field in the XML available to the user of the library, or just stick to having only the parts that make sense available to the user? I'm leaning towards only the parts that make sense, but wanted to ask the opinion of others.

答:
I would follow the YAGNI principle and carefully think through what the client needs on his/her side.

Including things that you think the client is going to need is a symptom of a core problem - that being lack of research and/or knowledge what the client actually needs.


答:
If the purpose of your API is just to provide data (which is true in my opinion),
then do not return redundant or formatted values.

In your example, returning single date/time is enough.
This makes your response more concise and less ambitious.

Making assumptions about consumer GUI and interpretation
of provided data is usually wrong approach, avoid.

Title: How much data from a web service should I expose in a library?

Body:
I'm working on a personal project, a library that can access the weather forecasts and other weather related data from it.

However, a lot of the returned data is sometimes quite redundant or simply doesn't make sense to have certain data within that particular XML element etc. Consider this XML data I get from the service, which contains the hourly forecast:

```<code><hour>20</hour>
<hour_padded>20</hour_padded>
<min>00</min>
<min_unpadded>0</min_unpadded>
<sec>0</sec>
<year>2015</year>
<mon>3</mon>
<mon_padded>03</mon_padded>
<mon_abbrev>Mar</mon_abbrev>
<mday>21</mday>
<mday_padded>21</mday_padded>
<yday>79</yday>
<isdst>0</isdst>
<epoch>1426968000</epoch>
<pretty>8:00 PM GMT on March 21, 2015</pretty>
<civil>8:00 PM</civil>
<month_name>March</month_name>
<month_name_abbrev>Mar</month_name_abbrev>
<weekday_name>Saturday</weekday_name>
<weekday_name_night>Saturday Night</weekday_name_night>
<weekday_name_abbrev>Sat</weekday_name_abbrev>
<weekday_name_unlang>Saturday</weekday_name_unlang>
<weekday_name_night_unlang>Saturday Night</weekday_name_night_unlang>
<ampm>PM</ampm>
</code>```

As you can see there is a lot of data that you probably don't need, because you can calculate/convert the time/date information into a simple DateTime etc. Another useless series of fields is the "padded" ones. There a lot of other examples of this redundancy with other types of weather data as well.

So how should I approach this, have literally every field in the XML available to the user of the library, or just stick to having only the parts that make sense available to the user? I'm leaning towards only the parts that make sense, but wanted to ask the opinion of others.


问:
Simulating a Production Line
I'm trying to simulate a DVD production line in Java. The thing I have a problem with is the calculation of the time in this kind of simulation and the number of DVDs per hour.

The production line consists of 4 machines, each of which spends a certain random time working on 1 DVD. The third one can work on more than 1 DVD at the same time (max. 100). Also, the third one will always accept more DVDs  to work on, as long it's capacity is < 50%, which I plan to label as m3Capacity. But for now, let's just ignore the capacity characteristic.

What I have so far is that, with a random number generator (since each machine has random DVD processing time each time it starts working on a new DVD), I assigned a random processing time to each of the four machines, summed up their processing times for the total time spent in one-go production (totalProdTime = processTime1 + processTime2 + processTime3 + processTime4), and then I keep summing up those totalProdTime values until the total time of the whole simulation reaches the desired duration of the simulation specified by the user (totalProdTimeSim = totalProdTimeSim + mTotal.totalProdTime).  Later I just verify whether the totalProdTimeSim has reached the desired time and that's it.

Now, the problem is that, this way, the production of the DVDs waits for one instance of production to finish all the way until the very end of the machine 4, and then the work begins on the second DVD, etc. What I want to do is that after machine 1 finishes it's work, and the second one begins its work, machine 1 begins work on another DVD with it's newly generated time. The same goes for all other machines. After machine 2 finishes work on a DVD, it immediately begins working on another DVD.

Now, since all machines have random processing times each time they start working on another DVD, it will often happen that one machine 'wants to work on another DVD' while the previous one hasn't finished its work on the current one. In this case, the idle machine just 'waits' for the previous machine to finish processing and then accepts the DVD from the previous machine.

So, in my example, we have that all the machines work one by one, but I want them all to work constantly, even after they finish working on the current DVD (except  in the first iteration, where the further machines need to wait for the previous ones to forward them their DVD they previously worked on).

How do you think I should calculate the total simulation time and DVD output? I've been thinking last night about it, but haven't gotten any ideas.

My sketch of how it should work can be found in the picture below. In the sketch all machines behave as if they constantly have something to work on, but should wait from the input from the previous machine.

Thanks in advance!

答:
An odd question, and I'm not really sure it fits here... Here is a brute-force approach.

If I were to write code to solve this, I would create a ProductionLine class that contains a list of Machine-objects, along with a DiskOuput counter. The ProductionLine-class would have a method ('timePasses') you can call to simulate the passing of time, say 1-second increments. This would in turn call onto the Machine-objects who would also have a timePasses method. The Machine knows how many calls of timePasses are needed before it finishes wirting a disk (the random amount of seconds). When a Machine finishes writing a disk, the timePasses object would return a value to indicate a disk was finished. The Machine would then reset the random number of seconds needed to write a disk and start over. The ProductionLine class knows that when timePasses returns a value, the DiskOuput counter should be incremented because a disk was finished.

You now have an application where all machines start at the same time. You can run this with a loop until a certain amount of time passes or until DiskOuput reaches a certain value.

Now, to make your machines dependent on the first disk... Your ProductionLine would have a list of Machines (the 'pool' of available machines in the line) and a list of RunningMachines (that are currently producing something). You would only call timePasses on running machines. When you call timePasses on ProductionLine the first time it would take a Machine from the pool, put in onto RunningMachines and call timePasses on it. Every time a call to timePasses on a Machine indicates that a new disk is ready, the ProductionLine could check if additional machines are available and if so, put them onto the RunningMachines-list and start working with it.

Title: Simulating a Production Line