答:
It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

```<code>class Decoder : IDecoder
{
    // initialize with a completed Task
    Task previous = Task.FromResult(true);

    public Task<DecodeResult> DecodeAsync(parameters)
    {
        var result = DecodeAsyncInternal(parameters);
        previous = result;
        return result;
    }

    private async Task<DecodeResult> DecodeAsyncInternal(parameters)
    {
        await previous;
        return await Task.Run(() => ActualDecode(parameters));
    }
}
</code>```

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.

Title: Converting event-based asynchrony to C#5 async

Body:
We currently have an interface for an asynchronous video decoder that runs on its own thread. Basically you feed it some data and it'll eventually call you back on its thread through some events, like so (not real code):

```<code>interface IDecoder {
    void Decode(parameters);
    event FrameReady;
    event FrameDropped;
    // lots of other possibilities
}
</code>```

It's a bit messy and I'd like to convert it to a C#5, async-based version, something like:

```<code>interface IDecoder {
    async Task<DecodeResult> DecodeAsync(parameters);
}
</code>```

Where DecodeResult will have all the information that would have otherwise been transmitted via events, and the client code can be written cleanly with async/await rather than a mess of event handlers and thread dispatching.

It is my understanding that Tasks are scheduled on the ThreadPool by default. We want all Decode operations to happen sequentially on a single, decoder-specific thread. Can this be achieved using Tasks, if so, how? Are Tasks even appropriate for this use or is there a more obvious pattern I'm missing?

Body:
It is my understanding that Tasks are scheduled on the ThreadPool by default.

Tasks that are created using Task.Run() (or Task.Factory.StartNew(), in the common case) are. But this does not apply to Tasks that don't execute any code themselves, like the ones that automatically created from async methods, or the ones that are created using TaskCompletionSource.

So, what you want is certainly possible. How exactly to do it depends on what should DecodeAsync() do.

EDIT: Probably the simplest way to convert your current code to Tasks would be using TaskCompletionSource. Simply call TaskCompletionSource.SetResult() instead of invoking an event.

But another option might be something like this:

class Decoder : IDecoder
{
    // initialize with a completed Task
    Task previous = Task.FromResult(true);

    public Task<DecodeResult> DecodeAsync(parameters)
    {
        var result = DecodeAsyncInternal(parameters);
        previous = result;
        return result;
    }

    private async Task<DecodeResult> DecodeAsyncInternal(parameters)
    {
        await previous;
        return await Task.Run(() => ActualDecode(parameters));
    }
}

This won't guarantee that all decoding is done on the same thread, but it does guarantee that the jobs will be executed one after the other.

Also, this code is not thread-safe: it won't work correctly if call DecodeAsync() at the same time from multiple threads. If you need that, use a lock.


问:
What is the most productive way to handle development-related failures?
We've all been there:

Your project failed or got cancelled.

The code you spent days working on got rejected by your team.

The design pattern you introduced to the team created chaos.

Everyone ignores your ideas.

My question is, what is the most productive way for a programmer to handle development-related failures such as these?

答:
Well, you asked :) One by one:

```<code>* Your project failed.
</code>```

That is hardly new. We've all failed privately, and we've all failed in full view of our peers. Anyone who has gone through primary and secondary education has experienced this.

If I can't make mistakes and expect stable employment, you should consider sending a memo to HR letting them know that human beings will be banned from future consideration.

Several failures in a row means you either have unreasonable demands and specifications, or you don't learn from your mistakes. Either scenario begs immediate action.

It is conceivable that many people sign onto something just to gain employment, then work out some way of making the requirements happen.

```<code>* What you have spent days coding was rejected by your team.
</code>```

That happens. As others noted, save it. Do it again. This is why we call it work. I think, in this case, you probably did not involve the team very much in what you were doing.

It could also be that requirements changed yesterday, or an hour ago. This should be an exception, not a norm, however. Peer review is as brutal as it is helpful. If your code is constantly dismissed as 'inadequate' (or something like that), you should spend more time picking brains and involving others. I believe this question to be a fallacy in most team settings, unless the 'team' is anything but self describing.

```<code>* Nobody listens to your ideas in your company.
</code>```

Again, this needs context. How long have you been there? How much do your fellow hackers trust in your ability? Have you considered that ideas that result in more work for many people might invite ANY reason to dismiss it? I once had something dismissed because it was not IPV6 ready, yet it used a simple domain socket on the loopback device (exclusively). The person who sunk it simply couldn't take any more work to do.

Also, how well do you articulate yourself? Can you make friends and influence people?

```<code>* The design pattern you introduced with force in your team created a mess.
</code>```

Hence why force should have been avoided. Being able to talk is not a prerequisite for being able to listen. No other comments.

ContentLicense: CC BY-SA 3.0

Body:
Well, you asked :) One by one:

* Your project failed.

That is hardly new. We've all failed privately, and we've all failed in full view of our peers. Anyone who has gone through primary and secondary education has experienced this.

If I can't make mistakes and expect stable employment, you should consider sending a memo to HR letting them know that human beings will be banned from future consideration.

Several failures in a row means you either have unreasonable demands and specifications, or you don't learn from your mistakes. Either scenario begs immediate action.

It is conceivable that many people sign onto something just to gain employment, then work out some way of making the requirements happen.

* What you have spent days coding was rejected by your team.

That happens. As others noted, save it. Do it again. This is why we call it work. I think, in this case, you probably did not involve the team very much in what you were doing.

It could also be that requirements changed yesterday, or an hour ago. This should be an exception, not a norm, however. Peer review is as brutal as it is helpful. If your code is constantly dismissed as 'inadequate' (or something like that), you should spend more time picking brains and involving others. I believe this question to be a fallacy in most team settings, unless the 'team' is anything but self describing.

* Nobody listens to your ideas in your company.

Again, this needs context. How long have you been there? How much do your fellow hackers trust in your ability? Have you considered that ideas that result in more work for many people might invite ANY reason to dismiss it? I once had something dismissed because it was not IPV6 ready, yet it used a simple domain socket on the loopback device (exclusively). The person who sunk it simply couldn't take any more work to do.

Also, how well do you articulate yourself? Can you make friends and influence people?

* The design pattern you introduced with force in your team created a mess.

Hence why force should have been avoided. Being able to talk is not a prerequisite for being able to listen. No other comments.


问:
Is Java Bytecode interpreted?
The definition of interpretation (correct me if I'm wrong) is parsing code like so:

1- Translate currently parsed line to some intermediate language. 2- Run the translated line. 3- Move to the next line. 4- Translate it. 5- Run it. And so on.

If so, why do people say that the JVM interprets the Java Bytecode? What it does is execute it. The Bytecode is already translated Java source code, so there's no need to translate further.

Than why is the term interpretation involved?

If this term is used because the JVM executes the Bytecode line by line, well I'd say that any execution does that. Executes the runnable code from top to bottom. Than why use the term interpretation?

Interpretation as opposed to what?

答:
A processor executes machine instructions. They are the only thing that a processor understands.

Java bytecode is an intermediate, compact, way of representing a series of operations (for want of a better term). The processor can't execute these directly.

The Java Virtual Machine processes that stream of bytecode operations and interprets them into a series of machine instructions for the processor to execute.

This is a very similar process to the one the Python interpreter performs on an input Python script. It doesn't matter that Java Bytecode is a binary format to help speed up execution, and a Python script is a text file. Even Python processes .py modules into a binary .pyc form for the same reason. The more fundamental difference is that Java bytecode has been through a more thorough pre-processing step - resolving method calls on objects, checking types etc., so that the JVM doesn't then have to do them.

This VM process is what allows compiled Java to be portable to any computer, whether it has an X86 processor, ARM or anything else - as long as there is a JVM for that platform. The different versions of the JVM all interpret the same bytecode, but produce the appropriate machine instructions for their processor.

For further detail, and an excellent explanation on the difference between a Virtual Machine  like Java and an interpreter like CPython see the accepted answer here:

https://stackoverflow.com/questions/441824/java-virtual-machine-vs-python-interpreter-parlance

Title: Is Java Bytecode interpreted?


答:
It depends on the implementation.

Java bytecode isn't the same thing as machine code. It's a very similar format to that used by most architectures, which makes it relatively easy to translate to machine code, but I'm not aware of any machines that actually run it natively.

The Java specs don't care how the code gets executed, as long as the results are what the spec says they should be. But if you're not executing it natively, then you have to translate it in some way. You can do this with interpretation, and that's how some early JVMs worked, but this technique has fallen out of favor in more recent years. Nowadays, it's more common to compile it to native code, either ahead-of-time or just-in-time, and then execute that instead of the bytecode.

Title: Is Java Bytecode interpreted?

Body:
The definition of interpretation (correct me if I'm wrong) is parsing code like so:

1- Translate currently parsed line to some intermediate language. 2- Run the translated line. 3- Move to the next line. 4- Translate it. 5- Run it. And so on.

If so, why do people say that the JVM interprets the Java Bytecode? What it does is execute it. The Bytecode is already translated Java source code, so there's no need to translate further.

Than why is the term interpretation involved?

If this term is used because the JVM executes the Bytecode line by line, well I'd say that any execution does that. Executes the runnable code from top to bottom. Than why use the term interpretation?

Interpretation as opposed to what?


答:
Java bytecode is a language. Languages aren't interpreted or compiled. They just are. Interpretation and compilation are traits of, well, the interpreter or compiler (duh!), i.e. an implementation of that language.

There are interpreted implementations of the JVM (e.g. early versions of the Sun JVM before Java 1.2), there are compiled implementations of the JVM (e.g. early versions of Maxine), but the most commonly used implementation, the Sun/Oracle HotSpot JVM is actually both: it first interprets the bytecode, gathering statistics, and then it compiles the performance-critical portions using optimization information derived from those statistics.

Title: Is Java Bytecode interpreted?


问:
User interfaces for C function completion
In method call syntax in many object-oriented languages, the receiver object goes to the left of the method name, e.g. someObject.someMethod(). This comes in handy when using an IDE with code completion/code assist/Intellisense; when the user types a method call expression, the receiver has already been typed, so the IDE can narrow down its method choices to apply to that receiver (at least in statically-typed languages).

What I'm wondering is, what is the user interface for method/function completion like in languages where the method or function name goes before its receiver and/or arguments, e.g. Lisp or C? Does the user have to trigger a hotkey, to which the IDE responds by asking for the receiver and/or arguments, and then once the value is typed in the IDE pops up a list of methods or functions that are applicable to that list?

答:
(Short answer – it depends: there are a gazillion different IDEs and editors which might all handle such cases slightly differently, so there is no single user interface which everyone uses)

The problem is much larger than just languages where the method comes before the invocant. What horror must it be to program in languages that don't even support OOP, or which are dynamically typed so that we have no idea what methods could be called on the object inside some variable!

There are a number of ways out of this conundrum:

Just remember what methods can be called on what type. And if we aren't sure, we can always read the documentation. You would be surprised how well this works.

Dumb text completition can complete words which occur in the same file or project. So if there is a method foobar() somewhere, typing foo could be completed to foobar. Unfortunately, a variable foobaz would be suggested as well.

Any form of more advanced completition. Let's assume we want to call frobnicate on a Foo instance, and the syntax is method(instance, arguments...). Then typing fro might suggest

```<code>frobnicate(Foo foo, int x)
frobnicate(Bar bar, int x, int y)
frodo
</code>```

You can be quite productive without intellisense-like autocompletition, although it's a very nice feature to have.

My primary language happens to be dynamically typed and defies any static analysis (metaprogramming is too nice to give up), so suggesting available methods for some object is absolutely impossible. But the problem is smaller than it seems: Not all my code is object oriented, quite often procedural or functional code is a better fit. I also survive by reading the docs of the libraries I use. The dumb text completition which my editor offers is a general speedup – it's more work than getting only sensible suggestions, but it's still a lot faster than typing out everything. The way I've set up my editor, no shortcut is required to trigger suggestions, only a prefix of some minimal length.

Body:
(Short answer – it depends: there are a gazillion different IDEs and editors which might all handle such cases slightly differently, so there is no single user interface which everyone uses)

The problem is much larger than just languages where the method comes before the invocant. What horror must it be to program in languages that don't even support OOP, or which are dynamically typed so that we have no idea what methods could be called on the object inside some variable!

There are a number of ways out of this conundrum:

Just remember what methods can be called on what type. And if we aren't sure, we can always read the documentation. You would be surprised how well this works.

Dumb text completition can complete words which occur in the same file or project. So if there is a method foobar() somewhere, typing foo could be completed to foobar. Unfortunately, a variable foobaz would be suggested as well.

Any form of more advanced completition. Let's assume we want to call frobnicate on a Foo instance, and the syntax is method(instance, arguments...). Then typing fro might suggest

frobnicate(Foo foo, int x)
frobnicate(Bar bar, int x, int y)
frodo

You can be quite productive without intellisense-like autocompletition, although it's a very nice feature to have.

My primary language happens to be dynamically typed and defies any static analysis (metaprogramming is too nice to give up), so suggesting available methods for some object is absolutely impossible. But the problem is smaller than it seems: Not all my code is object oriented, quite often procedural or functional code is a better fit. I also survive by reading the docs of the libraries I use. The dumb text completition which my editor offers is a general speedup – it's more work than getting only sensible suggestions, but it's still a lot faster than typing out everything. The way I've set up my editor, no shortcut is required to trigger suggestions, only a prefix of some minimal length.


问:
Low level programming - what's in it for me?
For years I have considered digging into what I consider "low level" languages. For me this means C and assembly. However I had no time for this yet, nor has it EVER been neccessary.

Now because I don't see any neccessity arising, I feel like I should either just schedule some point in time when I will study the subject or drop the plan forever.

My Position

For the past 4 years I have focused on "web technologies", which may change, and I am an application developer, which is unlikely to change.

In application development, I think usability is the most important thing. You write applications to be "consumed" by users. The more usable those applications are, the more value you have produced.

In order to achieve good usability, I believe the following things are viable

Good design: Well-thought-out features accessible through a well-thought-out user interface.

Correctness: The best design isn't worth anything, if not implemented correctly.

Flexibility: An application A should constantly evolve, so that its users need not switch to a different application B, that has new features, that A could implement. Applications addressing the same problem should not differ in features but in philosophy.

Performance: Performance contributes to a good user experience. An application is ideally always responsive and performs its tasks reasonably fast (based on their frequency). The value of performance optimization beyond the point where it is noticeable by the user is questionable.

I think low level programming is not going to help me with that, except for performance. But writing a whole app in a low level language for the sake of performance is premature optimization to me.

My Question

What could low level programming teach me, what other languages wouldn't teach me? Am I missing something, or is it just a skill, that is of very little use for application development? Please understand, that I am not questioning the value of C and assembly. It's just that in my everyday life, I am quite happy that all the intricacies of that world are abstracted away and managed for me (mostly by layers written in C/C++ and assembly themselves). I just don't see any concepts, that could be new to me, only details I would have to stuff my head with. So what's in it for me?

My Conclusion

Thanks to everyone for their answers. I must say, nobody really surprised me, but at least now I am quite sure I will drop this area of interest until any need for it arises.

To my understanding, writing assembly these days for processors as they are in use in today's CPUs is not only unneccesarily complicated, but risks to result in poorer runtime performance than a C counterpart. Optimizing by hand is nearly impossible due to OOE, while you do not get all kinds of optimizations a compiler can do automatically. Also, the code is either portable, because it uses a small subset of available commands, or it is optimized, but then it probably works on one architecture only.

Writing C is not nearly as neccessary anymore, as it was in the past. If I were to write an application in C, I would just as much use tested and established libraries and frameworks, that would spare me implementing string copy routines, sorting algorithms and other kind of stuff serving as exercise at university. My own code would execute faster at the cost of type safety. I am neither keen on reeinventing the wheel in the course of normal app development, nor trying to debug by looking at core dumps :D

I am currently experimenting with languages and interpreters, so if there is anything I would like to publish, I suppose I'd port a working concept to C, although C++ might just as well do the trick.

Again, thanks to everyone for your answers and your insight.

答:
Hooray for curiosity!

It's very good to have some notion what's really going on at the lowest levels of a complex system, even if there's no logical need to know for one's everday duties.   By far the best way to grok things at the bits level is build your own CPU.   You have to think about machine language-level opcodes, understand why orthogonal instruction sets are so good, complications of interrupt handling, tradeoffs between complex circuits vs. microcode (e.g in multiplication units), and oh so much other fun!

But that, obviously, takes electronics know-how and is time consuming, so next best thing is toy around with an antique-style 8-bit CPU.  Microcontrollers like the 8051 are still in widespread use and available to hobbyists.  That still takes some know-how in herding electronics and making LEDs glow w/o smoking, and costs $$ if you're not already equiped for electronics.

Next best thing after that: toy around in a CPU simulator (emulator? I get those terms mixed up) -- these exist for Z80, 6502, 8086... all the old 8-bitters. That may be the most educational and fun for an applications programmer who doesn't know which end of the soldering iron to hold (though one learns that pretty fast :)   How text is written to video memory, how assembly code tricks help with performance... there's plenty of fun stuff to explore at this level.

I'm not so sure about learning C as just another language, without some initial understanding of CPU inner workings.  Knowing how bits are sent between CPU registers and how the memory accessed, helps tremendously with truly getting pointers and other C language concepts.

ContentLicense: CC BY-SA 2.5


问:
How to locate source code that implemented a certain feature?
I was wondering what are some techniques to locate which code implemented a specific feature, on a desktop application.

I am a junior developer, with only professional programming experience lying around web programming. In the Web it is easier to do that. For example, you "inspect" a button with the browser tools, and you can see what is being done when you click it. And then, presuming you have the full source code, you can drill down the hierarchy of the calls.

But how do you do this in desktop applications? At least, without having to dive into the full codebase?

答:
Assuming that the feature is tied to some UI thingie, like a Button or Menu, what I tend to do follows (very tedious but it works).  This is looking through the Source Code, not using a debugger.

Search for the (hopefully distinctive) text on the button, e.g. "Super Feature X3".

That is probably in a file with some constant, e.g.  SUPER_BUTTON_3 = "Super Feature X3".  For future reference, remember this file name.

There may be another layer (of even two) of abstraction, keep searching to get the "real" String that gets used by the Button.  Note how this is done for the future.

Now search on that constant.  Hopefully you have now found the Button.  Maybe that is where they connect the ActionListener.  (I'm taking Java-ese here, YMMV, but the concept still holds)

If necessary, search on that Button and you'll eventually find where it gets connected to a Listener.

Perhaps that listener really redirects to other listeners (the "real" functionality)  based upon the constant, if so, follow that if/else or case statement.  NOTE: If there is a central dispatchy thing, this is a great place to setup breakpoints.

Finally, you should be at the actual code.

As @amon noted, sometimes a Debugger is simpler...


答:
Back Tracing

Back tracing is locating an endpoint to an event associated with the feature (see below). Once there, a breakpoint is placed in the debugger. The feature is triggered and when the debugger stops. The call stack is reviewed to back trace the calling path. While walking up the call stack you can take notes on variable states, or place new breakpoints to inspect the event again.

The feature is trigger again and the debugger stops at the new breakpoints. You can then repeat back tracing or perform forward tracing until the goal is found.

Pros & Cons

It's always easier to walk up the call stack and see how you got somewhere.

There could be millions of conditions that need to be true before reaching an endpoint. If you know the endpoint already you've saved yourself lots of work.

If the feature is broken. You may never reach the endpoint, and time can be wasted trying to figure out why.

Endpoint Discovery

To debug a feature you have to know where in the source code the final goal is achieved. Only from this point can you backtrace to see how the code got there. An example; To understand how undo is performed. You know where in the code things are undone, but you don't know how things get there. This would be a candidate for backtracing to figure out how the feature works.

Forward Tracing

Forward tracing is locating a start point for an event associated with a feature (see below). Once there, logging messages are inserted into the source code or breakpoints are set. This process is repeated as you progress further away from the start point until you discover the goal for the feature.

Pros & Cons

It's the easiest starting point for finding a feature.

Code complexity reduces the effectiveness of forward tracing. The more conditions there are in the code the greater the chance you'll go in the wrong direction.

Forward tracing often results in setting breakpoints that will be triggered by unrelated events. Interrupting the debugging process and interfering with your search.

Start Point Discovery

You can use keywords, user interface identifiers (button IDs, window names) or easy to find event listeners associated with the feature. For example, you might start with the button used to trigger an undo feature.

Process Of Elimination

You can think of this as the middle point compared to start point and end point positions. You perform a process of elimination when you already know a piece of code is used in a feature, but it is neither the start or end of the feature.

The direction you take from the middle point depends upon the number of entries and exits. If the code chunk is used in many places, then back tracing from this position could be very time consuming as they all have to be inspected. You then employ a process of elimination to reduce this list. Alternative, you can perform a forward trace from this point, but again if the code chunk branches out to many places this can also be a problem.

You have to reduce position directions by not following paths that clearly wouldn't be executed for the feature. Moving past this code and only placing breakpoints where it's likely related to the feature.

Middle point debugging often requires more advance IDE features. The ability to see code hierarchy and dependencies. Without those tools it's difficult to do.

Pros & Cons

Middle points are often the first peice of code that pops into your head when you think of the feature. You say to yourself "Ah, that has to use XXXX to work."

Middle points can reveal start points the easiest.

Middle points can be an easy way to pick up the trail to a feature when lost by  synchronization or threading changes.

Middle points can take you to code you are not familiar with. Costing you time to learn what is going on.

Title: How to locate source code that implemented a certain feature?

Body:
I was wondering what are some techniques to locate which code implemented a specific feature, on a desktop application.

I am a junior developer, with only professional programming experience lying around web programming. In the Web it is easier to do that. For example, you "inspect" a button with the browser tools, and you can see what is being done when you click it. And then, presuming you have the full source code, you can drill down the hierarchy of the calls.

But how do you do this in desktop applications? At least, without having to dive into the full codebase?


问:
Would this interpreter be considered a Virtual Machine?
(I reworded my question to make it more specific).

Consider a programming language, that it's programs may only be run inside a specific program that serves as an interpreter.

The interpreter scans each line of the source code and executes it as it is.

Would the interpreter be considered a virtual machine?

Conceptually, a VM is a program that other programs use as a platform to run inside of. Thus this interpreter suits the definition. But this interpreter only interprets plain-text source code into executions (and not bytecode).

答:
It depends. "executing" isn't really the defining part of a virtual machine.

To qualify as a virtual machine, an interpreter would have to offer:

a memory model (ways for a program to acquire, use and release memory - is there garbage collection?)

APIs for IO (ways for programs to access files, networks, etc.)

optionally, a concurrency model (ways for programs to execute in parallel and coordinate)

And all of these would have to be well-defined and independent of the underlying OS and hardware. An interpreter that does all of this would have a good claim of being a VM.


答:
I think you're confusing a sandbox with virtual machine. A sandbox is a safe container for a single application, where as a virtual machine is a safe container for many applications. VMs often don't restrict what those apps can be, but a sandbox can be for a specific type of app.

The difference between a sandbox and an interpreter is; An interpreter can be interrupted without killing the application, where as a sandbox can only be interrupted by killing the application.

Title: Would this interpreter be considered a Virtual Machine?

Body:
(I reworded my question to make it more specific).

Consider a programming language, that it's programs may only be run inside a specific program that serves as an interpreter.

The interpreter scans each line of the source code and executes it as it is.

Would the interpreter be considered a virtual machine?

Conceptually, a VM is a program that other programs use as a platform to run inside of. Thus this interpreter suits the definition. But this interpreter only interprets plain-text source code into executions (and not bytecode).


答:
If you can find any related code at all, you can use your source control software to show you the entire commit or nearby commits that added it. That should show you everything that was required to implement that feature.

One easy way to find some starting point to look would be to grep through your codebase looking for the text on the button.

Often, people will put an issue id from their issue tracker in their commit messages. If you can find an issue describing the feature request, then you can search for commits with that issue id.


答:
Any interpreter could be considered a virtual machine.  It entirely depends on the definition of virtual machine that you adopt.

Conceptually, a VM is a program that other programs use as a platform to run inside of. Thus this interpreter suits the definition.

Yes ...

But this interpreter only interprets plain-text source code into executions (and not bytecode).

Well your definition of virtual machine does not say anything about the nature of the "platform".  So those issues are not relevant.

There is also the issue that you haven't defined "program".  Depending on how you define it, your example may not be an example of VM because the interpreter is not a different program to the virtual machine.  (On the other hand, that might just be a flaw in your definition of a "virtual machine".)

I would point out that there is one difference between your interpreter and (say) a Java + JVM instance.  In your case, the virtual machine is not exposed.  It is entirely inside the interpreter.  Hence, what it is and how it works is only really of academic interest.

And frankly, so is this entire topic.


答:
The definition of interpretation (correct me if I'm wrong) is parsing code like so:

Translate currently parsed line to some intermediate language.

Run the translated line.

Move to the next line.

Translate it.

Run it. And so on.

That is not a valid definition.  It describes just one way of implementing an interpreter, but it excludes other ways.  Most interpreters do not operate a line at a time like that.  It is more normal to translate from source code to an intermediate form ahead of actually trying to execute the intermediate form.

And even the phrase "intermediate form" is potentially incorrect, in that it suggests that there is some other form for the code after the intermediate form.

If so, why do people say that the JVM interprets the Java Bytecode? What it does is execute it.

Interpretation is a form of execution.  So there is no contradiction.

Interpretation as opposed to what?

As opposed to compiling the bytecodes to native code and executing the native code.  Which is what typically happens in typical Java implementations ... one way or another.

In a typical JVM, the bytecodes are interpreted to start with.  After a bit the JIT compiler compiles them to native code that can be executed directly.  Other modes include:

Interpreting bytecode all of the time; e.g. using java -int

Ahead of time compilation; e.g. using gcj.

Load-time compilation ... in which the bytecodes are compiled to native code as they are loaded by the classloader; e.g. JNode does this.

FOLLOWUP QUESTION

JIT execution means to compile each line during execution, correct?  If so, how is it different than interpretation?

Firstly, no that is not correct:

There is no such thing as "JIT execution".  When people say that, they really mean "JIT compilation and execution" ... and they are not spelling it out.

JIT compilation is not done a line at a time.  It is typically done a method at a time.

And the difference is in what it is doing.  The JIT compiler's job it to compile bytecodes to native code.  It does not execute the bytecodes.  Execution of the bytecodes is done by either interpreting the bytecodes (before they have been JIT compiled) or executing the native code that the JIT compiler has produced.

Title: Is Java Bytecode interpreted?


问:
What is the difference between the incremental and iterative approach to software development?
The Incremental approach is a method of software development where the model is designed, implemented and tested incrementally (a little more is added each time) until the product is finished. It involves both development and maintenance. The product is defined as finished when it satisfies all of its requirements

The Iterative Design is a design methodology based on a cyclic process of prototyping, testing, analyzing, and refining a product or process. Based on the results of testing the most recent iteration of a design, changes and refinements are made. This process is intended to ultimately improve the quality and functionality of a design. In iterative design, interaction with the designed system is used as a form of research for informing and evolving a project, as successive versions, or iterations of a design are implemented.

It seems both methods are about creating a part of the system ,  refining it to pass all the test cases , adding another component of the system and refining it again , these gets repeated untill the system is finished.

What is the actual difference between these two ways of designing software

How is it possible to combine these two methods to form iterative and incremental design approach

答:
The Incremental Approach uses a set number of steps and development goes from start to finish in a linear path of progression.

Incremental development is done in steps from design, implementation, testing/verification, maintenance. These can be broken down further into sub-steps but most incremental models follow that same pattern. The Waterfall Model is a traditional incremental development approach.

The Iterative Approach has no set number of steps, rather development is done in cycles.

Iterative development is less concerned with tracking the progress of individual features. Instead, focus is put on creating a working prototype first and adding features in development cycles where the Increment Development steps are done for every cycle. Agile Modeling is a typical iterative approach.

The incremental model was originally developed to follow the traditional assembly line model used in factories. Unfortunately, software design and development has little in common with manufacturing physical goods. Code is the blueprint not the finished product of development. Good design choices are often 'discovered' during the development process. Locking the developers into a set of assumptions without the proper context may lead to poor designs in the best case or a complete derailing of the development in the worst.

The iterative approach is now becoming common practice because it better fits the natural path of progression in software development. Instead of investing a lot of time/effort chasing the 'perfect design' based on assumptions, the iterative approach is all about creating something that's 'good enough' to start and evolving it to fit the user's needs.

tl;dr - If you were writing an essay under the Incremental Model, you'd attempt to write it perfectly from start to finish one sentence at at time. If you wrote it under the Iterative Model, you'd bang out a quick rough draft and work to improve it through a set of revision phases.

Update:

I modified my definition for 'Incremental Approach' to fit a more practical example.

If you have ever had to deal with contracting the Incremental Approach is how most contracts are carried out (especially for the military). Despite the many subtle variations of the typical 'Waterfall Model' most/all of them are applied the same way in practice.

The steps go as follows:

Contract Award

Preliminary Design Review

Critical Design Review

Specification Freeze

Development

Fielding/Integration

Verification

Reliability Testing

The PDR and CDR are where the spec is created and revised. Once the spec is complete, it should be frozen to prevent scope creep. Integration occurs if the software is used to extend a pre-existing system. Verification is for checking that the application matches the spec. Reliability is a test to prove that the application will be reliable over the long term, this can be specified much like a SLA (Service Level Agreement) where the system is required to sustain a certain percentage of uptime (ex 99% uptime for 3 months).

This model works great for systems that are straightforward to specify on paper but difficult to produce. Software is very difficult to specify on paper to any appreciable degree of detail (ex UML). Most 'business types' in charge of management/contracting fail to realize that -- when it comes to software development -- the code itself is the spec. Paper specifications often take as much or more time/effort to write as the code itself and they usually prove to be incomplete/inferior in practice.

Incremental approaches attempt to the wasted time/resources by treating the code itself as the specification. Instead of running the paper spec through multiple revision steps, the code itself goes through multiple cycles of revision.

ContentLicense: CC BY-SA 4.0


问:
What is the relationship between OpenGL, GLX, DRI, and Mesa3D?
I am starting out doing some low-level 3D programming in Linux. I have a lot of experience using the higher level graphics API OpenInventor.

I know it is not strictly necessary to be aware of how all these things fit together but I'm just curious. I know OpenGL is just a standard for graphics applications. Mesa3D seems to be an open source implementation of this standard.

So where do GLX and DRI fit? Digging around on Wikipedia and all these websites, I've yet to find an explanation of exactly how it all goes together. Where does hardware acceleration happen? What do proprietary drivers have to do with this?

答:
http://www.bitwiz.org.uk/s/how-dri-and-drm-work.html

The Direct Rendering Infrastructure, also known as the DRI, is a framework for allowing direct access to graphics hardware under the X Window System in a safe and efficient manner. It includes changes to the X server, to several client libraries, and to the kernel (DRM, Direct Rendering Manager). The most important use for the DRI is to create fast OpenGL implementations providing hardware acceleration for Mesa. Several 3D accelerated drivers have been written to the DRI specification, including drivers for chipsets produced by 3DFX, AMD (formerly ATI), Intel and Matrox.


问:
When an interpreter executes code: Is there a "chain of interpretations" down to the lowest level?
After doing some research and with the help of people on this site, I finally came to an understanding of what interpretation actually is.

Essentially, what interpretation means is (correct me if I'm wrong):

Scan a piece of code.

Come up with a piece of code in another language, with the same meaning.

Execute that new piece of code.

So for example, and interpreter written in Java that interprets code in C, and sees this line of code:printf("hello world");

Will come up with this line of code: System.out.println("hello world");

And will execute it (as opposed to a compiler, which will store it).

If all of this is true, then here is my question:

I think, that every execution an interpreter carries out, actually creates a chain of interpretations down to the lowest level. I'd like to know if this is true. Here is what I mean:

When an interpreter executes a line of code (which is the new line it came up with, after scanning a line), it actually tells the underlying platform to interpret it.

For example, as we know, an interpreter written in Java that interprets C code, sees printf("hello") and executes in reaction the new line of code System.out.println("hello").

But what does "executes System.out.println("hello")" actually mean? It means to tell the underlying platform (in this case the JVM) to interpret this line.

And so, another interpretation begins: The (in this example) interpreter in the JVM receives the line System.out.println(), comes up with a new line of code with the same meaning in another language, and executes it.

And when it executes the new line of code, again: It actually tells it's underlying platform to interpret it (in this example, the OS). And then another interpretation begins in the OS, which comes up with a new line of code with the same meaning in a different language, and tells an even lower level to interpret it. This continues down to the lowest level of the CPU.

My question is: Is this true? Is every execution an interpreter carries out, actually a call to the underlying platform to interpret? (Thus creating a chain of interpretations down to the lowest level?)

When people say that an interpreter executes code, do they actually mean that it tells it's underlying platform to interpret that code? (And so on?)

(Note: I might be not accurate about the function of the JVM specifically, I missed some steps there. But my question is more general, Java is just an example).

答:
Yes, but more than that. All of the interpreter's code is interpreted by a lower level, including the "scan a piece of code" step.

However, there are less levels than you think - more than three levels is rare.
Jython is one example of an interpreter running on an interpreter. It runs Python code, and is itself written in Java, which is interpreted by a JVM, which is machine code (that was compiled from C or C++) which is interpreted by the CPU.

JVMs commonly are written in C or C++, and run directly on the CPU, not the OS. Native programs run directly on the CPU, alongside the operating system, rather than being interpreted by the operating system. The difference between the OS and a native program is that the OS has more access to the hardware, so that if the native program wants to access the hardware (e.g. to display stuff on the screen) it still needs to ask the OS.

Also, the "coming up with a line of code in a new language" is Just-In-Time Compilation, not strictly interpretation. Many programs traditionally thought of as interpreters (including nearly all JVMs) do use some form of JIT compilation. A JIT compiler looks something like this:

```<code>void execute(instruction instructions_to_execute[])
{
    lower_level_function f;
    if(is_translation_in_cache(instructions_to_execute))
        f = get_translation_from_cache(instructions_to_execute);
    else
    {
        f = translate_to_lower_level_instructions(instructions_to_execute);
        put_translation_in_cache(instructions_to_execute, f);
    }
    f();
}
</code>```

while an interpreter looks like this:

```<code>void execute(instruction instructions_to_execute[])
{
    for(instruction i in instructions_to_execute)
    {
        switch(i.type)
        {
        case PRINT_STRING:
            print(i.string_to_print);
            break;
        case ADD:
            variables[i.result_variable] = variables[i.left_variable] + variables[i.right_variable];
            break;
        case CALL:
            execute(functions[i.function_to_call].instructions);
            break;
        // etc
        }
    }
}
</code>```

JIT compiling is usually faster for frequently run sections of code, because they can be converted into the lowest level code, and then executed directly. Interpreting is faster for sections of code that are infrequently executed, because the compiler (the translate_to_lower_level_instructions function) is slow.

Body:
Yes, but more than that. All of the interpreter's code is interpreted by a lower level, including the "scan a piece of code" step.

However, there are less levels than you think - more than three levels is rare.
Jython is one example of an interpreter running on an interpreter. It runs Python code, and is itself written in Java, which is interpreted by a JVM, which is machine code (that was compiled from C or C++) which is interpreted by the CPU.

JVMs commonly are written in C or C++, and run directly on the CPU, not the OS. Native programs run directly on the CPU, alongside the operating system, rather than being interpreted by the operating system. The difference between the OS and a native program is that the OS has more access to the hardware, so that if the native program wants to access the hardware (e.g. to display stuff on the screen) it still needs to ask the OS.

Also, the "coming up with a line of code in a new language" is Just-In-Time Compilation, not strictly interpretation. Many programs traditionally thought of as interpreters (including nearly all JVMs) do use some form of JIT compilation. A JIT compiler looks something like this:

void execute(instruction instructions_to_execute[])
{
    lower_level_function f;
    if(is_translation_in_cache(instructions_to_execute))
        f = get_translation_from_cache(instructions_to_execute);
    else
    {
        f = translate_to_lower_level_instructions(instructions_to_execute);
        put_translation_in_cache(instructions_to_execute, f);
    }
    f();
}

while an interpreter looks like this:

void execute(instruction instructions_to_execute[])
{
    for(instruction i in instructions_to_execute)
    {
        switch(i.type)
        {
        case PRINT_STRING:
            print(i.string_to_print);
            break;
        case ADD:
            variables[i.result_variable] = variables[i.left_variable] + variables[i.right_variable];
            break;
        case CALL:
            execute(functions[i.function_to_call].instructions);
            break;
        // etc
        }
    }
}

JIT compiling is usually faster for frequently run sections of code, because they can be converted into the lowest level code, and then executed directly. Interpreting is faster for sections of code that are infrequently executed, because the compiler (the translate_to_lower_level_instructions function) is slow.


问:
Empty virtual method on base class VS abstract methods
I couldn't find a question that was not too specific to some case, so I'll try to make this very generic.

We need an extractor base class to a set of documents, for example. Each document has its specific properties, but they're ultimately documents. So we want to provide common extraction operations for all of them.

Even though they're all documents, as I said, they're somewhat different. Some may have some properties, but some may not.

Let's imagine that we have the Document base abstract class, and the FancyDocument and NotSoFancyDocument classes that inherit from it.
The FancyDocument has a SectionA, the NotSoFancyDocument doesn't.

That said, what would you defend as the best way of implementing this? Here's the two options:

Empty virtual methods on the base class

Empty virtual methods on the base class would allow the programmer to only override the methods that make sense for the different types of documents. We would then have a default behavior on the abstract base class, which would be returning the default for the methods, like this:

```<code>public abstract class Document
{
    public virtual SectionA GetDocumentSectionA()
    {
        return default(SectionA);
    }
}

public class FancyDocument : Document
{
    public override SectionA GetDocumentSectionA()
    {
        // Specific implementation
    }
}

public class NotSoFancyDocument : Document
{
    // Does not implement method GetDocumentSectionA because it doesn't have a SectionA
}
</code>```

Concrete empty methods or concrete methods throwing a NotImplementedException

Since the NotSoFancyDocument does not have a SectionA, but the others do, we could either just return the default for the method in it, or we could throw a NotImplementedException. That would depend on how the program was written and some other things. We could come up with something like this:

```<code>//// Return the default value

public abstract class Document
{
    public abstract SectionA GetDocumentSectionA();
}

public class FancyDocument : Document
{
    public override SectionA GetDocumentSectionA()
    {
        // Specific implementation
    }
}

public class NotSoFancyDocument : Document
{
    public override SectionA GetDocumentSectionA()
    {
        return default(SectionA);
    }
}
</code>```

OR

```<code>//// Throw an exception

public abstract class Document
{
    public abstract SectionA GetDocumentSectionA();
}

public class FancyDocument : Document
{
    public override SectionA GetDocumentSectionA()
    {
        // Specific implementation
    }
}

public class NotSoFancyDocument : Document
{
    public override SectionA GetDocumentSectionA()
    {
        throw new NotImplementedException("NotSoFancyDocument does not have a section A");
    }
}
</code>```

Personally, I do think that the abstract method approach is better, since it means "Hey, I need you to be able to get a SectionA to be a document. I don't care how." while the virtual method means "Hey, I do have this SectionA here. If it's not good enough for you, feel free to change the way I get it.".

I do think the first one is a sign of object oriented programming smell.

What are your opinions on this?

答:
As stated in the comments, neither of these options is very good. That's probably the reason why you're asking this question as well.

The solution with empty virtual methods gives no information on what is supported by a specific document instance. Furthermore, it forces you to add all possible methods in the base class. This forces all clients to be updated as whel, when you decide that the base class needs additional methods.

The solution that throws exceptions is possibly even worse, since clients of the document classes will have to handle a possible exception for every method. That leads to dreadfull and unreliable code.

The problem that you are struggling with is that the document classes cannot predict the desired result. That is application logic, and that should not be implemented in the model layer. At least not in a way that leads to a reusable model layer.

I would suggest using interfaces to describe the sets of capabilities that you require. Fo instance, an IDocument interface, an IFancy interface and an INotSoFancy interface. These interface may or may not derive from IDocument or an other common interface, since you are talking about capabillities, not objects.

Using this interface based solution, client code can determine whether the given document instance supports a desired capabillity (by attempting to cast the document instance to the desired interface). The client code can than act accordingly.


问:
Are there programming languages that their programs don't run on a VM or natively, but rather on an interpreter?
In this question I presented an idea I have for a simple programming language. The way programs written in this language will be run, is inside an interpreter written in Java, which will interpret the source code directly and execute it.

I would say that there is no doubt that this language would be considered a 'programming language'. It is capable of producing programs that can run, and there exists a platform for them to run on (the interpreter).

However, most answers on my question said that this interpreter won't be considered a VM.

I am used to thinking that all programming languges create programms that are most commonly either compiled to machine code and executed natively, or compiled to some kind of bytecode or IL and interpreted (executed) on a VM. (Or like in the rare case of the Dart language, interpreted and executed by a VM which interprets the source-code directly, no IL or bytecode).

But in my case - if it's true that my interpreter isn't considered a VM - programs written in my language do not run on a VM, and do not run natively, but rather run on an interpreter.

My question:

Are there programming languages in existence, that their programms are most commonly executed similarly? Not on a VM, and not natively, but rather run on an interpreter? (which is not considered a VM - although I must add I still don't understand why an interpreter that's used as a platform for other programs to run on isn't considered a VM).

答:
Most first implementations of programming languages are either transcompilers into another programming language or interpreters, because these are a lot easier to write than compilers or virtual machines.

When the language becomes popular and the first people start complaining about its lack of performance, people start to look for ways to make the implementations of the language execute faster. Making it a compiled language would change how it is used and deployed. So the usual choice is to turn the interpreter into a virtual machine which converts the source to bytecode before running it.

A good example is Javascript. When Netscape invented Javascript in 1995, it was purely interpreted. But when people started using JS for more and more complex applications, speed started to matter. There was also the browser war going on, where all the browser vendors tried to outperform each other. So browser vendors started looking at ways to make JS execute faster. SpiderMonkey, the Javascript engine by Mozilla, compiles Javascript to Bytecode and runs it in a VM. Google's V8 engine is even compiling Javascript code to native machine code before running it.


答:
A VM is a piece of software that offers a machine-like abstraction. In the context of virtualization, a VM might abstract hardware resources. In programming language VMs, the VM offers a machine model, e.g. with a specific instruction set, a number of stacks, and a memory model.

It is true that we can interpret any language as an instruction set, but usually VM instructions are more fine-grained than high-level programming directives. For example, the high-level foo("bar", "baz") might have been changed to these instructions for a stack machine:

```<code>PUSH "baz"
PUSH "bar"
PUSH 2      ; number of arguments
LOAD "foo"  ; load the value of a variable onto the stack, here a function
CALL        ; the "CALL" op pops a function and number of arguments off the stack,
            ; then calls it
</code>```

How these instructions are executed is irrelevant for this discussion, they may well be interpreted.

An interpreter that “directly” executes foo("bar", "baz") would generally not be considered to be a VM. Direct interpretation has fallen out of favor even for simple hobby languages, but early BASIC dialects used to be interpreted. Today, simple interpretation might be still used for simple shell languages.

The problem with naive, line-based interpreters is the difficulty of implementing structured and procedural programming. Let's assume we want to write if (x) { y } else { z }. This could be done with conditional GOTOs:

```<code>10 GOTO 40 IF x
20 z
30 GOTO 50
40 y
50
</code>```

This is far to fragile for any serious use, but is very easy to implement. But Go To is Considered Harmful, and we rather much prefer an if/else construct. For example, bash uses if/then/else/fi:

```<code>if x
then y
else z
fi
</code>```

If the condition if false, the interpreter could jump to the matching else – but this is essentially a balanced parens problem, because conditionals may be nested. Another complication is that statements can also be separated via ; instead of newlines, so it's not simply a matter of looking at the first word in every line.

In short, any language with even remotely bearable syntax should be parsed into a data structure prior to execution. The output of a parser is called an Abstract Syntax Tree. E.g. foo("bar", 4 + variable) might produce this AST:

```<code>FunctionCall
name: "foo"
    |
   List
 length: 2
 /      \
String  Addition
"bar"    /    \
       Int   Variable
        4    name: "variable"
</code>```

An AST can be evaluated bottom-up. First, we replace the variable with its value (e.g. 38). Next, the subtree

```<code>Addition
 /   \
4    38
</code>```

would get evaluated, which replaces this subtree with 42. Finally, the function get's executed which substitutes that part of the tree.

Describing the operational semantics of a programming language using these graphs is nice, but it's not a good model for actual execution: this destroys the original tree, so you have to make a copy for stuff like loop bodies or procedures. And if we have variables, our interpreter needs a concept of an environment which already brings us very close to being a VM.

We cross that boundary to being a VM if we note that the nodes in our AST are essentially Opcodes. If we order the tree operations (here: bottom-up, right to left: post-order traversal), and do not update the actual tree but place the intermediate values on the stack instead, the above example could also have been written as a more assembler-like

```<code>Variable "variable"
Int 4
Addition
String "bar"
List 2
FunctionCall "foo"
</code>```

Title: Are there programming languages that their programs don't run on a VM or natively, but rather on an interpreter?

Body:
In this question I presented an idea I have for a simple programming language. The way programs written in this language will be run, is inside an interpreter written in Java, which will interpret the source code directly and execute it.

I would say that there is no doubt that this language would be considered a 'programming language'. It is capable of producing programs that can run, and there exists a platform for them to run on (the interpreter).

However, most answers on my question said that this interpreter won't be considered a VM.

I am used to thinking that all programming languges create programms that are most commonly either compiled to machine code and executed natively, or compiled to some kind of bytecode or IL and interpreted (executed) on a VM. (Or like in the rare case of the Dart language, interpreted and executed by a VM which interprets the source-code directly, no IL or bytecode).

But in my case - if it's true that my interpreter isn't considered a VM - programs written in my language do not run on a VM, and do not run natively, but rather run on an interpreter.

My question:

Are there programming languages in existence, that their programms are most commonly executed similarly? Not on a VM, and not natively, but rather run on an interpreter? (which is not considered a VM - although I must add I still don't understand why an interpreter that's used as a platform for other programs to run on isn't considered a VM).

Body:
A VM is a piece of software that offers a machine-like abstraction. In the context of virtualization, a VM might abstract hardware resources. In programming language VMs, the VM offers a machine model, e.g. with a specific instruction set, a number of stacks, and a memory model.

It is true that we can interpret any language as an instruction set, but usually VM instructions are more fine-grained than high-level programming directives. For example, the high-level foo("bar", "baz") might have been changed to these instructions for a stack machine:

PUSH "baz"
PUSH "bar"
PUSH 2      ; number of arguments
LOAD "foo"  ; load the value of a variable onto the stack, here a function
CALL        ; the "CALL" op pops a function and number of arguments off the stack,
            ; then calls it

How these instructions are executed is irrelevant for this discussion, they may well be interpreted.

An interpreter that “directly” executes foo("bar", "baz") would generally not be considered to be a VM. Direct interpretation has fallen out of favor even for simple hobby languages, but early BASIC dialects used to be interpreted. Today, simple interpretation might be still used for simple shell languages.

The problem with naive, line-based interpreters is the difficulty of implementing structured and procedural programming. Let's assume we want to write if (x) { y } else { z }. This could be done with conditional GOTOs:

10 GOTO 40 IF x
20 z
30 GOTO 50
40 y
50

This is far to fragile for any serious use, but is very easy to implement. But Go To is Considered Harmful, and we rather much prefer an if/else construct. For example, bash uses if/then/else/fi:

if x
then y
else z
fi

If the condition if false, the interpreter could jump to the matching else – but this is essentially a balanced parens problem, because conditionals may be nested. Another complication is that statements can also be separated via ; instead of newlines, so it's not simply a matter of looking at the first word in every line.

In short, any language with even remotely bearable syntax should be parsed into a data structure prior to execution. The output of a parser is called an Abstract Syntax Tree. E.g. foo("bar", 4 + variable) might produce this AST:

FunctionCall
name: "foo"
    |
   List
 length: 2
 /      \
String  Addition
"bar"    /    \
       Int   Variable
        4    name: "variable"

An AST can be evaluated bottom-up. First, we replace the variable with its value (e.g. 38). Next, the subtree

Addition
 /   \
4    38

would get evaluated, which replaces this subtree with 42. Finally, the function get's executed which substitutes that part of the tree.

Describing the operational semantics of a programming language using these graphs is nice, but it's not a good model for actual execution: this destroys the original tree, so you have to make a copy for stuff like loop bodies or procedures. And if we have variables, our interpreter needs a concept of an environment which already brings us very close to being a VM.

We cross that boundary to being a VM if we note that the nodes in our AST are essentially Opcodes. If we order the tree operations (here: bottom-up, right to left: post-order traversal), and do not update the actual tree but place the intermediate values on the stack instead, the above example could also have been written as a more assembler-like

Variable "variable"
Int 4
Addition
String "bar"
List 2
FunctionCall "foo"


问:
Communication between nested directives
There seem to be quite a few ways of communicating between directives. Say you have nested directives, where the inner directives must communicate something to the outer (e.g. it's been chosen by the user).

```<code><outer>
  <inner></inner>
  <inner></inner>
</outer>
</code>```

So far I have 5 ways of doing this

require: parent directive

The inner directive can require the outer directive, which can expose some method on its controller. So in the inner definition

```<code>require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
   // This can be passed to ng-click in the template
   $scope.chosen = function() {
     outerController.chosen(something);
   }
}
</code>```

And in the outer directive's controller:

```<code>controller: function($scope) {
   this.chosen = function(something) {
   }
}
</code>```

$emit event

The inner directive can $emit an event, which the outer directive can respond to, via $on. So in the inner directive's controller:

```<code>controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}
</code>```

and in the outer directives controller:

```<code>controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}
</code>```

Execute expression in parent scope, via &

The item can bind to an expression in the parent scope, and execute it at an appropriate point. The HTML would be like:

```<code><outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>
</code>```

So the inner controller has an 'innerChoose' function it can call

```<code>scope: {
  'innerChoose': '&'
},
controller: function() {
  $scope.click = function() {
    $scope.innerChoose({item:something});
  }
}
</code>```

which would call (in this case) the 'functionOnOuter' function on the outer directive's scope:

```<code>controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}
</code>```

Scope inheritance on non-isolated scope

Given that these are nested controllers, scope inheritance can be at work, and the inner directive can just call any functions in the scope chain, as long as it doesn't have an isolated scope). So in the inner directive:

```<code>// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}
</code>```

And in the outer directive:

```<code>controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}
</code>```

By service injected into both inner and outer

A service can be injected into both directives, so they can have direct access to the same object, or call functions to notify the service, and maybe even register themselves to be notified, in a pub/sub system. This doesn't require the directives to be nested.

Question: What are any potential drawbacks and advantages of each over the others?

答: My preference is for defining a & attribute in the directive scope primarily because I view the scope: {} definition of a directive as its API.  It's much easier to look at a scope attribute definition to see what information the directive needs to function properly than it is to scour link and controller functions for $emit'd events, inherited scope functions or functions used within injected controllers.

Title: Communication between nested directives


答:
Interpreting: This means you take a tiny piece of code, figure out what it does and then do it. The tiny piece of code may be "plain text" source code, but it may also be some sort of pre-tokenised code, or some sort of byte-code, or native instructions for a different CPU.  The important difference here is that for interpreting its never converted into native code for the CPU it's running on.

Compiling: This means you convert the source code into native code. When most people think of "compilers" they think of a tool that converts plain text source code into native code (known as "ahead of time compiling" because it's compiled before it's run - often even before the end-user receives it), but this isn't the only way to compile. The main benefit of ahead of time compiling is that the compiler can spend a lot of time optimising the code really well without the end-user caring how long it takes.

JIT Compiling: This is one of the different cases of compiling (note: JIT is "Just In Time", and different people will call this dynamic translation instead). In this case you wait until a small piece of code needs to be executed, then compile that small piece into native code and execute it; then you go looking for the next small piece of code. By caching the previously compiled small pieces you end up compiling most of the program while the program is being executed. For code that is executed often this is a lot faster than interpreting; but for code that is only run once it's slower than interpreting.

For Java, first the plain text source code is compiled into byte-code using an ahead of time compiler. This is where a lot of optimisation happens. After that the byte-code is executed by a Java Virtual Machine (JVM).

Old implementations of JVMs used to interpret the byte-code (which was slower). Modern JVMs interpret byte-code that isn't executed very often (to avoid the overhead of compiling when it's not justified) and also do JIT compiling for code that is executed often (to get close to native speed for those more important parts).

Basically (for modern implementations), it's not one or the other - it's "ahead of time" followed by a mixture of interpreted and JIT compiling.

Title: Is Java Bytecode interpreted?


答:
I have pondered this question many times. My answer is that these terms are only marginally useful, that there may be something of a spectrum of languages and implementations between them, but ultimately:

A VM executes an intermediate code; an interpreter executes the source code.

For a VM, the source code is merely "syntactic sugar" over the intermediate code. The source code is not required after compilation. Multiple languages could target the same VM. (JVM, CLR)

For an interpreter, the source code is all there is, and it is parsed, analysed and executed immediately. It might be tokenised, but if so it can be guaranteed that a version of the original source code can be reconstructed from the tokenised form.

So, where is such a language? There are almost none of them in existence. Most languages get compiled sooner or later for the performance improvement. The ones that can't are those where runtime values are or could be directly interpolated into the statements, or where nobody could be bothered to write a compiler.

Most shell script languages are interpreted: sh, bash, csh, MSDOS/Windows BAT files, etc. Desk top calculators (dc). A graphic package like Gnuplot. Editor scripts (sed, ed, vi).
The configuration file for a major piece of software like Apache. These are all interpreted, but some of them only marginally qualify as languages.

That's all I can think of.


问:
Disadvantages of scoped-based memory management
I really like scope-based memory management (SBMM), or RAII, as it is more commonly (confusingly?) referred to by the C++ community. As far as I know, except for C++ (and C), there's no other mainstream language in use today that makes SBMM/RAII their main memory management mechanism, and instead they prefer to use garbage collection (GC).

I find this rather confusing, since

SBMM makes programs more deterministic (you can tell exactly when an object is destroyed);

in languages that use GC you often have to do manual resource management (see closing files in Java, for example), which partly defeats the purpose of GC and is also error prone;

heap memory can also (very elegantly, imo) be scope-bound (see std::shared_ptr in C++).

Why is not SBMM more widely used? What are its disadvantages?

答:
RAII also follows from automatic reference-counting memory management, e.g. as used by Perl. While reference counting is easy to implement, deterministic, and quite performant, it cannot deal with circular references (they cause a leak) which is why it isn't commonly used.

Garbage-collected languages can't use RAII directly, but often do offer syntax with an equivalent effect. In Java, we have the try-with-ressource statement

```<code>try (BufferedReader br = new BufferedReader(new FileReader(path))) { ... }
</code>```

which automatically calls .close() on the resource on block exit. C# has the IDisposable interface, which allows .Dispose() to be called when leaving an using (...) { ... } statement. Python has the with statement:

```<code>with open(filename) as f:
    ...
</code>```

which works in a similar fashion. In an interesting spin on this, Ruby's file open method gets a callback. After the callback has been executed, the file is closed.

```<code>File.open(name, mode) do |f|
    ...
end
</code>```

I think Node.js uses the same strategy.

Body:
RAII also follows from automatic reference-counting memory management, e.g. as used by Perl. While reference counting is easy to implement, deterministic, and quite performant, it cannot deal with circular references (they cause a leak) which is why it isn't commonly used.

Garbage-collected languages can't use RAII directly, but often do offer syntax with an equivalent effect. In Java, we have the try-with-ressource statement

try (BufferedReader br = new BufferedReader(new FileReader(path))) { ... }

which automatically calls .close() on the resource on block exit. C# has the IDisposable interface, which allows .Dispose() to be called when leaving an using (...) { ... } statement. Python has the with statement:

with open(filename) as f:
    ...

which works in a similar fashion. In an interesting spin on this, Ruby's file open method gets a callback. After the callback has been executed, the file is closed.

File.open(name, mode) do |f|
    ...
end

I think Node.js uses the same strategy.


问:
Size of objects during Multilevel inheritance
Below is a pseudo declaration for a multilevel inheritance.

```<code>Base class ( protected int data)

derived1 : virtual public base ( protected int data1 )

derived2 : virtual public base ( protected int data2)

derived3 : derived1,derived2 ( private int data3 )

Main(){ base b;    derived1 d1;   derived2 d2;   derived3 d3; }

    sizeof(b) // 4 which is correct as only int (4bytes)
    sizeof(d1) // 12 why not 8 -> 4(base) + 4(derived)
    sizeof(d2) // ??? whatever applies above should apply here
    sizeof(d3) // 24 why not 12 -> 4(base) + 4(derived1/derived2) + 4(d3).
</code>```

Does size also include virtual tables also. Again here there cannot be virtual table as no virtual function defined. Please help in clarifying my doubt.

PS: What I have understood till now:

Unless the function is declared virtual in base class,

```<code>base *bptr;
 derived d;
 bptr = &d;
 bptr->fun();  // will call the base class function.
</code>```

But if the fun() is declared virtual then the above code will call derived class fun().

答:
The question you ask has no answer in the C++ standard. Compilers are free to insert additional members into classes for reasons of multiple inheritance, virtual, access control, alignment and so on. I think I would expect an additional item for a virtual base class, but I haven't investigated it specifically.

In practice you can expect a single pointer rather than a whole virtual table, and reasonably predictable padding. Beyond that I would hesitate to generalise.

If you really want to know why a specific structure you wrote has the specific sizes they do then you might use the debugger to find out what actually gets stored in each location. Any programs written to take advantage of that information would of course be non-portable.

Your supposition is correct but (a) that's a down-cast which has to be explicit (b) virtual function is not the same as virtual base class.

BTW it's called multiple inheritance.


答: Looking at some popularity index like TIOBE (which is arguable, of course, but I guess for your kind of question its ok to use this) , you first see that ~50% of the top 20 are "scripting languages" or "SQL dialects", where the "ease of use" and means of abstraction have a much more importance than deterministic behaviour. From the remaining "compiled" languages, there are around 50% of the languages with SBMM and ~50% without. So when taking the scripting languages out of your calculation, I would say your assumption is just wrong, among compiled languages the ones with SBMM are as popular as the ones without.</p>

Title: Disadvantages of scoped-based memory management

Body:
I really like scope-based memory management (SBMM), or RAII, as it is more commonly (confusingly?) referred to by the C++ community. As far as I know, except for C++ (and C), there's no other mainstream language in use today that makes SBMM/RAII their main memory management mechanism, and instead they prefer to use garbage collection (GC).

I find this rather confusing, since

SBMM makes programs more deterministic (you can tell exactly when an object is destroyed);

in languages that use GC you often have to do manual resource management (see closing files in Java, for example), which partly defeats the purpose of GC and is also error prone;

heap memory can also (very elegantly, imo) be scope-bound (see std::shared_ptr in C++).

Why is not SBMM more widely used? What are its disadvantages?


答:
Closures are an essential feature of pretty much all modern languages. They are very easy to implement with GC and very hard (though not impossible) to get right with RAII, since one of their main features is that they allow you to abstract over the lifetime of your variables!

C++ only got them 40 years after everybody else did, and it took a lot of hard work by a lot of smart people to get them right. In contrast, many scripting languages designed and implemented by people with zero knowledge in designing and implementing programming languages have them.


答:
Let's start by postulating that memory is by far (dozens, hundreds or even thousands of time) more common than all other resources combined. Every single variable, object, object member needs some memory allocated to it and freed later on. For every file you open, you create dozens to millions of objects to store the data pulled out of the file. Every TCP stream goes together with an unbounded number of temporary byte strings created to be written to the stream. Are we on the same page here? Great.

For RAII to work (even if you have ready-made smart pointers for every use case under the sun), you need to get ownership right. You need to analyse who should own this or that object, who should not, and when ownership should be transferred from A to B. Sure, you could use shared ownership for everything, but then you'd be emulating a GC via smart pointers. At that point it becomes much easier and faster to build the GC into the language.

Garbage collection frees you from this concern for the by far most commonly used resource, memory. Sure, you still need to make the same decision for other resources, but those are far less common (see above), and complicated (e.g. shared) ownership is less common too. The mental burden is reduced significantly.

Now, you name some downsides to making all values garbage collected. However, integrating both memory-safe GC and value types with RAII into one language is extremely hard, so perhaps it's better to migitate these trade offs via other means?

The loss of determinism in turns out to be not that bad in practice, because it only affects deterministic object lifetime. As described in the next paragraph, most resources (aside from memory, which is plentiful and can be recycled rather lazily) are not bound to object lifetime in these languages. There are a few other uses cases, but they are rare in my experience.

Your second point, manual resource management, is nowadays addressed via a statement that does perform scope-based cleanup, but does not couple this clean up to the object life time (hence not interacting with the GC and memory safety). This is using in C#, with in Python, try-with-resources in recent Java versions.


答:
In my opinion the most convincing advantage of garbage collection is that it allows for composability. Correctness of memory management is a local property in garbage collected environment. You can look at each part in isolation and determine if it can leak memory. Combine any number of memory-correct parts and they stay correct.

When you rely on reference counting you lose that property. Whether your application can leak memory becomes a global property of the whole application with reference counting. Every new interaction between parts has the possibility to use the wrong ownership and break memory management.

It has a very visible effect on the design of programs in the different languages. Programs in GC-languages tend to be a bit more soups of objects with lots of interactions, while in GC-less languages one tends to prefer structured parts with strictly controlled and limited interactions between them.


答:
Low level programming is for the corner cases where there is a requirement not immediately present on normal desktop computers.  This might be a speed bottleneck, or a memory bottleneck or something completely different, and it is very frequently very interesting to see what can be done given those requirements.

Think of it as Haikus or Limericks, where the restrictions make it interesting.

To give you an idea of what is possible in what would seem impossible today, here is one of the greatest hacks ever.  Chess in 1 Kb RAM!   http://users.ox.ac.uk/~uzdm0006/scans/1kchess/

Title: Low level programming - what's in it for me?

Body:
For years I have considered digging into what I consider "low level" languages. For me this means C and assembly. However I had no time for this yet, nor has it EVER been neccessary.

Now because I don't see any neccessity arising, I feel like I should either just schedule some point in time when I will study the subject or drop the plan forever.

My Position

For the past 4 years I have focused on "web technologies", which may change, and I am an application developer, which is unlikely to change.

In application development, I think usability is the most important thing. You write applications to be "consumed" by users. The more usable those applications are, the more value you have produced.

In order to achieve good usability, I believe the following things are viable

Good design: Well-thought-out features accessible through a well-thought-out user interface.

Correctness: The best design isn't worth anything, if not implemented correctly.

Flexibility: An application A should constantly evolve, so that its users need not switch to a different application B, that has new features, that A could implement. Applications addressing the same problem should not differ in features but in philosophy.

Performance: Performance contributes to a good user experience. An application is ideally always responsive and performs its tasks reasonably fast (based on their frequency). The value of performance optimization beyond the point where it is noticeable by the user is questionable.

I think low level programming is not going to help me with that, except for performance. But writing a whole app in a low level language for the sake of performance is premature optimization to me.

My Question

What could low level programming teach me, what other languages wouldn't teach me? Am I missing something, or is it just a skill, that is of very little use for application development? Please understand, that I am not questioning the value of C and assembly. It's just that in my everyday life, I am quite happy that all the intricacies of that world are abstracted away and managed for me (mostly by layers written in C/C++ and assembly themselves). I just don't see any concepts, that could be new to me, only details I would have to stuff my head with. So what's in it for me?

My Conclusion

Thanks to everyone for their answers. I must say, nobody really surprised me, but at least now I am quite sure I will drop this area of interest until any need for it arises.

To my understanding, writing assembly these days for processors as they are in use in today's CPUs is not only unneccesarily complicated, but risks to result in poorer runtime performance than a C counterpart. Optimizing by hand is nearly impossible due to OOE, while you do not get all kinds of optimizations a compiler can do automatically. Also, the code is either portable, because it uses a small subset of available commands, or it is optimized, but then it probably works on one architecture only.

Writing C is not nearly as neccessary anymore, as it was in the past. If I were to write an application in C, I would just as much use tested and established libraries and frameworks, that would spare me implementing string copy routines, sorting algorithms and other kind of stuff serving as exercise at university. My own code would execute faster at the cost of type safety. I am neither keen on reeinventing the wheel in the course of normal app development, nor trying to debug by looking at core dumps :D

I am currently experimenting with languages and interpreters, so if there is anything I would like to publish, I suppose I'd port a working concept to C, although C++ might just as well do the trick.

Again, thanks to everyone for your answers and your insight.


问:
Multiple entrance points in project
My question is related to C++ but it comes from Java actually.

When I was programming Java I had multiple classes, which were derived from a base "Test" class. Their purpose was to test things - run tests (unit tests/not unit tests).

In order to run a test, I had a public static void main in every class. So the matter of running such a test was to click run in Eclipse/Netbeans, whatever good IDE.

I know this question maybe IDE dependent, it actually boils down to a makefiles, but is it possible to maintain a similar structure in C++ IDEs?

Actually my question is: how do you deal with tests?

Do you put a huge main method with some switch/enum based statements to run the tests or make different build configurations for each test, or have different solution to this?

I know this question won't get a straightforward answer, but I'm curious how to deal with it so I can choose something for myself.

答:
The short answer is "you can't do this in C or C++ as easily as you can in Java."

Java lets you get away with having a main() method in every class because each class is its own namespace and can, in theory, be completely self-contained.  When you invoke the JVM on a class, you're telling it which namespace contains the main() you want it to run.  So, for example, java Foo really means "run Foo.main()."

Languages that compile to native objects don't work that way.  Most systems have a bit of code that gets linked into executables and is responsible for doing a bit of pre-flight prep, calling main() and passing the int that it returns back to the operating system as an exit code.  (On many Unixy systems, that code is in a file called crt0.o, or "C runtime zero.")  There's no simple way to pass in an alternate main() function at runtime because the linker has to sew all of that up beforehand.

If you want to achieve something similar in C or C++, you have a couple of choices:

One way is to use the preprocessor to subvert the usual things main() does and call a method directly if a symbol is defined:

```<code>class Foo {
  public:
    static void test() { // Your Test Here }
};

int main() {
#ifdef TEST_CLASS
  TEST_CLASS ## ::test();
#else
  // Do whatever main() usually does
#endif
}
</code>```

Then, to make this work, you'd have to have your IDE define TEST_CLASS to the name of the class whose test you'd like to run, recompile and run.

The other way is to compile all of your objects into a shared library and add exported-to-C symbols to run your tests.  Then you'd need a small program that uses the dynamic loader to fish out the symbol for the test you want to run and call it.  How you'd do this is very system-dependent and has no basis in a standard, so I'm not going to recommend it or elaborate on how it's done.

Title: Multiple entrance points in project

Body:
The short answer is "you can't do this in C or C++ as easily as you can in Java."

Java lets you get away with having a main() method in every class because each class is its own namespace and can, in theory, be completely self-contained.  When you invoke the JVM on a class, you're telling it which namespace contains the main() you want it to run.  So, for example, java Foo really means "run Foo.main()."

Languages that compile to native objects don't work that way.  Most systems have a bit of code that gets linked into executables and is responsible for doing a bit of pre-flight prep, calling main() and passing the int that it returns back to the operating system as an exit code.  (On many Unixy systems, that code is in a file called crt0.o, or "C runtime zero.")  There's no simple way to pass in an alternate main() function at runtime because the linker has to sew all of that up beforehand.

If you want to achieve something similar in C or C++, you have a couple of choices:

One way is to use the preprocessor to subvert the usual things main() does and call a method directly if a symbol is defined:

class Foo {
  public:
    static void test() { // Your Test Here }
};

int main() {
#ifdef TEST_CLASS
  TEST_CLASS ## ::test();
#else
  // Do whatever main() usually does
#endif
}

Then, to make this work, you'd have to have your IDE define TEST_CLASS to the name of the class whose test you'd like to run, recompile and run.

The other way is to compile all of your objects into a shared library and add exported-to-C symbols to run your tests.  Then you'd need a small program that uses the dynamic loader to fish out the symbol for the test you want to run and call it.  How you'd do this is very system-dependent and has no basis in a standard, so I'm not going to recommend it or elaborate on how it's done.


问:
Designing interfaces and async
Suppose I have created interface IFolderRepository with methods like that:

```<code>IEnumerable<Folder> GetAllFolders();
Folder GetFolderWithId(int id);
void AddFolder(Folder newFolder);
void ModifyFolder(Folder folderToModify, Folder folderAfterModification);
void RemoveFolder(Folder folderToRemove);
</code>```

and I've implemented DatabaseFolderRepository and lets say CacheFolderRepositoryDecorator. Now 'hundreds of lines later' I'd like to add SkyDrive folders functionallity so I'm ready to add SkyDriveFolderRepository. Unfortunately while DatabaseFolderRepository implementation used synchronous methods to talk with database, skydrive one uses a lot of async and await. What to do in such case? In case of void methods marking it async is not a solution (need to exception handling). Should I change interface to return Task<T>? Sure it will work in above example but they're just 2 interface implementation classes. Or should most of my interfaces have Task return types (against you aren't gonna need it rule)?

答:
You will probably find this MSDN article about Asynchronous practices to be a good read.

You asked:

Unfortunately while DatabaseFolderRepository implementation used synchronous methods to talk with database, skydrive one uses a lot of async and await.

This is where the sub-section Async All the Way in the MSDN article I linked will be pertinent to your situation.

In particular, it’s usually a bad idea to block on async code by calling Task.Wait or Task.Result. This is an especially common problem for programmers who are “dipping their toes” into asynchronous programming, converting just a small part of their application and wrapping it in a synchronous API so the rest of the application is isolated from the changes. Unfortunately, they run into problems with deadlocks.

Since you have at least one interface that needs to be asynchronous, YAGNI is reversed.  You are gonna need to make changes so that your interfaces are consistent.  Yes, it will create more effort up front for you.  But the benefit is less risk of deadlock; less complex debugging; and more predictable blocking (when it actually needs to occur).

I'm skipping over some of the other questions you asked as I think I addressed the core of your question.  Deal with the core and the rest of your questions fall away. The article is fairly involved and addresses the other points you brought up as well as pointing out additional pitfalls.

Asynchronous programming is one of those where you have to embrace the whole concept and just go with it.  Trying to just "dip your toes in" on a piecemeal basis ends up being a lot more complicated then just jumping straight in.

Title: Designing interfaces and async


问:
Where to Populate Objects
As mentioned in this question, I am moving our team towards objects (as opposed to just throwing DataTables and variables around everywhere).  I have picked a suitable spot for the project that contains the object definitions, but not sure how I should go about populating some of the objects.  In particular, what do I do with classes as properties?

```<code>Public Class Class1
    Public Property SomeProperty As String
    Public Property SomeOtherProperty As String
    Public Property SomeKey As Integer
    Public Property Foo As Class2
End Class
</code>```

In this basic example, I can easily populate the first three properties from a query, but Foo has its own set of properties.  Right now, to create a List(Of Class1) I generate the data for all of the Class1 objects, and then use SomeKey to go back and, one object at a time, populate all of the Foo.  Certainly this works, but in my case it is rather slow, and it seems that perhaps I am simply doing it wrong.

Am I handling that incorrectly?  If so, what should I be doing?  The only other thing I can come up with is to create a query (or stored procedure) that returns all of the appropriate data for all of the objects.  In my test case that amounts to a list that contains 154 Class1's, with each of them having four properties like Foo, and some of those having classes as properties.

答: There is no "best practice" on how to "populate objects", the same way as there is no best practice for how to create /populate a string or integer somewhere in your program. Objects are instances of classes, which can be seen as the equivalence of a user-defined type. You create and use some of them  within a small block scope, some of them a function scope, some of them in a class scope, module scope or global scope, just as long as you need the individual objects instance in your program to solve a certain task. Which task that is,  and which lifetime for an object is appropriate, depends fully on how the class you created, its responsibilities and the usage scenario.</p>

Title: Where to Populate Objects