问:
What is the correct way to deal with similar but independent features?
Let's say we have a feature request come in and we begin work on it, which we'll call feature-1. It introduces some new logic to the application, which we'll call logic-A and logic-B. A programmer branches from the release branch and begins work on the feature.

Soon after, we get another feature request, which we'll call feature-2. It will implement logic-A and logic-C into the application. The logic A being implemented by this feature is the same logic-A as was implemented in feature-1.

Let's also say that given logic-B, logic-A might be implemented slightly differently than it would have been given logic-C, and also differently given both logic-B and logic-C (eg. with only one feature, the code would be less flexible than with both).

How should this situation be handled?

Concrete Example (to help with any confusion in my wording)

feature-1 is a feed from programmers.stackexchange.com.

feature-2 is a feed from gaming.stackexchange.com.

logic-A is the implementation of a feed at all (assuming the application currently has no feeds), which links to the content as well and gives related information.

logic-B is that the feed's source is from programmers.stackexchange.com.

Adds to logic-A that the related programming language is displayed.

logic-C is that the feed's source is from gaming.stackexchange.com.

Adds to logic-A that the related game's name and box art is displayed.

答:
I assume feature2 arrived before too much work had been done on feature1. Otherwise you need to finish feature1 first. But if you have the luxury of choosing...
Prioritize feature1 and feature2 based on how much value they add to the project.
Add logicA in the way that benefits the feature you're adding first. It's ok to at least be aware that you will use logicA for another feature, but don't go nuts.
Finish the first feature, so logicA is earning the highest amount of value possible (because you prioritized the most valuable feature).
Refactor logicA as needed to implement the other feature.This earns the most value soonest.

After coding the first feature, you get a chance to decide if the cost of refactoring logicA is too high and not do the second feature unless it becomes more valuable. You know more about logicA. Maybe your fear that you couldn't reuse logicA is unfounded. You also have experience implementing logicA. So if you have to refactor or completely redesign logicA, you can do it from a standpoint of knowledge, rather than trying to design logicA for any conceivable use from a standpoint of no real knowledge of the use cases.


问:
Why do we need to include the .h while everything works when including only the .cpp file?
Why do we need to include both the .h and .cpp files while we can make it work solely by including the .cpp file?

For example: creating a file.h containing declarations, then creating a file.cpp containing definitions and including both in main.cpp.

Alternatively: creating a file.cpp containing declaration/definitions ( no prototypes ) including  it in main.cpp.

Both work for me. I can't see the difference. Maybe some insight into the compiling and linking process may help.

答:
While you can include .cpp files as you mentioned, this is a bad idea.

As you mentioned, declarations belong in header files. These cause no problems when included in multiple compilation units because they do not include implementations. Including a the definition of a function or class member multiple times will normally cause a problem (but not always) because the linker will get confused and throw an error.

What should happen is each .cpp file includes definitions for a subset of the program, such as a class, logically organized group of functions, global static variables (use sparingly if at all), etc.

Each compilation unit (.cpp file) then includes whatever declarations it needs to compile the definitions it contains. It keeps track of the functions and classes it references but does not contain, so the linker can resolve them later when it combines the object code into an executable or library.

Example

Foo.h -> contains declaration (interface) for class Foo.

Foo.cpp -> contains definition (implementation) for class Foo.

Main.cpp -> contains main method, program entry point. This code instantiates a Foo and uses it.

Both Foo.cpp and Main.cpp need to include Foo.h. Foo.cpp needs it because it is defining the code that backs the class interface, so it needs to know what that interface is. Main.cpp needs it because it is creating a Foo and invoking its behavior, so it has to know what that behavior is, the size of a Foo in memory and how to find its functions, etc. but it does not need the actual implementation just yet.

The compiler will generate Foo.o from Foo.cpp which contains all of the Foo class code in compiled form. It also generates Main.o which includes the main method and unresolved references to class Foo.

Now comes the linker, which combines the two object files Foo.o and Main.o into an executable file. It sees the unresolved Foo references in Main.o but sees that Foo.o contains the necessary symbols, so it "connects the dots" so to speak. A function call in Main.o is now connected to the actual location of the compiled code so at runtime, the program can jump to the correct location.

If you had included the Foo.cpp file in Main.cpp, there would be two definitions of class Foo. The linker would see this and say "I don't know which one to pick, so this is an error." The compiling step would succeed, but linking would not. (Unless you just do not compile Foo.cpp but then why is it in a separate .cpp file?)

Finally, the idea of different file types is irrelevant to a C/C++ compiler. It compiles "text files" which hopefully contain valid code for the desired language. Sometimes it may be able to tell the language based on the file extension. For example, compile a .c file with no compiler options and it will assume C, while a .cc or .cpp extension would tell it to assume C++. However, I can easily tell a compiler to compile a .h or even .docx file as C++, and it will emit an object (.o) file if it contains valid C++ code in plain text format. These extensions are more for the benefit of the programmer. If I see Foo.h and Foo.cpp, I immediately assume that the first contains the declaration of the class and the second contains the definition.

ContentLicense: CC BY-SA 4.0

ContentLicense: CC BY-SA 3.0


问:
How does Python compile some its code in C?
I read that some constructs of Python are more efficient because they are compiled in C.

https://wiki.python.org/moin/PythonSpeed/PerformanceTips

Some of the examples used were map() and filter(). I was wondering how Python is able to do this? It's generally interpreted, so how does some of the code get compiled while another is interpreted - and in a different language? Why not just compile the whole thing?

答:
The interpreter itself is written in C (or at least the reference implementation CPython is). That means every language feature is implemented with a tiny C function. All the interpreter does is read the sourcecode to find out which of these tiny functions to call.

This means it is not a problem to also delegate more complex functions to C implementations.

These functions are not compiled with your program. They already exist in compiled form in the Python interpreter which just calls them when it encounters them in your sourcecode.


答: It's not "compiled in C" per se: map and filter are built-in functions from the standard library, which is provided by the language implementation (in this case, CPython).  Since CPython is written in C, it can easily implement any of its primitive functions in C if needed.

Title: How does Python compile some its code in C?

Body:
I read that some constructs of Python are more efficient because they are compiled in C.

https://wiki.python.org/moin/PythonSpeed/PerformanceTips

Some of the examples used were map() and filter(). I was wondering how Python is able to do this? It's generally interpreted, so how does some of the code get compiled while another is interpreted - and in a different language? Why not just compile the whole thing?


问:
Why does void in C mean not void?
In strongly-typed languages like Java and C#, void (or Void) as a return type for a method seem to mean:

This method doesn't return anything. Nothing. No return. You will not receive anything from this method.

What's really strange is that in C, void as a return type or even as a method parameter type means:

It could really be anything. You'd have to read the source code to find out.  Good luck. If it's a pointer, you should really know what you're doing.

Consider the following examples in C:

```<code>void describe(void *thing)
{
    Object *obj = thing;
    printf("%s.\n", obj->description);
}

void *move(void *location, Direction direction)
{
    void *next = NULL;

    // logic!

    return next;
}
</code>```

Obviously, the second method returns a pointer, which by definition could be anything.

Since C is older than Java and C#, why did these languages adopt void as meaning "nothing" while C used it as "nothing or anything (when a pointer)"?

答:
In C, it is possible to have a pointer to things of any type [pointers behave as a type of reference].  A pointer may identify an object of a known type, or it may identify an object of arbitrary (unknown) type.  The creators of C chose to use the same general syntax for "pointer to thing of arbitrary  type" as for "pointer to thing of some particular type".  Since the syntax in the latter case requires a token to specify what the type is, the former syntax requires putting something where that token would belong if the type were known.  C chose to use the keyword "void" for that purpose.

In Pascal, as with C, it is possible to have pointers to things of any type; more popular dialects of Pascal also allow "pointer to thing of arbitrary type", but rather than using the same syntax as they use for "pointer to thing of some particular type", they simply refer to the former as Pointer.

In Java, there are no user-defined variable types; everything is either a primitive or a heap object reference.  One can define things of type "reference to a heap object of a particular type" or "reference to a heap object of arbitrary type".  The former simply uses the type name without any special punctuation to indicate that it's a reference (since it can't be anything else); the latter uses the type name Object.

The use of void* as the nomenclature for a pointer to something of arbitrary type is so far as I know unique to C and direct derivatives like C++; other languages I know of handle the concept by simply using a distinctly-named type.

Title: Why does void in C mean not void?


问:
How can I find the shortest path between two subgraphs of a larger graph?
I'm working with a weighted, undirected multigraph (loops not permitted; most node connections have multiplicity 1; a few node connections have multiplicity 2). I need to find the shortest path between two subgraphs of this graph that do not overlap with each other. There are no other restrictions on which nodes should be used as start/end points.

Edges can be selectively removed from the graph at certain times (as explained in my previous question) so it's possible that for two given subgraphs, there might not be any way to connect them.

I'm pretty sure I've heard of an algorithm for this before, but I can't remember what it's called, and my Google searches for strings like "shortest path between subgraphs" haven't helped. Can someone suggest a more efficient way to do this than comparing shortest paths between all nodes in one subgraph with all nodes in the other subgraph? Or at least tell me the name of the algorithm so I can look it up myself?

For example, if I have the graph below, the nodes circled in red might be one subgraph and the nodes circled in blue might be another. The edges would all have positive integer weights, although they're not shown in the image. I'd want to find whatever path has the shortest total cost as long as it starts at a red node and ends at a blue node. I believe this means the specific node positions and edge weights cannot be ignored.

(This is just an example graph I grabbed off Wikimedia and drew on, not my actual problem.)

答:
You should be able to adapt Dijkstra's algorithm.

Just add two points A & B to your graph, which are connected to one of the subgraphs each. Then calculate the shortest path between the two points A & B.

The shortest path between the two subgraphs should be the path that you get after removing A & B from the result.


答:
I read that some constructs of Python are more efficient because they are compiled in C.

That's not true.

First off, there is nothing in the specification of the Python language that requires that certain functions have to be implemented in a certain language. A Python implementor can choose to implement any function and language construct anyway he wants. For example, in Jython, those functions are implemented in Java, not in C. In IronPython, they are implemented in C#. In PyPy, they might be implemented in RPython or just in Python. In Pynie, they are probably implemented in Python.

Seondly, there is nothing in the specification of the C language that says that it must be compiled. There are interpreters for C.

Thirdly, just because it is in C doesn't mean it's fast. There are C compilers out there which produce really terrible code, and there are pretty fast Python implementations.

And fourth, even if the function implemented in C is blazingly fast, that doesn't necessarily translate into faster execution speed of the overall program. Optimizations typically don't work across languages. For example, the optimizer can't inline the call to map into your program, because your program is written in Python but map is written in C. But inlining is pretty much the foundation of all optimizations, because inlining (and loop unrolling) give nice long straight paths of code without branches or calls, which is what optimizers love.

It's generally interpreted,

Actually, all currently existing Python implementations always compile Python code, they never interpret it.

Why not just compile the whole thing?

That's a good question! Writing everything in the same language has many advantages, some of which I outlined above. (Another one is that it's easier to find collaborators who know one language than two.)

If everything is written in the same language, then performance improvements to that language get multiplied throughout the whole system. If everything is written in C, then making the Python 10 times faster isn't going to speed up your program much, because most of the code isn't Python. Sure, the code you wrote is running 10 times faster, but that code mostly consists of calls to C functions which have the same speed as before.

But if everything is written in Python, then making Python faster will have a ripple effect: the primitive types get faster, the datastructures built on top of those primitive types get faster, the algorithms using those datastructures get faster, the modules using those algorithms get faster and so on.


答:
Snowman's example need a little extension to show you exactly why .h files are needed.

Add another class Bar into the play which is also dependent on class Foo.

Foo.h -> contains declaration for class Foo

Foo.cpp -> contains definition (impementation) of class Foo

Main.cpp -> uses variable of the type Foo.

Bar.cpp -> uses variable of type Foo too.

Now all cpp files needs to include Foo.h
It would be an error to include Foo.cpp in more than one other cpp file.
Linker would fail because class Foo would be defined more than once.

Title: Why do we need to include the .h while everything works when including only the .cpp file?

Body:
Why do we need to include both the .h and .cpp files while we can make it work solely by including the .cpp file?

For example: creating a file.h containing declarations, then creating a file.cpp containing definitions and including both in main.cpp.

Alternatively: creating a file.cpp containing declaration/definitions ( no prototypes ) including  it in main.cpp.

Both work for me. I can't see the difference. Maybe some insight into the compiling and linking process may help.


答:
Due to C++'s multiple-unit build model, you need a way to have code that appears in your program only once (definitions), and you need a way to have code that appears in each translation unit of your program (declarations).

From this is born the C++ header idiom. It's convention for a reason.

You can dump your entire program into a single translation unit, but this introduces problems with code re-use, unit testing and inter-module dependency handling. It's also just a big mess.


问:
Why does the instruction "do" require a "while"?
Since this statement is so common:

while (true) (Java)

or

while (1) (C)

or sometimes

for (;;)

Why is there not a single instruction for this? I could think that an instruction that could do it is just do but do requires a while at the end of the block but it would be more logical to write an infinite loop like this

```<code>do {

//loop forever

}
</code>```

Why not? AFAIK the instruction do always requires a while at the end but if we could use it like above then it would be a clear way to define something like while (true) which I think should not be written like that (or for (;;)).

答:
What should be the meaning of:

```<code>do
{
  doThis();
  doThat();
  if(shouldExit())
    break();
  theOtherThing();
}
while(read_data() != null)
  ;
</code>```

If some other keyword had been used for expressing the continuation condition of a do loop (as with Pascal's Repeat...Until) then it might have been possible to make the continuation condition optional.  As it is, however, while(condition); can either appear as the last thing in a do/while or as a stand-alone loop.  Something must appear between the controlled statement of a do/while and a succeeding stand-alone statement, and its easiest to simply have that something always be a while(expr); clause.

Body:
What should be the meaning of:

do
{
  doThis();
  doThat();
  if(shouldExit())
    break();
  theOtherThing();
}
while(read_data() != null)
  ;

If some other keyword had been used for expressing the continuation condition of a do loop (as with Pascal's Repeat...Until) then it might have been possible to make the continuation condition optional.  As it is, however, while(condition); can either appear as the last thing in a do/while or as a stand-alone loop.  Something must appear between the controlled statement of a do/while and a succeeding stand-alone statement, and its easiest to simply have that something always be a while(expr); clause.


答:
Infinite loops are generally regarded as bad pratcice, and thus it wouldn't make sense to include a dedicated syntax for them in a language. Special syntax (or 'syntatic sugar') is added for common tasks, such as an unless block in addition to an if block, to make the code more 'friendly' and readable.

Since infinite loops are fairly rare, and are generally regarded as bad practice, it wouldn't be a good idea to support them in a language via a dedicated syntax.

Title: Why does the instruction "do" require a "while"?

Body:
Since this statement is so common:

while (true) (Java)

or

while (1) (C)

or sometimes

for (;;)

Why is there not a single instruction for this? I could think that an instruction that could do it is just do but do requires a while at the end of the block but it would be more logical to write an infinite loop like this

```<code>do {

//loop forever

}
</code>```

Why not? AFAIK the instruction do always requires a while at the end but if we could use it like above then it would be a clear way to define something like while (true) which I think should not be written like that (or for (;;)).


问:
Cheerp -- C++ for web: advance or regression?
Recently I've run into Cheerp, a C++ to Javascript compiler, which uses a modified version of clang to generate Javascript code from C++ sources.

That makes me wonder: why in the seven kingdoms would someone do this in their right mind?

I mean: why would you take a language that is not designed for web at all, that is far more convoluted and bureaucratic, write your code and then compile it into Javascript itself?

Can anybody see any advantages in doing so?

We surely can discard performance as a reason, because in the end it generates pure Javascript code.

Is there anyone here that have real experience with this?

P.S.: I'm not sure if this is an on topic question, but this is the most general forum about programming that I could find in the StackExchange network.

Edit

Although this seems like a subjective question, it is not.

I am asking for reasons why this tool could be useful. I got interested at first, but started wondering why would someone use it.

答:
Questioned framework is built on top of LLVM, which can be used to compile anything to anything (pretty awesome BTW).

Using LLVM as a cpp-to-js compiler should be taken into consideration when existing C++ program (let's say >=100kLOC) is to be ported to the web browser. From a technical point of view, I see 2 cases:

Creating nice JavaScript API around reusable parts of C++ code and coding the rest JavaScript.

Implementing platform-specific parts in JavaScript and sticking with C++ for the main logic.

Porting almost all C++ GUI programs will require creating browser-based implementation of used UI libraries.
If ported program had nothing to do with the network, significant amount of code that handles user accounts and data storage must also be added.

Cheerp provides DOM and GL APIs (that could be used to port GUI libraries) and also implements automagical server function call mechanism (that could greatly simplify writing client-server code). I don't have any experience in using this framework, but after looking at the number of commits in cheerp-clang and cheerp-llvm repositories, I would say that it's pretty mature and worth trying out.

From functionality point of view, I see compile-to-js potential in:

Advanced libraries coded in C++ (cryptographic algorithms, neural nets, etc.),

Everyday programs (mail clients, IM clients, media players, IDEs),

3D games (check out port of Quake III game to WebGL),

Web browsers (as a punishment for excessive usage of recursion :P).

Code compiled from C++ could come off better in microbenchmarks than native JavaScript because of LLVM's compiler optimizations.


答:
Saying that they are "compiled in C" is a bit confusing statement. Let me rephrase it: CPython (the most widespread implementation of the Python interpreter, to which you are referring) is a C program, and those are C functions built in the interpreter, not Python code that the interpreter magically chooses to compile to C.

When you feed a .py file to Python, it parses it and converts each function into bytecode, i.e. a compact binary form of the operations that the function does . This is fed to the Python virtual machine, a piece of the interpreter which reads the bytecode and does what it tells it to do.

When you call functions written in Python nothing special happens: the VM will just jump to interpret their bytecode; but when you call a function that is built in inside the interpreter, the interpreter calls the corresponding C function that it has built in (this happens all the time, for example most operations on primitive types are actually performed by code compiled directly inside the interpreter).

Function written in C in CPython are generally faster, both because they are written in a language that is tailored for high performance, compiled to native code (no need for an interpreter, runs directly on the CPU) and has simpler, less dynamic semantics (for example, in Python each access to a member is a complex hashtable lookup, in C it can boil down to a single assembly instruction).

It's generally interpreted, so how does some of the code get compiled while another is interpreted - and in a different language? Why not just compile the whole thing?

You seem to think that the it's the interpreter to decide what code is compiled and what is interpreted; that's a wrong premise. The compiled parts are code that it's written directly in C by the CPython developers, and is compiled inside the interpreter when the interpreter is built (other code written in C or other compiled languages can be called by Python if it's compiled in Python extensions or via ctypes). All the CPython interpreter can do when you run it is just to interpret Python and call ready-made C functions.


问:
Is my class structure good enough?
So I wanted to try out this challenge on reddit which is mostly about how you structure your data the best you can. I decided to challenge my C++ skills. Here's how I planned this.

First, there's the Game class. It deals with time and is the only class main has access to.

A game has a Forest. For now, this class does not have a lot of things, only a size and a Factory. Will be put in better use when it will come to SDL-stuff I guess

A Factory is the thing that deals with the Game Objects (a.k.a. Trees, Lumberjack and Bears). It has a vector of all GameObjects and a queue of Events which will be managed at the end of one month.

A GameObject is an abstract class which can be updated and which can notify the Event Listener

The EventListener is a class which handles all the Events of a simulation. It can recieve events from a Game Object and notify the Factory if needed, the latter will manage correctly the event.

So, the Tree, Lumberjack and Bear classes all inherits from GameObject. And Sapling and Elder Tree inherits from Tree.

Finally, an Event is defined by an event_type enumeration (LUMBERJACK_MAWED, SAPPLING_EVOLUTION, ...) and an event_protagonists union (a GameObject or a pair of GameObject (who killed who ?)).

I was quite happy at first with this because it seems quite logic and flexible. But I ended up questionning this structure. Here's why :

I dislike the fact that a GameObject need to know about the Factory. Indeed, when a Bear moves somewhere, it needs to know if there's a Lumberjack ! Or it is the Factory which handles places and objects. It would be great if a GameObject could only interact with the EventListener... or maybe it's not that much of a big deal.

Wouldn't it be better if I separate the Factory in three vectors ? One for each kind of GameObject. The idea would be to optimize research. If I'm looking do delete a dead lumberjack, I would only have to look in one shorter vector rather than a very long vector.

Another problem arises when I want to know if there is any particular object in a given case because I have to look for all the gameObjects and see if they are at the given case. I would tend to think that the other idea would be to use a matrix but then the issue would be that I would have empty cases (and therefore unused space).

I don't really know if Sapling and Elder Tree should inherit from Tree. Indeed, a Sapling is a Tree but what about its evolution ? Should I just delete the sapling and say to the factory to create a new Tree at the exact same place ? It doesn't seem natural to me to do so. How could I improve this ?

Is the design of an Event quite good ? I've never used unions before in C++ but I didn't have any other ideas about what to use.

Well, I hope I have been clear enough. Thank you for taking the time to help me !

答:
If I understand your design, there is no need for the GameObject to know the Factory type. The only case where a GameObject would need to access a factory is when it needs to create another GameObject, which is common for objects that spawn other objects. However, since you are already using an event system, you can just define an event type such as "create object". This way, the GameObject type can spawn/create other objects by firing an event, without knowing about the existence of a Factory.

No, not a good idea to separate the GameObjects by "type", GameObject is supposed to be an abstraction, if you start typing it, you loose that abstraction and create coupling. Also, this would not be scalable if you where to introduce another specialized GameObject "type". It would require changing the factory to add another container for this new type. OOP-wise, it is best to keep the GameObject abstract.

You can optimize search and management of the GameObjects by using a more efficient data structure. A scene graph or a quadtree can reduce the number of queries when dealing with a lot of GameObjects spread into a given space. Also, for the specific case of removal, you can delegate that task to the GameObject itself. When the object is expired, make it fire an event: E.g.: new Event_RemoveObject(this) that passes itself as the event argument. When the event is handled, the event manager will know who to delete.

If you want to design for scalability, it is best to avoid inheritance. Taking the Tree case, other more specific kinds of trees don't need to be objects in their own right. You can use configuration parameters to define that. This is what is otherwise known as Component Based Design. Define the behavior of a GameObject from the set of its components. This makes for a very flexible and extensible approach.

Yes, you can use a C++ union to define a Variant type.

This is an example I have used before:

```<code>union Data {
    void *    asVoidPtr;
    bool      asBoolean;
    int       asInteger;
    float     asFloat;
    char *    asCString;
    Vector3 * asVector3;
    Vector4 * asVector4;
};
// Plus an enum flag that tell which field of the
// union is in use, e.g.: a "type tag"
</code>```

It should be enough if the parameters of your events are only primitive types and raw pointers. If you need more complex parameters like objects and smart pointers, then your best bet is to define an abstract Event class and specialize it as needed.

Title: Is my class structure good enough?

Body:
If I understand your design, there is no need for the GameObject to know the Factory type. The only case where a GameObject would need to access a factory is when it needs to create another GameObject, which is common for objects that spawn other objects. However, since you are already using an event system, you can just define an event type such as "create object". This way, the GameObject type can spawn/create other objects by firing an event, without knowing about the existence of a Factory.

No, not a good idea to separate the GameObjects by "type", GameObject is supposed to be an abstraction, if you start typing it, you loose that abstraction and create coupling. Also, this would not be scalable if you where to introduce another specialized GameObject "type". It would require changing the factory to add another container for this new type. OOP-wise, it is best to keep the GameObject abstract.

You can optimize search and management of the GameObjects by using a more efficient data structure. A scene graph or a quadtree can reduce the number of queries when dealing with a lot of GameObjects spread into a given space. Also, for the specific case of removal, you can delegate that task to the GameObject itself. When the object is expired, make it fire an event: E.g.: new Event_RemoveObject(this) that passes itself as the event argument. When the event is handled, the event manager will know who to delete.

If you want to design for scalability, it is best to avoid inheritance. Taking the Tree case, other more specific kinds of trees don't need to be objects in their own right. You can use configuration parameters to define that. This is what is otherwise known as Component Based Design. Define the behavior of a GameObject from the set of its components. This makes for a very flexible and extensible approach.

Yes, you can use a C++ union to define a Variant type.

This is an example I have used before:

union Data {
    void *    asVoidPtr;
    bool      asBoolean;
    int       asInteger;
    float     asFloat;
    char *    asCString;
    Vector3 * asVector3;
    Vector4 * asVector4;
};
// Plus an enum flag that tell which field of the
// union is in use, e.g.: a "type tag"

It should be enough if the parameters of your events are only primitive types and raw pointers. If you need more complex parameters like objects and smart pointers, then your best bet is to define an abstract Event class and specialize it as needed.


问:
Which Continuous Integration framework do you use and why?
There are quite a few different Continuous Integration (CI) frameworks out there and I'm wondering which is the most popular.  Which frameworks have you used at firms where you work?

Is there any reason one CI framework is more popular than another - perhaps this is to do with the features it offers, things that integrate into it or maybe its just marketing?

It seems like continuous integration is used more in the Java and .net worlds than say ruby or python.  Why is this?

答:
Hudson. It's a little buggy at times, and some of the more interesting plugins don't actually work, but with a little handholding it's pretty usable.

I'd probably use Pulse instead, but if you need to build on multiple platforms it's >$5k, which is a bit much.

ContentLicense: CC BY-SA 2.5


问:
git workflow for separating commits
Best practices with git (or any VCS for that matter) is supposed to be to have each commit do the smallest change possible. But, that doesn't match how I work at all.

For example I recently I needed to add some code that checked if the version of a plugin to my system matched the versions the system supports. If not print a warning that the plugin probably requires a newer version of the system. While writing that code I decided I wanted the warnings to be colorized. I already had code that colorized error message so I edited that code. That code was in the startup module of one entry to the system. The plugin checking code was in another path that didn't use that entry point so I moved the colorization code into a separate module so both entry points could use it. On top of that, in order to test my plugin checking code works I need to go edit UI/UX code to make sure it tells the user "You need to upgrade".

When all is said and done I've edited 10 files, changed dependencies, the 2 entry points are now both dependant on the colorization code, etc etc. Being lazy I'd probably just git add . && git commit -a the whole thing. Spending 10-15 minutes trying to manipulate all those changes into 3 to 6 smaller commits seems frustrating which brings up the question

Are there workflows that work for you or that make this process easier?

I don't think I can some how magically always modify stuff in the perfect order since I don't know that order until after I start modifying and seeing what comes up.

I know I can git add --interactive etc but it seems, at least for me, kind of hard to know what I'm grabbing exactly the correct changes so that each commit is actually going to work. Also, since the changes are sitting in the current directory it doesn't seem like it would be easy to run tests on each commit to make sure it's going to work short of stashing all the changes. And then, if it were to stash and then run the tests, if I missed a few lines or accidentally added a few too many lines I have no idea how I'd easily recover from that. (as in either grab the missing lines from the stash and then put the rest back or take the few extra lines I shouldn't have grabbed and shove them into the stash for the next commit.

Thoughts? Suggestions?

PS: I hope this is an appropriate question. The help says development methodologies and processes

答:
The thing to realize is the smallest commits are most beneficial to you, during development.  If you wait until you're ready to push to separate out commits, you're missing out on a lot of help your tool could be providing.

What you do is work on recognizing when you're switching gears, and just make a commit or a branch on the spot.  That lets your tool help answer questions like "what changed since I started working on the colorizing code?"  It lets you more easily back out partial changes when you realize you're taking the wrong approach, which happens most frequently right after you first write something.  It also sometimes help keep you from distractedly bouncing around from one task to another.  Because you don't want to make a branch, you focus and get the part you're working on to a good place for a commit.

Often people want to clean it up before a push anyway, but the difference now is you already have nice small commits breaking everything up, they just might need some rearranging and consolidation, which is a lot easier than doing the breaking up after the fact.

Title: git workflow for separating commits


答:
My own general rule is to keep commits as modular as possible. When developing something new, I keep commits relative to sections in the wireframes so they relate to pages/sections. While maintaining a consistent naming convention that others could quickly pick up on.

Regardless of how many files are in a commit at a time, I think an important questions is, do the files in the commit all pertain to the message. I find I commonly have minor, insignificant changes that are part of the commit that aren't totally relevant, but this is bound to happen form time to time. After I've finished major milestones, i habitually create annotated tags with git tag -a NAME_OF_TAG. If you're using something like github, gitlab, or bitbucket, you can download these sections for historical reference.

Commonly I find myself adding files to the repo, at points where I haven't committed files I am already tracking. It's handy to use git add -u, which adds only files you are tracking to the staging area. Once the tracked files are committed, I can move on to adding and committing the newly added files.

Keeping things in order seems to be hardest when you're a) refactoring or b) fixing bugs. At these points I like to make branches which further helps keep me organized, as well as keeping the main line safe.

A useful tool for re-organization, git rebase -i. I've rebased at a time where I needed to change the order of two commits and this was a handy way to alter history in a helpful way. Rebase has much more it is capable of, but thats just one example. Editing commit messages is also possible during an interactive rebase. Rebasing is an option to be aware of, I would rely on this as a "first option".

Title: git workflow for separating commits

Body:
Best practices with git (or any VCS for that matter) is supposed to be to have each commit do the smallest change possible. But, that doesn't match how I work at all.

For example I recently I needed to add some code that checked if the version of a plugin to my system matched the versions the system supports. If not print a warning that the plugin probably requires a newer version of the system. While writing that code I decided I wanted the warnings to be colorized. I already had code that colorized error message so I edited that code. That code was in the startup module of one entry to the system. The plugin checking code was in another path that didn't use that entry point so I moved the colorization code into a separate module so both entry points could use it. On top of that, in order to test my plugin checking code works I need to go edit UI/UX code to make sure it tells the user "You need to upgrade".

When all is said and done I've edited 10 files, changed dependencies, the 2 entry points are now both dependant on the colorization code, etc etc. Being lazy I'd probably just git add . && git commit -a the whole thing. Spending 10-15 minutes trying to manipulate all those changes into 3 to 6 smaller commits seems frustrating which brings up the question

Are there workflows that work for you or that make this process easier?

I don't think I can some how magically always modify stuff in the perfect order since I don't know that order until after I start modifying and seeing what comes up.

I know I can git add --interactive etc but it seems, at least for me, kind of hard to know what I'm grabbing exactly the correct changes so that each commit is actually going to work. Also, since the changes are sitting in the current directory it doesn't seem like it would be easy to run tests on each commit to make sure it's going to work short of stashing all the changes. And then, if it were to stash and then run the tests, if I missed a few lines or accidentally added a few too many lines I have no idea how I'd easily recover from that. (as in either grab the missing lines from the stash and then put the rest back or take the few extra lines I shouldn't have grabbed and shove them into the stash for the next commit.

Thoughts? Suggestions?

PS: I hope this is an appropriate question. The help says development methodologies and processes


问:
Why doesn't Python have a "flatten" function for lists?
Erlang and Ruby both come with functions for flattening arrays. It seems like such a simple and useful tool to add to a language. One could do this:

```<code>>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> mess.flatten()
[1, 2, 3, 4, 5, 6]
</code>```

Or even:

```<code>>>> import itertools
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> list(itertools.flatten(mess))
[1, 2, 3, 4, 5, 6]
</code>```

Instead, in Python, one has to go through the trouble of writing a function for flattening arrays from scratch. This seems silly to me, flattening arrays is such a common thing to do. It's like having to write a custom function for concatenating two arrays.

I have Googled this fruitlessly, so I'm asking here; is there a particular reason why a mature language like Python 3, which comes with a hundred thousand various batteries included, doesn't provide a simple method of flattening arrays? Has the idea of including such a function been discussed and rejected at some point?

答:
It does come with such a method but it doesn't call it flatten. It's called "chain". It returns an iterator which you'd then need to use the list() function on to turn it back into a list. If you don't want to use a *, you can use the second "from_iterator" version. It works the same in Python 3. It will fail if the list input is not a list of lists.

```<code>[[1], [2, 3], [3, 4, 5]] #yes
[1, 2, [5, 6]] #no
</code>```

There was at one time a flatten method in the compiler.ast module but this was deprecated in 2.6 and then removed in 3.0. Arbitrary depth recursion, necessary for arbitrarily nested lists does not function well with Python's conservative maximum recursion depth. The reasoning for compiler's removal were largely due to it being a mess. Compiler was turned into ast but flatten was left behind.

Arbitrary depth can be achieved with numpy's arrays and that library's flatten.

Body:
It does come with such a method but it doesn't call it flatten. It's called "chain". It returns an iterator which you'd then need to use the list() function on to turn it back into a list. If you don't want to use a *, you can use the second "from_iterator" version. It works the same in Python 3. It will fail if the list input is not a list of lists.

[[1], [2, 3], [3, 4, 5]] #yes
[1, 2, [5, 6]] #no

There was at one time a flatten method in the compiler.ast module but this was deprecated in 2.6 and then removed in 3.0. Arbitrary depth recursion, necessary for arbitrarily nested lists does not function well with Python's conservative maximum recursion depth. The reasoning for compiler's removal were largely due to it being a mess. Compiler was turned into ast but flatten was left behind.

Arbitrary depth can be achieved with numpy's arrays and that library's flatten.


答: From my point of view using do...while to create infinite loops leads to code difficult to maintain. When you encounter a do you have to scroll all the way to see if it is a infinite loop or not. On the other hand using for(;;) or while(1) at the beginning of the loop is a lot more clear. As it was already mentioned you can still create infinite loops with the current design of the language so you don't need to change it. Since there is no actual need for a design change in the language none is actually changing it.</p>


问:
Should I try to write simple key-value storage by myself?
I need a key-value storage in a simplest form we can think of.

Keys should be some fixed-length strings, values should be some texts.

This key-value storage should have an HTTP-backed API.

That's basically it. As you can see, there is no big difference between such storage and some web application with some upload functionality.

The thing is - it'll take few hours (including tests and coffee drinking) to write something like this.
"Something like this" will be fully under my control and can be tuned on demand.

Should I, in this specific case, not try to reinvent bicycles? Is it better to use some of existing NoSQL solutions. If yes, which one exactly?

If, say, I'd needed something SQL-like, I won't ask and won't try to write something by myself. But with NoSQL I just don't know what is adequate and what is not.

答:
On Linux and Posix systems I would recommend using the dbm API or the GNU gdbm library (implementing a superset of dbm)

That key-value storage API is pretty common and exists since the previous century. It is in POSIX (using <ndbm.h>). The implementations are quite good and able to deal with both small and huge data.


问:
Isolated Unit Tests and Fine Grained Failures
One of the reasons often given to write unit tests which mock out all dependencies and are thus completely isolated is to ensure that when a bug exists, only the unit tests for that bug will fail. (Obviously, an integration tests may fail as well). That way you can readily determine where the bug is.

But I don't understand why this is a useful property. If my code were undergoing spontaneous failures, I could see why its useful to readily identify the failure point. But if I have a failing test its either because I just wrote the test or because I just modified the code under test. In either case, I already know which unit contains a bug.

What is the useful in ensuring that a test only fails due to bugs in the unit under test? I don't see how it gives me any more precision in identifying the bug than I already had.

答:
Who gives that reason? I consider it to be a weak reason, in fact almost useless. The point of having unit tests is to ensure that no detectable defects are in the code under test. When the test suite fails, you know that there is at least one defect, so you can't publish your code base - it doesn't matter whether exactly one test case fails or more.

Clearly it would be nice to be able to read off from the title of the single failing test exactly what the problem is, but that never happens in practice. It takes an inordinate effort to arrange matters so that every test really does exercise only exactly one bit of code, and no other test does the same, and that effort is almost never worthwhile. It is much more important that every code path is exercised at least once than exactly once. And if a change breaks more than one test case at a time, well usually you investigate one of them and fix the problem, at which point the other failures disappear as well - it's rather like compiler diagnostics in that respect: only the first failure is meaningful, the others may be spurious.


问:
How to fix legacy code that uses <string.h> unsafely?
We've got a bunch of legacy code, written in straight C (some of which is K&R!), which for many, many years has been compiled using Visual C 6.0 (circa 1998) on an XP machine. We realize this is unsustainable, and we're trying to move it to a modern compiler. Political issues have said that the most recent compiler allowed is VC++ 2005.

When compiling the project, there are many warnings about the unsafe string manipulation functions used (sprintf(), strcpy(), etc). Reviewing some of these places shows that the code is indeed unsafe; it does not check for buffer overflows. The compiler warning recommends that we move to using sprintf_s(), strcpy_s(), etc. However, these are Microsoft-created (and proprietary) functions and aren't available on (say) gcc (although we're primarily a Windows shop we do have some clients on various flavors of *NIX)

How ought we to proceed? I don't want to roll our own string libraries. I only want to go over the code once. I'd rather not switch to C++ if we can help it.

答:
First note that those "safe" functions are only marginally safer than the functions they replace. Most of those "safe" functions take an extra parameter informing it of the size of the destination buffer (which they use to check for overflows) and they check that no null pointers are passed where they shouldn't.
This can catch certain errors, but not all of them and you could make an error in passing the wrong buffer size.

If you don't want to switch to the secure functions, or you can't due to portability requirements, then I would advise the following path:

Compile your code with Visual Studio with the deprecation warnings enabled

For each string manipulation function that gets flagged, evaluate if there really is a possibility of a buffer overflow or null pointer being passed.

Where potential problems lie, modify the surrounding code to ensure the error can't occur.

When you are sure that all string handling functions are used in a secure way as much as possible, you add to your Visual Studio a define _CRT_SECURE_NO_WARNINGS to suppress the deprecation warnings.

As the code has been used successfully for a large number of years, I suspect that there are few places with problematic uses of the string functions.


答:
I think you're actually bikeshedding here. Whatever it is that you are doing, in all likelihood this question is way beside the point.

As you've said yourself, the storage will have an HTTP based API. Define that first.

Use the most simple implementation you could (e.g. on top of redis). If this takes longer than an hour, you're doing it wrong.

Write the actual application that consumes the data through said API.

Add reasonably realistic example data.

Measure performance under load. If the performance is satisfactory, you are done.

Use the information you've collected to make a better implementation of the API.

Go to 5.

As for "Isn't XYZ overkill?": Probably not.

Unless you actually have hard evidence to prove that it significantly impacts performance, why bother? It has more features than you need? You don't need to use them. Certainly, you are using a programming language with more features than you actually put to use.

That's not "overkill". It's "maintaining an option" ;)

Lastly, regarding your statement on making this work in just a few hours. There's two options really:

Either it is reasonable to assume that the storage may become a bottle neck, in which case you are far better off using a well maintained, optimized, scalable and reliable solution, because it will take you weeks to provide one and there is no telling how much data loss or data corruption you will cause in the mean time.

Or, if the storage is not a bottle neck, why not just use something that gets the job done? Where is the value of having the full control that you are after?

If you can't measure the benefits of dismissing all readily available 3rd party solutions in favor of a home made one, you're probably suffering from Not Invented Here.

Title: Should I try to write simple key-value storage by myself?

Body:
I need a key-value storage in a simplest form we can think of.

Keys should be some fixed-length strings, values should be some texts.

This key-value storage should have an HTTP-backed API.

That's basically it. As you can see, there is no big difference between such storage and some web application with some upload functionality.

The thing is - it'll take few hours (including tests and coffee drinking) to write something like this.
"Something like this" will be fully under my control and can be tuned on demand.

Should I, in this specific case, not try to reinvent bicycles? Is it better to use some of existing NoSQL solutions. If yes, which one exactly?

If, say, I'd needed something SQL-like, I won't ask and won't try to write something by myself. But with NoSQL I just don't know what is adequate and what is not.


问:
Is Rails 3 ready for use in production?
I'm looking to get a snapshot of Rails 3 at this point in time. We're about to start a new long term project, and I'm wondering if R3 is ready for real use. Or, if there are still a lot of bumps to be worked out. E.g. I saw questions about its compatibility with Passenger. (?)

Thanks!

答: Yes Rails 3 is ready for production. Many sites are already using it in production. The compatibility issue is because Rails 3 is using Rack, Passenger will treat Rails 3 apps as Rack apps when it sees config.ru in the application root directory. </p>

Title: Is Rails 3 ready for use in production?


问:
Expected time for lazy evaluation with nested functions?
A colleague and I are doing a free R course, although I believe this is a more general lazy evaluation issue, and have found a scenario that we have discussed briefly and I'd like to find out the answer from a wider community.

The scenario is as follows (pseudo code):

```<code>wrapper => function(thing)
{
    print => function()
    {
        write(thing)
    }
}

v = createThing(1, 2, 3)
w = wrapper(v)
v = createThing(4, 5, 6)
w.print()
// Will print 4, 5, 6 thing.
v = create(7, 8, 9)
w.print()
</code>```

// Will print 4, 5, 6 because "thing" has now been evaluated.

Another similar situation is as follows:

```<code>// Using the same function as above
v = createThing(1, 2, 3)
v = wrapper(v)
w.print()
// The wrapper function incestuously includes itself.
</code>```

Now I understand why this happens but where my colleague and I differ is on what should happen.

My colleague's view is that this is a bug and the evaluation of the passed in argument should be forced at the point it is passed in so that the returned "w" function is fixed.

My view is that I would prefer his option myself, but that I realise that the situation we are encountering is down to lazy evaluation and this is just how it works and is more a quirk than a bug. I am not actually sure of what would be expected, hence the reason I am asking this question. I think that function comments could express what will happen, or leave it to be very lazy, and if the coder using the function wants the argument evaluated then they can force it before passing it in.

So, when working with lazy evaulation, what is the practice for the time to evaluate an argument passed, and stored, inside a function?

答:
While I'm not familiar with R, based on the manual it seems to be due to the imperative nature of R combined the way it implements laziness.  See 4.3.3 Argument evaluation and 4.3.4 Scope.

Let's look at the example you have:

```<code>wrapper =
  function(thing)
    function()
      print(thing)
</code>```

First of all, notice that you can call

```<code>w = wrapper(v) // line A
</code>```

without even defining v first.  What happens is that the function wrapper captures a promise, which consists of 3 things:

a value (possibly absent),

an expression, and

a pointer to the environment.

Until something forces the evaluation of the promise, the promise remains unevaluated and thus its value is absent.  Once the promise is forced, the value is filled in by the result of the evaluation and it will never be evaluated again.  In other words, promises are evaluated at most once.  (There is some complication if the evaluation fails, however.)

The key property is that a promise contains a pointer to the environment, not a copy of it!  This means if the lexical environment changes later on, then the future value of the promise could also change!

Hence, if you enter the following after line A:

```<code>v = 10
w()
</code>```

You will see that it will print the value 10.

I would agree that this is highly non-intuitive, but I don't believe it's a bug either.  Even though I regularly work with Haskell (another lazy language), the language is designed in such a way that such things can't happen (partly due to the lack of impurity).

I think this is largely an artifact of the fact that promises hold pointers to their lexical environments, rather than a copy of it.  This means that in R arguments are not truly "pass-by-value", nor are they "pass-by-reference", nor are they "pass-by-name"!

Body:
While I'm not familiar with R, based on the manual it seems to be due to the imperative nature of R combined the way it implements laziness.  See 4.3.3 Argument evaluation and 4.3.4 Scope.

Let's look at the example you have:

wrapper =
  function(thing)
    function()
      print(thing)

First of all, notice that you can call

w = wrapper(v) // line A

without even defining v first.  What happens is that the function wrapper captures a promise, which consists of 3 things:

a value (possibly absent),

an expression, and

a pointer to the environment.

Until something forces the evaluation of the promise, the promise remains unevaluated and thus its value is absent.  Once the promise is forced, the value is filled in by the result of the evaluation and it will never be evaluated again.  In other words, promises are evaluated at most once.  (There is some complication if the evaluation fails, however.)

The key property is that a promise contains a pointer to the environment, not a copy of it!  This means if the lexical environment changes later on, then the future value of the promise could also change!

Hence, if you enter the following after line A:

v = 10
w()

You will see that it will print the value 10.

I would agree that this is highly non-intuitive, but I don't believe it's a bug either.  Even though I regularly work with Haskell (another lazy language), the language is designed in such a way that such things can't happen (partly due to the lack of impurity).

I think this is largely an artifact of the fact that promises hold pointers to their lexical environments, rather than a copy of it.  This means that in R arguments are not truly "pass-by-value", nor are they "pass-by-reference", nor are they "pass-by-name"!


问:
What should every programmer know about programming?
Please, stay on technical issues, avoid behavior, cultural, career or political issues.

答: That the #1 thing you can do to increase the quality and maintainability of your code is REDUCE DUPLICATION. </p>


问:
How to avoid being forked into oblivion by a more powerful contributor?
As recently reported here:

Xamarin has forked Cocos2D-XNA, a 2D/3D game development framework,
  creating a cross-platform library that can be included in PCL
  projects.

However the founder of the project that was forked says:

The purpose of the MIT license is to unencumber your fair use. Not to
  encourage you to take software, rebrand it as your own, and then "take
  it in a new direction" as you say.

While not illegal, it is unethical.

It seems that the GitHub page of the new project doesn't even indicate that it's a fork in a typical GitHub manner, opting for an easily-removable History section instead (see bottom).

So my questions are:

Was Xamarin's action and the way the action was done ethical or not?

Is it possible to avoid such a situation if you are a single
developer or a small unfunded group of developers?

I am hoping this could be either a wiki question or there will be some objective answers grounded on modern OSS ethics/philosophy.

答:
An expansion of the trademark topic:

At the Apache Software Foundation, all the code is AL. And, as with the BSD license under discussion here, it's perfectly clear that the AL permits forks. Period. End of discussion. In fact, as discussed in other answers, all  true open source licenses permit forks. All they control is the license / usage of the forked code.

The Apache foundation has chosen to register and defend trademarks. If some entity other than a foundation project forks, oh, 'Apache Tomcat', they are fine ... but they cannot call it Apache Tomcat, and, when we can defend the mark, they cannot call it Tomcat.

The problem here is that trademarks are not for the faint of heart. If you are a small group of people, with no legal structure and no funding, you cannot, practically, use trademark law to protect your name.

In the end, this sort of thing is one of the reasons for the various foundations out there.

From an ethical standpoint, well, if there's an internal fission between contributors, who is to say who 'deserves' to keep the name? If, on the other hand, an outsider forks, it's probably not the most ethical thing in the world to leave the name unchanged. It's not a heinous act, either.

Github is full of forks. Sometimes people do change the name, or the Java package, or whatever -- particularly if they want to publish to Maven central. Often they don't, and users are left navigating a maze of confusion. It's not ideal, but that's the breaks with anarchy.


问:
What is referential transparency?
I have seen that in imperative paradigms

f(x)+f(x)

might not be the same as:

2*f(x)

But in a functional paradigm it should be the same. I have tried to implement both cases in Python and Scheme, but for me they look pretty straightforward the same.

What would be an example that could point out the difference with the given function?

答:
Referential transparency, referred to a function, indicates that you can determine the result of applying that function only by looking at the values of its arguments. You can write referentially transparent functions in any programming language, e.g. Python, Scheme, Pascal, C.

On the other hand, in most languages you can also write non referentially transparent functions. For example, this Python function:

```<code>counter = 0

def foo(x):
  global counter

  counter += 1
  return x + counter
</code>```

is not referentially transparent, in fact calling

```<code>foo(x) + foo(x)
</code>```

and

```<code>2 * foo(x)
</code>```

will produce different values, for any argument x. The reason for this is that the function uses and modifies a global variable, therefore the result of each invocation depends on this changing state, and not only on the function's argument.

Haskell, a purely functional language, strictly separates expression evaluation in which pure functions are applied and which is always referentially transparent, from action execution (processing of special values), which is not referentially transparent, i.e. executing the same action can have each time a different result.

So, for any Haskell function

```<code>f :: Int -> Int
</code>```

and any integer x, it is always true that

```<code>2 * (f x) == (f x) + (f x)
</code>```

An example of an action is the result of the library function getLine:

```<code>getLine :: IO String
</code>```

As a result of expression evaluation, this function (actually a constant) first of all produces a pure value of type IO String. Values of this type are values like any other: you can pass them around, put them in data structures, compose them using special functions, and so on. For example you can make a list of actions like so:

```<code>[getLine, getLine] :: [IO String]
</code>```

Actions are special in that you can tell the Haskell runtime to execute them by writing:

```<code>main = <some action>
</code>```

In this case, when your Haskell program is started, the runtime walks through the action bound to main and executes it, possibly producing side-effects. Therefore, action execution is not referentially transparent because executing the same action two times can produce different results depending on what the runtime gets as input.

Thanks to Haskell's type system, an action can never be used in a context
where another type is expected, and vice versa. So, if you want to find the length of a string you can use the length function:

```<code>length "Hello"
</code>```

will return 5. But if you want to find the length of a string read from the terminal, you cannot write

```<code>length (getLine)
</code>```

because you get a type error: length expects an input of type list (and a String is, indeed, a list) but getLine is a value of type IO String (an action). In this way, the type system ensures that an action value like getLine (whose execution is carried out outside the core language and which may be non-referentially transparent) cannot be hidden inside a non-action value of type Int.

EDIT

To answer exizt question, here is a small Haskell program that reads a line from the console and prints its length.

```<code>main :: IO () -- The main program is an action of type IO ()
main = do
          line <- getLine
          putStrLn (show (length line))
</code>```

The main action consists of two subactions that are executed sequentially:

getline of type IO String,

the second is constructed by evaluating the function putStrLn of type String -> IO () on its argument.

More precisely, the second action is built by

binding line to the value read by the first action,

evaluating the pure functions length (compute length as an integer) and then show (turn the integer into a string),

building the action by applying function putStrLn to the result of show.

At this point, the second action can be executed. If you have typed "Hello", it will print "5".

Note that if you get a value out of an action using the <- notation, you can only use that value inside another action, e.g. you cannot write:

```<code>main = do
          line <- getLine
          show (length line) -- Error:
                             -- Expected type: IO ()
                             --   Actual type: String
</code>```

because show (length line) has type String whereas the do notation requires that an action (getLine of type IO String) be followed by another action (e.g. putStrLn (show (length line)) of type IO ()).

EDIT 2

Jörg W Mittag's definition of referential transparency is more general than mine (I have upvoted his answer). I have used a restricted definition because the example in the question focuses on the return value of functions and I wanted to illustrate this aspect. However, RT in general refers to the meaning of the whole program, including changes to global state and interactions with the environment (IO) caused by evaluating an expression. So, for a correct, general definition, you should refer to that answer.

Title: What is referential transparency?

Body:
Referential transparency, referred to a function, indicates that you can determine the result of applying that function only by looking at the values of its arguments. You can write referentially transparent functions in any programming language, e.g. Python, Scheme, Pascal, C.

On the other hand, in most languages you can also write non referentially transparent functions. For example, this Python function:

counter = 0

def foo(x):
  global counter

  counter += 1
  return x + counter

is not referentially transparent, in fact calling

foo(x) + foo(x)

and

2 * foo(x)

will produce different values, for any argument x. The reason for this is that the function uses and modifies a global variable, therefore the result of each invocation depends on this changing state, and not only on the function's argument.

Haskell, a purely functional language, strictly separates expression evaluation in which pure functions are applied and which is always referentially transparent, from action execution (processing of special values), which is not referentially transparent, i.e. executing the same action can have each time a different result.

So, for any Haskell function

f :: Int -> Int

and any integer x, it is always true that

2 * (f x) == (f x) + (f x)

An example of an action is the result of the library function getLine:

getLine :: IO String

As a result of expression evaluation, this function (actually a constant) first of all produces a pure value of type IO String. Values of this type are values like any other: you can pass them around, put them in data structures, compose them using special functions, and so on. For example you can make a list of actions like so:

[getLine, getLine] :: [IO String]

Actions are special in that you can tell the Haskell runtime to execute them by writing:

main = <some action>

In this case, when your Haskell program is started, the runtime walks through the action bound to main and executes it, possibly producing side-effects. Therefore, action execution is not referentially transparent because executing the same action two times can produce different results depending on what the runtime gets as input.

Thanks to Haskell's type system, an action can never be used in a context
where another type is expected, and vice versa. So, if you want to find the length of a string you can use the length function:

length "Hello"

will return 5. But if you want to find the length of a string read from the terminal, you cannot write

length (getLine)

because you get a type error: length expects an input of type list (and a String is, indeed, a list) but getLine is a value of type IO String (an action). In this way, the type system ensures that an action value like getLine (whose execution is carried out outside the core language and which may be non-referentially transparent) cannot be hidden inside a non-action value of type Int.

EDIT

To answer exizt question, here is a small Haskell program that reads a line from the console and prints its length.

main :: IO () -- The main program is an action of type IO ()
main = do
          line <- getLine
          putStrLn (show (length line))

The main action consists of two subactions that are executed sequentially:

getline of type IO String,

the second is constructed by evaluating the function putStrLn of type String -> IO () on its argument.

More precisely, the second action is built by

binding line to the value read by the first action,

evaluating the pure functions length (compute length as an integer) and then show (turn the integer into a string),

building the action by applying function putStrLn to the result of show.

At this point, the second action can be executed. If you have typed "Hello", it will print "5".

Note that if you get a value out of an action using the <- notation, you can only use that value inside another action, e.g. you cannot write:

main = do
          line <- getLine
          show (length line) -- Error:
                             -- Expected type: IO ()
                             --   Actual type: String

because show (length line) has type String whereas the do notation requires that an action (getLine of type IO String) be followed by another action (e.g. putStrLn (show (length line)) of type IO ()).

EDIT 2

Jörg W Mittag's definition of referential transparency is more general than mine (I have upvoted his answer). I have used a restricted definition because the example in the question focuses on the return value of functions and I wanted to illustrate this aspect. However, RT in general refers to the meaning of the whole program, including changes to global state and interactions with the environment (IO) caused by evaluating an expression. So, for a correct, general definition, you should refer to that answer.


答:
def f(x): return x()

from random import random
f(random) + f(random) == 2*f(random)
# => False
```

<p>However, that's <em>not</em> what Referential Transparency means. RT means that you can replace <em>any</em> expression in the program with the result of evaluating that expression (or vice versa) without changing the meaning of the program.</p>

<p>Take, for example, the following program:</p>

<pre class="lang-py prettyprint-override"><code>def f(): return 2

print(f() + f())
print(2)
</code>```

This program is referentially transparent. I can replace one or both occurences of f() with 2 and it will still work the same:

def f(): return 2

print(2 + f())
print(2)
```

<p>or</p>

<pre class="lang-py prettyprint-override"><code>def f(): return 2

print(f() + 2)
print(2)
</code>```

or

def f(): return 2

print(2 + 2)
print(f())
```

will all behave the same.

Well, actually, I cheated. I should be able to replace the call to print with its return value (which is no value at all) without changing the meaning of the program. However, clearly, if I just remove the two print statements, the meaning of the program will change: before, it printed something to the screen, after it doesn't. I/O isn't referentially transparent.

The simple rule of thumb is: if you can replace any expression, sub-expression or subroutine call with the return value of that expression, sub-expression or subroutine call anywhere in the program, without the program changing its meaning, then you have referential transparency. And what this means, practically speaking is that you can't have any I/O, can't have any mutable state, can't have any side-effects. In every expression, the value of the expression must depend solely on the values of the constituent parts of the expression. And in every subroutine call, the return value must depend solely on the arguments.

Title: What is referential transparency?

Body:
I have seen that in imperative paradigms

f(x)+f(x)

might not be the same as:

2*f(x)

But in a functional paradigm it should be the same. I have tried to implement both cases in Python and Scheme, but for me they look pretty straightforward the same.

What would be an example that could point out the difference with the given function?

Body:
def f(x): return x()

from random import random
f(random) + f(random) == 2*f(random)
# => False

However, that's not what Referential Transparency means. RT means that you can replace any expression in the program with the result of evaluating that expression (or vice versa) without changing the meaning of the program.

Take, for example, the following program:

def f(): return 2

print(f() + f())
print(2)

This program is referentially transparent. I can replace one or both occurences of f() with 2 and it will still work the same:

def f(): return 2

print(2 + f())
print(2)

or

def f(): return 2

print(f() + 2)
print(2)

or

def f(): return 2

print(2 + 2)
print(f())

will all behave the same.

Well, actually, I cheated. I should be able to replace the call to print with its return value (which is no value at all) without changing the meaning of the program. However, clearly, if I just remove the two print statements, the meaning of the program will change: before, it printed something to the screen, after it doesn't. I/O isn't referentially transparent.

The simple rule of thumb is: if you can replace any expression, sub-expression or subroutine call with the return value of that expression, sub-expression or subroutine call anywhere in the program, without the program changing its meaning, then you have referential transparency. And what this means, practically speaking is that you can't have any I/O, can't have any mutable state, can't have any side-effects. In every expression, the value of the expression must depend solely on the values of the constituent parts of the expression. And in every subroutine call, the return value must depend solely on the arguments.


问:
Why is cleverness considered harmful in programming by some people?
I've noticed a lot of questions lately relating to different abstraction techniques, and answers saying basically that the techniques in question are "too clever." I would think that part of our jobs as programmers is to determine the best solutions to the problems we are given to solve, and cleverness is helpful in doing that.

So my question is: are the people who think certain abstraction techniques are too clever opposed to cleverness per se, or is there some other reason for the objection?

EDIT: This parser combinator is an example of what I would consider to be clever code. I downloaded this and looked it over for about half an hour. Then I stepped through the macro expansion on paper and saw the light. Now that I understand it, it seems much more elegant than the Haskell parser combinator.

答:
"Clever", when applied to code, is almost always just a euphemism for "needlessly complicated".

Reading good, clear, simple code is hard enough. Reading "clever" code is like studying latin poetry all over again.

The confusion arises because "clever" as an attribute of a person has a completely different meaning. This case can also be seen as an example of why designing software for real people is hard: Because they are ambiguous.

And because some programmers suffer to understand the social protocols most people follow, which forbid them to directly denounce code as "needlessly complicated", they may find it hard to differentiate between the two meanings of the word clever. Contrary to what some may think, I think ultimately better "people persons" (meaning: people who have empathy and introspection and patience) make better developers. Because they know who to write for.


问:
Evolutions in Agile development field
I recently pull up from under ten inches of dust one of my agile book. The book is now six years old; published in 2008. I prefer to keep it anonymous preventing to create a guerrilla of which one will yielded the best book about this subject. For that, I'm totally able to do a simple search from Amazon or Gooble to find the best book.

I seen a couple of books about agile released in the last 2-3 years and I'm wondering if it will be a good investment to buy a more recent book than my old one.

I mean, is there any great advancements in the last few years in the world of agile that worth to buy a more recent book?

Thank you.

答:
I would actually advise you to look for even OLDER books. Look for the original books from Ken Schwaber, Kent Beck, Alistar Cockburn and so on. Look for the OLD and ORIGINAL stuff. The reason I say this is because Agile has become a marketing buzzword in our industry, and most companies are simply applying bastardized versions of the processes listed within Scrum/Lean/Whatever as management practices, just to say that they are Agile, with no regards to the actual change in culture and values that are necessary for both the customers and the team to enjoy the process.

This is my opinion of course. But you can see in the following links that I'm not alone in this thought:

Half-Arsed Agile Manifesto: http://www.halfarsedagilemanifesto.org/

Prag Dave - Agile Is Dead: http://pragdave.me/blog/2014/03/04/time-to-kill-agile/

Robert C. Martin - The Land that Scrum Forgot - Article: https://www.scrumalliance.org/community/articles/2010/december/the-land-that-scrum-forgot

Robert C. Martin - The Land that Scrum Forgot - Video: https://www.youtube.com/watch?v=hG4LH6P8Syk

Martin Fowler - Flaccid Scrum:
http://martinfowler.com/bliki/FlaccidScrum.html
http://martinfowler.com/snips/201401291515.html

Title: Evolutions in Agile development field


问:
Solving a probabilistic problem
So I am interested in Computational Investing and came across this problem on a wiki page:

Write a program to discover the answer to this puzzle:"Let's say men
  and women are paid equally (from the same uniform distribution). If
  women date randomly and marry the first man with a higher salary, what
  fraction of the population will get married?"

I don't have much knowledge in probability theory, so I'm not really sure how to implement this in code.

My thinking:

Populate two arrays(female,male) with random salary values from a uniform
distribution.

Randomly pair one female and one male array element and see if
    condition of higher salary is met.

If it is, increment a counter.

Divide counter by population and get percentage.

Is this the correct logic? Do woman continually date until there is no males left with higher salaries than women?

答:
My thinking:

Populate two arrays(female,male) with random salary values from a uniform
  distribution.

Randomly pair one female and one male array element and see if
      condition of higher salary is met.

If it is, increment a counter.

Divide counter by population and get percentage.

Is this the correct logic? Do woman continually date until there is no males left with higher salaries than women?

There are a number of things wrong with the above.

Your algorithm has men and women continuing to date after they've been married. It's better to ignore the infidelity problem. You should remove a couple from the pool once they are married.

You're only doing steps #2 and #3 once. The randomly chosen pair either will satisfy the condition or they won't, which means your answer will be either 100% or 0%, and never anything in between.

You need some kind of loop and some kind of stopping condition for that loop.

First things first: This is a very politically incorrect question. It degrades women by implying that they only marry for money. However, it degrades men even more! Per this question, a male's threshold is "does she have a pulse?"

There are ways to rephrase this question that avoid the political incorrectness issue. For example, let sets X and Y be sets of the same cardinality. Each set comprises members with two attributes, value, which is drawn from U(0,1), and paired, which is initially false. By some scheme, we'll pair members of set X and set Y such that for each pair (x,y), we have x.paired == y.paired == false prior to the pairing and x.value > y.value'. After pairingxandy, thepairedattributes of membersxandyare set totrue`.

The fraction of the population that can be paired depends very much on the algorithm used to match elements of sets X and Y. This is not a well-phrased question.

Serial-serial matching

Assign random values to the value attribute of each member of set X and pf set Y. Walk over members yy of set Y. For each such member y, walk over members x of set X until a member is found  that satisfies !x.paired && (x.value > y.value). This member x is then paired with member y.

The percentage of the population that is paired by this algorithm is about 97%.

Serial-random matching

Assign random values to the value attribute of each member of set X and pf set Y. For each pairable member of set Y (a member y of set Y whose value is greater than the maximum value of all unpaired members of set X is not "parable"), repeatedly randomly select a member of x of the unpaired members of set X until x.value > y.value. This member x is then paired with member y.

The percentage of the population that is paired by this algorithm is about 68%.

Random-serial matching

This is in a sense the inverse of the above algorithm. Here we repeatedly select a random member y from the unpaired members of set Y.  Then we walk over the elements of set X, in order, until a match is found. Walking over the end says that y is a old maid is unpairable. The algorithm stops when the minimum value of set Y is greater than the maximum value of set X.

The percentage of the population that is paired by this algorithm is about 68%, the same as above.

Random-random matching

Randomly select a member y from the unpaired members of set Y and randomly select a member x from the unpaired members of set X. Pair these two members if x.value > y.value. Keep doing this until there are no pairable members left in the set.

The percentage of the population that is paired by this algorithm is about 68%, the same as above.

 Speed dating Speed matching

Basically, this is the above algorithm but in parallel. Here we randomly pair members from the unpaired members of set Y with unpaired members of set X. All of these that meet the criterion x.value > y.value are paired, en masse.

The percentage of the population that is paired by this algorithm is about 68%, the same as above. The performance of this algorithm is anything but that of the above. This algorithm is blazingly fast.

match.com matching Optimal matching

Here we try to match members of set X and set Y that just barely pass the criteria. Doing this serially barely beats the serial-serial algorithm. Do this in parallel, and almost every member gets paired with another. The only ones that don't get paired are the members of set Y that are completely unpairable.

Title: Solving a probabilistic problem


答:
Parts of this answer are taken directly from an unfinished tutorial on functional programming, hosted on my GitHub account:

A function is said to be referentially transparent if it, given the same input parameters, always produces the same output (return value). If one is looking for a raison d'être for pure functional programming, referential transparency is a good candidate. When reasoning with formulae in algebra, arithmetic, and logic, this property — also called substitutivity of equals for equals — is so fundamentally important that it is usually taken for granted...

Consider a simple example:

```<code>x = 42
</code>```

In a pure functional language, the left-hand and right-hand side of the equals sign are substitutable for each other both ways. That is, unlike in a language like C, the above notation truly asserts an equality. A consequence of this is that we can reason about program code just like mathematical equations.

From Haskell wiki:

Pure computations yield the same value each time they are invoked. This property is called referential transparency and makes possible to conduct equational reasoning on the code...

To contrast this, the type of operation performed by C-like languages is sometimes referred to as a destructive assignment.

The term pure is often used to describe a property of expressions, relevant to this discussion. For a function to be considered pure,

it is not allowed to exhibit any side effects, and

it must be referentially transparent.

According to the black-box metaphor, found in numerous mathematical textbooks, a function's internals are completely sealed off from the outside world. A side-effect is when a function or expression violates this principle — that is, the procedure is allowed to communicate in some way with other program units (e.g. to share and exchange information).

In summary, referential transparency is a must  for functions to behave like true, mathematical functions also in the semantics of programming languages.

Title: What is referential transparency?

Body:
Parts of this answer are taken directly from an unfinished tutorial on functional programming, hosted on my GitHub account:

A function is said to be referentially transparent if it, given the same input parameters, always produces the same output (return value). If one is looking for a raison d'être for pure functional programming, referential transparency is a good candidate. When reasoning with formulae in algebra, arithmetic, and logic, this property — also called substitutivity of equals for equals — is so fundamentally important that it is usually taken for granted...

Consider a simple example:

x = 42

In a pure functional language, the left-hand and right-hand side of the equals sign are substitutable for each other both ways. That is, unlike in a language like C, the above notation truly asserts an equality. A consequence of this is that we can reason about program code just like mathematical equations.

From Haskell wiki:

Pure computations yield the same value each time they are invoked. This property is called referential transparency and makes possible to conduct equational reasoning on the code...

To contrast this, the type of operation performed by C-like languages is sometimes referred to as a destructive assignment.

The term pure is often used to describe a property of expressions, relevant to this discussion. For a function to be considered pure,

it is not allowed to exhibit any side effects, and

it must be referentially transparent.

According to the black-box metaphor, found in numerous mathematical textbooks, a function's internals are completely sealed off from the outside world. A side-effect is when a function or expression violates this principle — that is, the procedure is allowed to communicate in some way with other program units (e.g. to share and exchange information).

In summary, referential transparency is a must  for functions to behave like true, mathematical functions also in the semantics of programming languages.


问:
What is the difference between Callable<T> and Java 8's Supplier<T>?
I've been switching over to Java from C# after some recommendations from some over at CodeReview. So, when I was looking into LWJGL, one thing I remembered was that every call to Display must be executed on the same thread that the Display.create() method was invoked on. Remembering this, I whipped up a class that looks a bit like this.

```<code>public class LwjglDisplayWindow implements DisplayWindow {
    private final static int TargetFramesPerSecond = 60;
    private final Scheduler _scheduler;

    public LwjglDisplayWindow(Scheduler displayScheduler, DisplayMode displayMode) throws LWJGLException {
        _scheduler = displayScheduler;
        Display.setDisplayMode(displayMode);
        Display.create();
    }

    public void dispose() {
        Display.destroy();
    }

    @Override
    public int getTargetFramesPerSecond() { return TargetFramesPerSecond; }

    @Override
    public Future<Boolean> isClosed() {
        return _scheduler.schedule(() -> Display.isCloseRequested());
    }
}
</code>```

While writing this class you'll notice that I created a method called isClosed() that returns a Future<Boolean>. This dispatches a function to my Scheduler interface (which is nothing more than a wrapper around an ScheduledExecutorService. While writing the schedule method on the Scheduler I noticed that I could either use a Supplier<T> argument or a Callable<T> argument to represent the function that is passed in. ScheduledExecutorService didn't contain an override for Supplier<T> but I noticed that the lambda expression () -> Display.isCloseRequested() is actually type compatible with both Callable<bool> and Supplier<bool>.

My question is, is there a difference between those two, semantically or otherwise - and if so, what is it, so I can adhere to it?

答:
Both are normal Java interfaces with no special semantics. Callable is a part of concurrent API. Supplier is a part of new functional programming API. They can be created from lambda expressions thanks to changes in Java8. @FunctionalInterface makes the compiler check that the interface is functional and raise an error if it isn't, but an interface doesn't need that annotation to be a functional interface and be implemented by lambdas. This is like how a method can be an override without being marked @Override but not vice-versa.

You can define your own interfaces compatible with lambdas and document them with @FunctionalInterface annotation. Documenting is optional though.

```<code>@FunctionalInterface
public interface MyInterface {
    boolean myCall(int arg);
}

...

MyInterface var = (int a) -> a != 0;
</code>```

Body:
Both are normal Java interfaces with no special semantics. Callable is a part of concurrent API. Supplier is a part of new functional programming API. They can be created from lambda expressions thanks to changes in Java8. @FunctionalInterface makes the compiler check that the interface is functional and raise an error if it isn't, but an interface doesn't need that annotation to be a functional interface and be implemented by lambdas. This is like how a method can be an override without being marked @Override but not vice-versa.

You can define your own interfaces compatible with lambdas and document them with @FunctionalInterface annotation. Documenting is optional though.

@FunctionalInterface
public interface MyInterface {
    boolean myCall(int arg);
}

...

MyInterface var = (int a) -> a != 0;


问:
Why do we need to include the .h while everything works when including only the .cpp file?
Why do we need to include both the .h and .cpp files while we can make it work solely by including the .cpp file?

For example: creating a file.h containing declarations, then creating a file.cpp containing definitions and including both in main.cpp.

Alternatively: creating a file.cpp containing declaration/definitions ( no prototypes ) including  it in main.cpp.

Both work for me. I can't see the difference. Maybe some insight into the compiling and linking process may help.

答:
The selected answer from Why do we need to write a header file? is a reasonable explanation, but I wanted to add additional detail.

It seems that the rational for header files tends to get lost in teaching and discussing C/C++.

Headers file provide a solution to two application development problems:

Separation of interface and implementation

Improved compile/link times for large programs

C/C++ can scale from small programs to very large multi-million line, multi-thousand file programs. Application development can scale from teams of one developer to hundreds of developers.

You can wear several hats as a developer. In particular, you can be the user of an interface to functions and classes, or you can be the writer of an interface of functions and classes.

When you are using a function you need to know the function interface, what parameters to use, what the functions returns and you need to know what the function does. This is easily documented in the header file without ever looking at the implementation. When have you read the implementation of printf? Buy we use it every day.

When you are the developer of an interface, the hat changes the other direction. The header file provides the declaration of the public interface. The header file defines what another implementation needs in order to use this interface. Information internal and private to this new interface do not (and should not) be declared in the header file. The public header file should be all anyone needs to use the module.

For large scale development, compiling and linking can take a long time. From many minutes to many hours (even to many days!). Dividing the software into interfaces (headers) and implementations (sources) provides a method for only compiling files that need to be compiled rather than re-building everything.

Additionally, header files allows a developer to provide a library (already compiled) as well as a header file. Other users of the library may not ever see the implementation proper, but can still use the library with the header file. You do this every day with the C/C++ standard library.

Even if you are developing a small application, using large scale software development techniques are a good habit. But we also need to remember why we use these habits.


问:
Overloading methods that do logically different things, does this break any major principles?
This is something that's been bugging me for a bit now. In some cases you see code that is a series of overloads, but when you look at the actual implementation you realize they do logically different things. However writing them as overloads allows the caller to ignore this and get the same end result. But would it be more sound to name the methods more explicitly then to write them as overloads?

```<code>public void LoadWords(string filePath)
{
    var lines = File.ReadAllLines(filePath).ToList();

    LoadWords(lines);
}

public void LoadWords(IEnumerable<string> words)
{
    // loads words into a List<string> based on some filters
}
</code>```

Would these methods better serve future developers to be named as LoadWordsFromFile() and LoadWordsFromEnumerable()? It seems unnecessary to me, but if that is better what programming principle would apply here?

On the flip side it'd make it so you didn't need to read the signatures to see exactly how you can load the words, which as Uncle Bob says would be a double take. But in general is this type of overloading to be avoided then?

答:
I really wonder why the version with actual IO has been added to the class in the first place. What's the point here? How is that the responsibility of the class?

Why not add a method to load the words from a zipped file, or from an .xml or a .json or a .doc or an SQL database or over http or ftp or whatever? Because it's not the responsibility of the class, that's why!

Particularly the file name based method adds a dependency against a global object. Which is anything but ideal if you ask me.

So I would argue that the programming principle that would apply here is composition.

loader.LoadWords(someList)

loader.LoadWords(File.ReadAllLines(somePath).ToList())

loader.LoadWords(Http.get(someUrl).split(NEWLINE))

...

Tying together a particular method of loading the data and a particular method of processing it should not be done in the class itself, but in another module, whose responsibility it is to carry out just that composition. Could be an IoC container or something, but it doesn't have to be as fancy as that.


问:
Ranking players depending on decision making during a game
How would I go about a ranking system for players that play a game? Basically, looking at video games, players throughout the game make critical decisions that ultimately impact the end game result.

Is there a way or how would I go about a way to translate some of those factors (leveling up certain skills, purchasing certain items, etc.) into something like a curve that can be plotted on a graph?

This game that I would like to implement this is League of Legends.

Example: Player is Level 1 in the beginning. Gets a kill very early in the game (he gets gold because of the kill and it increases his "power curve"), and purchases attack damage (gives him more damage which also increases his "power curve". However, the player that he killed (Player 2), buys armor (counters attack damage). This slightly increases Player 2's own power curve, and reduces Player 1's power curve.

There's many factors I would like to take into account. These relative factors (example: BECAUSE Player 2 built armor, and I am mainly attack damage, it lowers my OWN power curve) seem the hardest to implement.

My question is this: Is there a certain way to approach this task? Are there similar theoretical concepts behind ranking systems that I should read up on (Maybe in game theory or data mining)? I've seen the ELO system, but it doesn't seem what I want since it simply takes into account wins and losses.

答: I should think a data mining approach would work, probably with a neural network to map inputs (user actions) to outputs (game win/ loose).  Record many games and use these to train the neural net.  At run time let this trained 'net decide what's important and produce a numeric measure, which you graph.</p>