答:
Your class itself seems fine to me, but you're right in that LoadFluffies() does not exactly what the name advertises. One simple solution would be to change the name and move the explicit reloading out of GetFluffies, into a function with an appropriate description. Something like

```<code>public Fluffies GetFluffies()
{
  MakeSureTheFluffyCacheIsUpToDate();
  return m_Cache;
}

private void MakeSureTheFluffyCacheIsUpToDate()
{
  if( !NeedsReload )
    return;
  GetFluffiesFromDb();
  SetNextReloadTime();
}
</code>```

looks clean to me (also because as like Patrick says: it's composed of other tiny SRP-obedient functions), and especially also clear which is sometimes just as important.

Title: How to avoid violating the SRP in a class to manage caching?

Body:
Note: The code sample is written in c#, but that shouldn't matter. I've put c# as a tag because I can't find a more appropiate one. This is about the code structure.

I'm reading Clean Code and trying to become a better programmer.

I often find myself struggling to follow the Single Responsibility Principle (classes and functions should do only one thing), specially in functions. Maybe my problem is that "one thing" is not well-defined, but still...

An example: I have a list of Fluffies in a database. We don't care what a Fluffy is. I want a class to recover fluffies. However, fluffies can change according to some logic. Depending on some logic, this class will return the data from cache or get the latest from the database.
We could say that it manages fluffies, and that is one thing.
To make it simple, let's say loaded data is good for an hour, and then it must be reloaded.

```<code>class FluffiesManager
{
    private Fluffies m_Cache;
    private DateTime m_NextReload = DateTime.MinValue;
    // ...
    public Fluffies GetFluffies()
    {
        if (NeedsReload())
            LoadFluffies();

        return m_Cache;
    }

    private NeedsReload()
    {
        return (m_NextReload < DateTime.Now);
    }

    private void LoadFluffies()
    {
        GetFluffiesFromDb();
        UpdateNextLoad();
    }

    private void UpdateNextLoad()
    {
        m_NextReload = DatTime.Now + TimeSpan.FromHours(1);
    }
    // ...
}
</code>```

GetFluffies() seems ok to me. The user asks for some fluffies, we provide them. Going to recover them from the DB if needed, but that could be considered a part of getting the fluffies (of course, that's somewhat subjective).

NeedsReload() seems right, too. Checks if we need to reload the fluffies.
UpdateNextLoad is fine. Updates the time for the next reload. that's definitely one single thing.

However, I feel what LoadFluffies() do can't be described as one single thing. It's getting the data from the Database, and it's scheduling the next reload. It's hard to argue that calculating the time for the next reload is part of getting the data. However, I can't find a better way to do it (renaming the function to LoadFluffiesAndScheduleNextLoad may be better, but it just makes the problem more obvious).

Is there an elegant solution to really write this class according to the SRP?
Am I being too pedantic?

Or maybe my class isn't really doing just one thing?

Body:
Your class itself seems fine to me, but you're right in that LoadFluffies() does not exactly what the name advertises. One simple solution would be to change the name and move the explicit reloading out of GetFluffies, into a function with an appropriate description. Something like

public Fluffies GetFluffies()
{
  MakeSureTheFluffyCacheIsUpToDate();
  return m_Cache;
}

private void MakeSureTheFluffyCacheIsUpToDate()
{
  if( !NeedsReload )
    return;
  GetFluffiesFromDb();
  SetNextReloadTime();
}

looks clean to me (also because as like Patrick says: it's composed of other tiny SRP-obedient functions), and especially also clear which is sometimes just as important.


问:
How do I model a sortable resource in sql database?
I encounter this issue when I create REST API.

I cannot tell the exact scenario, but let's say it is for a website that has category and product resources.

Each category has many products and both category and product are ordered.

I originally add an order incremental integer attribute to the resources so both collections can be displayed in correct order.

The problem with my original approach is when user drags and drops a product, a lot of other product's order attributes need to be changed. (When you move the 10th product into 1st place 10 order attributes need to be updated) This is awful for REST API and the database itself.

Is there any way to create an attribute to order product (or model the collection with other approach) so that drag and drop ordering can be done with a single (or few in scalable way) resource items changed?

The answer to the question above without any more condition is good but it would be great if it also works when user drag product from one category and drop it in other category.

答:
To avoid updates to multiple rows, don't store the exact index in the database.  Instead, store a value that is used for sorting only.  When rearranging the order, give the inserted item a value halfway between the preceding and subsequent items. Using a floating point value will give you plenty of "empty slots" between items.

For example, given three items (A, B, C) valued 1.0, 2.0, and 3.0.  The user changes the third item (C) to be second.  Update the sorting value of C to be between A and B, resulting in A, C, B valued 1.0, 1.5, 2.0, respectively.

The trade-off here is that the index must be calculated from the whole list.  Looking at just a single item, the value tells you nothing about the location of that item in the list.

ContentLicense: CC BY-SA 3.0


答:
First of all, the product and category resources that can be accessed/viewed through your REST API do not have to mirror your database tables. In particular, the order of the products is not a property of a single product resource, but on the REST API it should be a property of the collection of products. This means that it should take only a single API call to change the order of the products.

In your database, you can then either use an array index column or a column that contains a link to the next product. As this implementation detail isn't exposed on the API, you can even change your mind later on and change how the ordering is stored in the database without affecting your clients.

Title: How do I model a sortable resource in sql database?

Body:
I encounter this issue when I create REST API.

I cannot tell the exact scenario, but let's say it is for a website that has category and product resources.

Each category has many products and both category and product are ordered.

I originally add an order incremental integer attribute to the resources so both collections can be displayed in correct order.

The problem with my original approach is when user drags and drops a product, a lot of other product's order attributes need to be changed. (When you move the 10th product into 1st place 10 order attributes need to be updated) This is awful for REST API and the database itself.

Is there any way to create an attribute to order product (or model the collection with other approach) so that drag and drop ordering can be done with a single (or few in scalable way) resource items changed?

The answer to the question above without any more condition is good but it would be great if it also works when user drag product from one category and drop it in other category.


问:
Low cost exceptions implementation using metaprogramming
(preface - boring stuff, feel free to skip down to the implementation details)

I need to provide exception handling to a language I am working on. It "compiles" to a subset of C, and since I don't want to make C++ a dependency, and found the few available C libraries rather stiff and lacking, the only way is to come up with an implementation of my own.

Naturally, I'd like it to be as efficient as possible. Exception handling schemes seem to always come with overheads, in some cases drastic performance hits, in other cases - (almost) zero cost, at least when it comes to executing the code, but there are still overheads in terms of code size, memory usage and CPU time when exceptions are thrown.

Going down to assembly level in order to get control of the stack is not an option either - although I could cook up a basic compiler that targets assembly for a platform or two, I am not in the capacity to produce a professional grade compiler with all its optimizations and such that can target as many platforms as say GCC. So I am stuck at C.

Which is not necessarily a bad thing. How would one go about handling errors in C? Check return values, check array bounds, check pointers before usage, check for 0 before division - good old tried and true.

But not necessarily convenient. Exceptions are intended to be more "coarse grain", involving deep trees of operations that may fail in different configuration, making it an (understatement) arduous task to propagate such a naive error checking scheme over all the code.

Implementation details

Luckily, the language I am working on has advanced meta capabilities, one of which - context aware code that can modify itself and generate extra code. Meaning that tasks, which would otherwise be considered impossibly tedious if done manually can be automated fairly easy. Thus my exception handling strategy begins to take shape.

Functions and operators that may fail are marked by a failSafe specifier, and as such are given an implicit parameter, which is essentially an integer, where 0 means we are all good and other than zero means something went wrong. Internally, they do the good old fine grain error checking stuff, and use the integer to notify of the error, which is the actual exception throwing.

Functions can have both a unsafe and fail-safe flavor. Functions that themselves do not fail, but contain invocation of functions that may fail are also implicitly fail-safe.

A try block essentially creates that error code integer, and forces the compiler to "roll out" all the code nested in the try block, and change to the overloads which propagate the integer to every stack frame that contains code which may fail. Every explicitly fail-safe function inserts a check after its invocation, and in case of an error, the caller function does not resume but returns, to another such check all the way down to the try block, essentially unrolling the stack and collecting all the locals along the way.

It may seem that all the checks which would reveal no error can be omitted, and instead implement "escape" code path, which is entered on the first error and normally skipped if the function succeeds, but saving the states to make all those jumps will likely cost more than skipping the checks from successful operations will save, on top of the extra complexity.

Another useful feature fairly easy to implement is the ability to filter out what kind of errors you want protection against. A try block may be set to protect only against specific errors likely or known to occur in this scenario, reducing the overheads from error checking and code duplication.

A 32 bit integer outta be efficient enough to pass around, while still providing an ample 4+ billion of error codes. Negative values are reserved for language and library use, positive are for user exceptions. The exception error string itself can be retrieved from a global enum which accumulates the available exception types transparently from the user - cryptic integer values are not a concern, both the error and the exception itself are available in the form of readable text. Also no need for any extra allocations for the exception. Destructors are forbidden from throwing exceptions in order to not interfere with the stack unrolling. Lastly - nested exceptions are possible, as in there can be nested try blocks, directly or indirectly, and exceptions which are not caught propagate down through the try blocks until the root try block. The application does not "crash" if the exception is not handled, the operation attempted in the root try block simply fails and program execution continues.

Unfortunately, it will inevitably lead to some code duplication, having both unsafe and exception safe overloads, although I am not sufficiently aware of the details of "zero cost" implementations and can't really make a comparison with the amount of code they generate. The unrolling of the stack itself seems like it will be a little more efficient, since it will not involve any sort of loading of exception handling data, progress lookup and extra jumps, just call destructors if any and return to the previous stack frame. It doesn't require any extra stuff like a particular well defined ABI, no exception frames/tables/decoding, PC lookups or any of the complexity typically associated with exception handling implementations and requires no compiler support (from the C compiler that is, not the compiler for my language). It works as if you actually went and painstakingly propagated error checking over the call chain.

A couple of things to consider in the context of CPU time overhead:

My compiler does a lot of inlining, practically all trivial calls such as accessors, operators and such are eliminated, since they cost more code to execute as function calls than to execute inline. On top of that the C compiler is free to do even more inlining and optimization. Over 90% of the calls are omitted (stats from the library code that accompanies the language) even before the code reaches the C compiler. This means a lot of the error code propagation is eliminated as well, and the variable will spend most of its time on a register, requiring only a single clock cycle per check.

Error handling is typically used in resource creation and allocation, involving latent operations such as memory allocation or random memory access, which come at a dozen to dozens of cycles of latency. I expect this to mask off and mitigate the overhead somewhat.

Having outlined the design, what I am interested in the following:

is it a sound design, does it make sense?

am I missing something important?

is there room for improvement?

are there any downsides, flaws or limitations?

how does it compare to existing implementations in regards to memory and CPU time overheads and capabilities (no concrete numbers naturally)?

Since several people mentioned profiling, it is testing time, using GCC 4.9.2 -o3:

```<code>int datacount, callcount, repeatcount, limit;
int * data = 0;

void foo1();
void foo2();
void foo3();
void foo4();

bool bar1();
bool bar2();
bool bar3();
bool bar4();

void __attribute__ ((noinline)) foo1() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] += 1;
    if ((callcount < (limit / 10)) && !(callcount % 3)) foo2();
    if ((callcount < (limit / 5)) && !(callcount % 2)) foo3();
    if (callcount < limit) foo4();
    return;
}

bool __attribute__ ((noinline)) bar1() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] += 1;
    if ((callcount < (limit / 10)) && !(callcount % 3)) if (!bar2()) return false;
    if ((callcount < (limit / 5)) && !(callcount % 2)) if (!bar3()) return false;
    if (callcount < limit) if (!bar4()) return false;
    return callcount;
}

void __attribute__ ((noinline)) foo2() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] -= 1;
    if ((callcount < (limit / 10)) && !(callcount % 3)) foo3();
    if ((callcount < (limit / 5)) && !(callcount % 2)) foo4();
    if (callcount < limit) foo1();
    return;
}

bool __attribute__ ((noinline)) bar2() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] -= 1;
    if ((callcount < (limit / 10)) && !(callcount % 3)) if (!bar3()) return false;
    if ((callcount < (limit / 5)) && !(callcount % 2)) if (!bar4()) return false;
    if (callcount < limit) if (!bar1()) return false;
    return callcount;
}

void __attribute__ ((noinline)) foo3() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] *= 2;
    if ((callcount < (limit / 10)) && !(callcount % 3)) foo4();
    if ((callcount < (limit / 5)) && !(callcount % 2)) foo1();
    if (callcount < limit) foo2();
    return;
}

bool __attribute__ ((noinline)) bar3() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] *= 2;
    if ((callcount < (limit / 10)) && !(callcount % 3)) if (!bar4()) return false;
    if ((callcount < (limit / 5)) && !(callcount % 2)) if (!bar1()) return false;
    if (callcount < limit) if (!bar2()) return false;
    return callcount;
}

void __attribute__ ((noinline)) foo4() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] /= 2;
    if ((callcount < (limit / 10)) && !(callcount % 3)) foo1();
    if ((callcount < (limit / 5)) && !(callcount % 2)) foo2();
    if (callcount < limit) foo3();
    return;
}

bool __attribute__ ((noinline)) bar4() {
    ++callcount;
    for (int i = 0; i < datacount; ++i) data[i] /= 2;
    if ((callcount < (limit / 10)) && !(callcount % 3)) if (!bar1()) return false;
    if ((callcount < (limit / 5)) && !(callcount % 2)) if (!bar2()) return false;
    if (callcount < limit) if (!bar3()) return false;
    return callcount;
}
</code>```

Generated assembly:

```<code>foo4():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L2
    movq    data(%rip), %rdx
    xorl    %ecx, %ecx
.L3:
    movl    (%rdx), %eax
    addl    $1, %ecx
    addq    $4, %rdx
    movl    %eax, %esi
    shrl    $31, %esi
    addl    %esi, %eax
    sarl    %eax
    movl    %eax, -4(%rdx)
    cmpl    %ecx, datacount(%rip)
    jg  .L3
    movl    callcount(%rip), %ecx
.L2:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L4
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L10
.L4:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L5
    testb   $1, %cl
    je  .L11
.L5:
    cmpl    %esi, %ecx
    jl  .L12
    addq    $8, %rsp
    ret
.L12:
    addq    $8, %rsp
    jmp foo3()
.L11:
    call    foo2()
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L5
.L10:
    call    foo1()
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jmp .L4
foo1():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L14
    movq    data(%rip), %rax
    xorl    %edx, %edx
.L15:
    addl    $1, (%rax)
    addl    $1, %edx
    addq    $4, %rax
    cmpl    %edx, datacount(%rip)
    jg  .L15
    movl    callcount(%rip), %ecx
.L14:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L16
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L21
.L16:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L17
    testb   $1, %cl
    je  .L22
.L17:
    cmpl    %esi, %ecx
    jl  .L23
    addq    $8, %rsp
    ret
.L23:
    addq    $8, %rsp
    jmp foo4()
.L22:
    call    foo3()
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L17
.L21:
    call    foo2()
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jmp .L16
foo2():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L25
    movq    data(%rip), %rax
    xorl    %edx, %edx
.L26:
    subl    $1, (%rax)
    addl    $1, %edx
    addq    $4, %rax
    cmpl    %edx, datacount(%rip)
    jg  .L26
    movl    callcount(%rip), %ecx
.L25:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L27
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L32
.L27:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L28
    testb   $1, %cl
    je  .L33
.L28:
    cmpl    %esi, %ecx
    jl  .L34
    addq    $8, %rsp
    ret
.L34:
    addq    $8, %rsp
    jmp foo1()
.L33:
    call    foo4()
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L28
.L32:
    call    foo3()
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jmp .L27
foo3():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L36
    movq    data(%rip), %rax
    xorl    %edx, %edx
.L37:
    sall    (%rax)
    addl    $1, %edx
    addq    $4, %rax
    cmpl    %edx, datacount(%rip)
    jg  .L37
    movl    callcount(%rip), %ecx
.L36:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L38
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L43
.L38:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L39
    testb   $1, %cl
    je  .L44
.L39:
    cmpl    %esi, %ecx
    jl  .L45
    addq    $8, %rsp
    ret
.L45:
    addq    $8, %rsp
    jmp foo2()
.L44:
    call    foo1()
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L39
.L43:
    call    foo4()
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jmp .L38
bar4():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L47
    movq    data(%rip), %rdx
    xorl    %ecx, %ecx
.L48:
    movl    (%rdx), %eax
    addl    $1, %ecx
    addq    $4, %rdx
    movl    %eax, %esi
    shrl    $31, %esi
    addl    %esi, %eax
    sarl    %eax
    movl    %eax, -4(%rdx)
    cmpl    %ecx, datacount(%rip)
    jg  .L48
    movl    callcount(%rip), %ecx
.L47:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L49
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L63
.L49:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jg  .L64
.L52:
    cmpl    %esi, %ecx
    jl  .L65
.L54:
    testl   %ecx, %ecx
    setne   %al
    addq    $8, %rsp
    ret
.L64:
    testb   $1, %cl
    jne .L52
    call    bar2()
    testb   %al, %al
    je  .L53
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L52
.L65:
    call    bar3()
    testb   %al, %al
    je  .L53
    movl    callcount(%rip), %ecx
    jmp .L54
.L63:
    call    bar1()
    testb   %al, %al
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jne .L49
.L53:
    xorl    %eax, %eax
    addq    $8, %rsp
    ret
bar1():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L67
    movq    data(%rip), %rax
    xorl    %edx, %edx
.L68:
    addl    $1, (%rax)
    addl    $1, %edx
    addq    $4, %rax
    cmpl    %edx, datacount(%rip)
    jg  .L68
    movl    callcount(%rip), %ecx
.L67:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L69
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L83
.L69:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jg  .L84
.L72:
    cmpl    %esi, %ecx
    jl  .L85
.L74:
    testl   %ecx, %ecx
    setne   %al
    addq    $8, %rsp
    ret
.L84:
    testb   $1, %cl
    jne .L72
    call    bar3()
    testb   %al, %al
    je  .L73
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L72
.L85:
    call    bar4()
    testb   %al, %al
    je  .L73
    movl    callcount(%rip), %ecx
    jmp .L74
.L83:
    call    bar2()
    testb   %al, %al
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jne .L69
.L73:
    xorl    %eax, %eax
    addq    $8, %rsp
    ret
bar2():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L87
    movq    data(%rip), %rax
    xorl    %edx, %edx
.L88:
    subl    $1, (%rax)
    addl    $1, %edx
    addq    $4, %rax
    cmpl    %edx, datacount(%rip)
    jg  .L88
    movl    callcount(%rip), %ecx
.L87:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L89
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L103
.L89:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jg  .L104
.L92:
    cmpl    %esi, %ecx
    jl  .L105
.L94:
    testl   %ecx, %ecx
    setne   %al
    addq    $8, %rsp
    ret
.L104:
    testb   $1, %cl
    jne .L92
    call    bar4()
    testb   %al, %al
    je  .L93
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L92
.L105:
    call    bar1()
    testb   %al, %al
    je  .L93
    movl    callcount(%rip), %ecx
    jmp .L94
.L103:
    call    bar3()
    testb   %al, %al
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jne .L89
.L93:
    xorl    %eax, %eax
    addq    $8, %rsp
    ret
bar3():
    subq    $8, %rsp
    movl    callcount(%rip), %eax
    leal    1(%rax), %ecx
    movl    datacount(%rip), %eax
    movl    %ecx, callcount(%rip)
    testl   %eax, %eax
    jle .L107
    movq    data(%rip), %rax
    xorl    %edx, %edx
.L108:
    sall    (%rax)
    addl    $1, %edx
    addq    $4, %rax
    cmpl    %edx, datacount(%rip)
    jg  .L108
    movl    callcount(%rip), %ecx
.L107:
    movl    limit(%rip), %esi
    movl    $1717986919, %edx
    movl    %esi, %eax
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    $2, %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jle .L109
    movl    %ecx, %eax
    movl    $1431655766, %edx
    imull   %edx
    movl    %ecx, %eax
    sarl    $31, %eax
    subl    %eax, %edx
    leal    (%rdx,%rdx,2), %eax
    cmpl    %eax, %ecx
    je  .L123
.L109:
    movl    %esi, %eax
    movl    $1717986919, %edx
    imull   %edx
    movl    %esi, %eax
    sarl    $31, %eax
    sarl    %edx
    subl    %eax, %edx
    cmpl    %ecx, %edx
    jg  .L124
.L112:
    cmpl    %esi, %ecx
    jl  .L125
.L114:
    testl   %ecx, %ecx
    setne   %al
    addq    $8, %rsp
    ret
.L124:
    testb   $1, %cl
    jne .L112
    call    bar1()
    testb   %al, %al
    je  .L113
    movl    callcount(%rip), %ecx
    movl    limit(%rip), %esi
    jmp .L112
.L125:
    call    bar2()
    testb   %al, %al
    je  .L113
    movl    callcount(%rip), %ecx
    jmp .L114
.L123:
    call    bar4()
    testb   %al, %al
    movl    limit(%rip), %esi
    movl    callcount(%rip), %ecx
    jne .L109
.L113:
    xorl    %eax, %eax
    addq    $8, %rsp
    ret
</code>```

I ran the test against a input parameter data set loaded from file to avoid any potential optimizations. The ran 5 times in a row, total run time about 38 minutes.

Initially foo is considerably faster - by 13.1%, but soon enough both are equalized, for a peak of 13.5% in favor of bar in the last quarter of the test.

All in all, over the duration of the entire test, bar actually takes the lead by an advantage of 3.36%.

I made a bunch of charts, hoping to find some correlation between the input parameters and the results, but so far I don't seem to detect any.

The following set of charts shows the relation between the result and the input parameters for every test run:

Total calls are complimentary to the data size, since I aimed to provide fairly uniform running time. But it does fluctuate, from a little less than 1 second to over 25 seconds.

Here is another set of charts, in which the test runs and results are sorted from the best for foo to the best for bar, overlaid by the test input parameters. Again, no correlation between parameters and results is visible to me:

Performance vs test run time, which for some reason I forgot about:

Finally, this mess, all of the charts from the last set laid over one another without any scale, in hope to reveal a correlation:

答:
If you restrict exceptions to integer error codes, then you cannot attach extra data. When I index an array out of bounds, its nice if the error can tell me which index I used, the size of the array, and the stack trace.

If you just tell me that I got an ArrayIndexError, that's pretty much useless.

To me, your solution comes across as overthinking it. Think about how you would implement error handling in C. Typically, the return value becomes the error indication, and what would have normally been a return value becomes an out parameter. Its pretty straightforward to see how you could compile exception handling logic to manual checks and returns. You've proposed pretty much the same thing, but swapping the return value and out parameter. But that's a minor style difference.

The whole point of zero-cost exception handling is that it costs even less then these manual checks. Constantly verifying that the error indicator isn't set takes some of the performance away from your code. This is unfortunate especially because in normal behavior, the error indicators are typically rarely set. Zero-cost exception handling doesn't do anything during normal execution, but once an exception occurs, it traces up the stack looking for exception handlers. That search is actually expensive, but in theory happens rarely.


问:
Is there any reason to use "plain old data" classes?
In legacy code I occasionally see classes that are nothing but wrappers for data. something like:

```<code>class Bottle {
   int height;
   int diameter;
   Cap capType;

   getters/setters, maybe a constructor
}
</code>```

My understanding of OO is that classes are structures for data and the methods of operating on that data. This seems to preclude objects of this type. To me they are nothing more than structs and kind of defeat the purpose of OO. I don't think it's necessarily evil, though it may be a code smell.

Is there a case where such objects would be necessary? If this is used often, does it make the design suspect?

答:
This kind of classes are quite useful when you are dealing with mid-size/big applications, for some reasons:

it's quite easy to create some test
cases and ensure that data is
consistent.

it holds all kind of behaviors that
involve that information, so data bug tracking time is reduce

Using them should keep method args lightweight.

When using ORMs , this classes gives flexybility and consistency. Adding a complex attribute that's calculated based on simple information already in the class, resutls in writing one simple method. This is quite more agile and productive that having to check your database and ensure all databases are patched with new modification.

So to sum up, in my experience they usually are more useful than annoying.

ContentLicense: CC BY-SA 2.5


问:
Client-side classes structure in UML project
I and two university colleagues of mine are designing a simple CMS software for a university exam using UML. Such software just needs to deal with sending an article, assigning an article for review, sending a review and scoring an article. Our solution expects a 3-tier client-server architecture, with tiny clients requesting services and a server responding to requests by interfacing with a DBMS (persistent data) and a SMTP server (e-mail notifications).

I'm at a point where I can't decide how to structure my client-side classes. I figured out a set of boundary classes representing single services and contain related methods (authentication, submit paper, review paper...), and a single control class which roles are requesting connection to the server and the creation of a new session, and it contains the methods to actually send messages to the server.

This is according to the single responsibility principle that states that any class should be responsible over a single functionality of the software: so, I have a class for signing up/logging in, one to submit an article, and so on, and then the control class that receives requests from other boundary classes and send messages to the server.

On the other hand, I was told by other people I asked that I could even get rid of my client-side controller class and give boundary classes methods to directly send request messages to the server. This still seems legit to me: boundary classes only send requests according to the particular service they were supposed to provide to the user.

Question is: is having a control class in my client application useful, redundant, or wrong at all? How can I improve my classes structure?

答:
Question is: is having a control class in my client application useful, redundant, or wrong at all? How can I improve my classes structure?

It is useful. Your controller, ctrClientManager, encapsulates the messaging over the socket; it is responsible for creating the socket, the message streams and other message-related plumbing. Every boundary class needs this functionality and it would lead to code duplication if every boundary class would directly send messages.

It improves maintainability, because if something needs to be changed generically in the communication between client and server, you can do that at a central place (the controller) instead of adapting each and every boundary class.

It improves reliability, because the chance that there is a bug in one central piece of code is less than the chance that there is a bug in one of the many copies of the same code.

By the way, it is recommended to apply the MVC pattern, where each view (boundary class) has its own controller, to control the user interaction. In addition, you should have the central messaging controller, called ctrClientManager in your example.

OwnerDisplayName: Giorgio Liggio


问:
How to avoid violating the SRP in a class to manage caching?
Note: The code sample is written in c#, but that shouldn't matter. I've put c# as a tag because I can't find a more appropiate one. This is about the code structure.

I'm reading Clean Code and trying to become a better programmer.

I often find myself struggling to follow the Single Responsibility Principle (classes and functions should do only one thing), specially in functions. Maybe my problem is that "one thing" is not well-defined, but still...

An example: I have a list of Fluffies in a database. We don't care what a Fluffy is. I want a class to recover fluffies. However, fluffies can change according to some logic. Depending on some logic, this class will return the data from cache or get the latest from the database.
We could say that it manages fluffies, and that is one thing.
To make it simple, let's say loaded data is good for an hour, and then it must be reloaded.

```<code>class FluffiesManager
{
    private Fluffies m_Cache;
    private DateTime m_NextReload = DateTime.MinValue;
    // ...
    public Fluffies GetFluffies()
    {
        if (NeedsReload())
            LoadFluffies();

        return m_Cache;
    }

    private NeedsReload()
    {
        return (m_NextReload < DateTime.Now);
    }

    private void LoadFluffies()
    {
        GetFluffiesFromDb();
        UpdateNextLoad();
    }

    private void UpdateNextLoad()
    {
        m_NextReload = DatTime.Now + TimeSpan.FromHours(1);
    }
    // ...
}
</code>```

GetFluffies() seems ok to me. The user asks for some fluffies, we provide them. Going to recover them from the DB if needed, but that could be considered a part of getting the fluffies (of course, that's somewhat subjective).

NeedsReload() seems right, too. Checks if we need to reload the fluffies.
UpdateNextLoad is fine. Updates the time for the next reload. that's definitely one single thing.

However, I feel what LoadFluffies() do can't be described as one single thing. It's getting the data from the Database, and it's scheduling the next reload. It's hard to argue that calculating the time for the next reload is part of getting the data. However, I can't find a better way to do it (renaming the function to LoadFluffiesAndScheduleNextLoad may be better, but it just makes the problem more obvious).

Is there an elegant solution to really write this class according to the SRP?
Am I being too pedantic?

Or maybe my class isn't really doing just one thing?

答:
One general-purpose mechanism for handling a broad range of cases where  we want to add value without violating the Single Responsibility Principle is the Decorator Pattern.

This mechanism is suitable when the adding of value can be done without changing the existing interface, which is typically what caches do.

The beautiful thing with this mechanism is that it takes the handling out of the code and into the design.

Specifically:

We begin by declaring an interface for what we want to do; in your case, a FluffiesProvider.

Then we write a class which implements FluffiesProvider and offers the fundamental functionality, in your case a DatabaseFluffiesProvider which reads the fluffies from the database without worrying at all about caching.

Then we write a decorator of FluffiesProvider which does nothing but caching and has no idea where the fluffies come from.

Finally, we wire them together as one, so the final FluffiesProvider that we end up with is a cached database fluffies provider.

Here is some example code:

```<code>/// Provides Fluffies.
interface FluffiesProvider
{
    Fluffies GetFluffies();
}

/// Implements FluffiesProvider using a database.
class DatabaseFluffiesProvider : FluffiesProvider
{
    public override Fluffies GetFluffies()
    {
        ... load fluffies from DB ...
        (the entire implementation of "GetFluffiesFromDb()" goes here.)
    }
}

/// Decorates FluffiesProvider to add caching.
class CachingFluffiesProvider : FluffiesProvider
{
    private FluffiesProvider decoree;
    private DateTime m_NextReload = DateTime.MinValue;
    private Fluffies m_Cache;

    public CachingFluffiesProvider( FluffiesProvider decoree )
    {
        Assert( decoree != null );
        this.decoree = decoree;
    }

    public override Fluffies GetFluffies()
    {
        if( DateTime.Now >= m_NextReload )
        {
             m_Cache = decoree.GetFluffies();
             m_NextReload = DatTime.Now + TimeSpan.FromHours(1);
        }
        return m_Cache;
    }
}
</code>```

and here is the instantiation and wiring together of the classes:

```<code>FluffiesProvider provider = new DatabaseFluffiesProvider();
provider = new CachingFluffiesProvider( provider );
...go ahead and use provider...
</code>```

OwnerDisplayName: raven

Body:
One general-purpose mechanism for handling a broad range of cases where  we want to add value without violating the Single Responsibility Principle is the Decorator Pattern.

This mechanism is suitable when the adding of value can be done without changing the existing interface, which is typically what caches do.

The beautiful thing with this mechanism is that it takes the handling out of the code and into the design.

Specifically:

We begin by declaring an interface for what we want to do; in your case, a FluffiesProvider.

Then we write a class which implements FluffiesProvider and offers the fundamental functionality, in your case a DatabaseFluffiesProvider which reads the fluffies from the database without worrying at all about caching.

Then we write a decorator of FluffiesProvider which does nothing but caching and has no idea where the fluffies come from.

Finally, we wire them together as one, so the final FluffiesProvider that we end up with is a cached database fluffies provider.

Here is some example code:

/// Provides Fluffies.
interface FluffiesProvider
{
    Fluffies GetFluffies();
}

/// Implements FluffiesProvider using a database.
class DatabaseFluffiesProvider : FluffiesProvider
{
    public override Fluffies GetFluffies()
    {
        ... load fluffies from DB ...
        (the entire implementation of "GetFluffiesFromDb()" goes here.)
    }
}

/// Decorates FluffiesProvider to add caching.
class CachingFluffiesProvider : FluffiesProvider
{
    private FluffiesProvider decoree;
    private DateTime m_NextReload = DateTime.MinValue;
    private Fluffies m_Cache;

    public CachingFluffiesProvider( FluffiesProvider decoree )
    {
        Assert( decoree != null );
        this.decoree = decoree;
    }

    public override Fluffies GetFluffies()
    {
        if( DateTime.Now >= m_NextReload )
        {
             m_Cache = decoree.GetFluffies();
             m_NextReload = DatTime.Now + TimeSpan.FromHours(1);
        }
        return m_Cache;
    }
}

and here is the instantiation and wiring together of the classes:

FluffiesProvider provider = new DatabaseFluffiesProvider();
provider = new CachingFluffiesProvider( provider );
...go ahead and use provider...

ContentLicense: CC BY-SA 4.0


答:
Your instincts are correct. Your class, small though it may be, is doing too much. You should separate the timed refresh caching logic into a completely generic class. Then create a specific instance of that class for managing Fluffies, something like this (not compiled, working code is left as an exercise for the reader):

```<code>public class TimedRefreshCache<T> {
    T m_Value;
    DateTime m_NextLoadTime;
    Func<T> m_producer();
    public CacheManager(Func<T> T producer, Interval timeBetweenLoads) {
          m_nextLoadTime = INFINITE_PAST;
          m_producer = producer;
    }
    public T Value {
        get {
            if (m_NextLoadTime < DateTime.Now) {
                m_Value = m_Producer();
                m_NextLoadTime = ...;
            }
            return m_Value;
        }
    }
}

public class FluffyCache {
    private TimedRefreshCache m_Cache
        = new TimedRefreshCache<Fluffy>(GetFluffiesFromDb, interval);
    private Fluffy GetFluffiesFromDb() { ... }
    public Fluffy Value { get { return m_Cache.Value; } }
}
</code>```

An added advantage is that it is now very easy to test TimedRefreshCache.

Body:
Your instincts are correct. Your class, small though it may be, is doing too much. You should separate the timed refresh caching logic into a completely generic class. Then create a specific instance of that class for managing Fluffies, something like this (not compiled, working code is left as an exercise for the reader):

public class TimedRefreshCache<T> {
    T m_Value;
    DateTime m_NextLoadTime;
    Func<T> m_producer();
    public CacheManager(Func<T> T producer, Interval timeBetweenLoads) {
          m_nextLoadTime = INFINITE_PAST;
          m_producer = producer;
    }
    public T Value {
        get {
            if (m_NextLoadTime < DateTime.Now) {
                m_Value = m_Producer();
                m_NextLoadTime = ...;
            }
            return m_Value;
        }
    }
}

public class FluffyCache {
    private TimedRefreshCache m_Cache
        = new TimedRefreshCache<Fluffy>(GetFluffiesFromDb, interval);
    private Fluffy GetFluffiesFromDb() { ... }
    public Fluffy Value { get { return m_Cache.Value; } }
}

An added advantage is that it is now very easy to test TimedRefreshCache.


问:
Communicating to an Object from another without coupling in java?
So I have a Person object, and a GumballMachine object. The behavior I'm searching for is, in the intent to avoid unnecessary coupling, have the method insertCoin() called from within the Person object, which will then call the insertCoin() within the GumballMachine to receive a Gumball.

What is a proper design-pattern, or solution that avoids coupling, and keeps these two objects as oblivious to each other as possible while having a type of "Bridge" between them?

答:
Create an interface, say Coinable, with a single insertCoin() method.

```<code>interface Coinable {
    insertCoin();
}
</code>```

Then you can make n Object(s) that implement Coinable (and, some may delegate). And by programming to the interface, you can use various instances interchangeably.

Body:
Create an interface, say Coinable, with a single insertCoin() method.

interface Coinable {
    insertCoin();
}

Then you can make n Object(s) that implement Coinable (and, some may delegate). And by programming to the interface, you can use various instances interchangeably.

OwnerDisplayName: Elliott Frisch


答:
To expand upon what Elliot was saying.

Your interface that returns true if the coin was accepted.

```<code>public interface Coinable {
    public boolean insertCoin();
}
</code>```

Some person class that has some coins to insert into a Coinable interface.

```<code>public class Person {
    private int coins;

    public Person(int coins) {
        this.coins = coins;
    }

    public void insertCoin(Coinable cn) {
        if (this.coins <= 0) {
            System.out.println("You have no coins");
        } else {
            boolean coinAccepted = cn.insertCoin();
            if (coinAccepted) {
                coins--;
            }
        }
    }
}
</code>```

And your GumballMachine that implements the Coinable interface.

```<code>class GumballMachine implements Coinable {
    private int gumBalls;

    public GumballMachine(int gumBalls) {
        this.gumBalls = gumBalls;
    }

    @Override
    public boolean insertCoin() {
        if (gumBalls <= 0) {
            System.out.println("There are no gumballs left");
            return false;
        } else {
            System.out.println("A gumball was dispensed!");
            gumBalls--;
            return true;
        }
    }
}
</code>```

And an example of how all this works

```<code>public static void main(String[] args) {
    Person p = new Person(3); // 3 coins
    GumballMachine g = new GumballMachine(2); // 2 gumballs

    p.insertCoin(g);
    p.insertCoin(g);
    p.insertCoin(g); // out of gumballs

    g = new GumballMachine(2); // refill the machine, still have 1 coin
    p.insertCoin(g);
    p.insertCoin(g);
}
</code>```

Output

```<code>A gumball was dispensed!
A gumball was dispensed!
There are no gumballs left
A gumball was dispensed!
You have no coins
</code>```

Title: Communicating to an Object from another without coupling in java?

Body:
So I have a Person object, and a GumballMachine object. The behavior I'm searching for is, in the intent to avoid unnecessary coupling, have the method insertCoin() called from within the Person object, which will then call the insertCoin() within the GumballMachine to receive a Gumball.

What is a proper design-pattern, or solution that avoids coupling, and keeps these two objects as oblivious to each other as possible while having a type of "Bridge" between them?

Body:
To expand upon what Elliot was saying.

Your interface that returns true if the coin was accepted.

public interface Coinable {
    public boolean insertCoin();
}

Some person class that has some coins to insert into a Coinable interface.

public class Person {
    private int coins;

    public Person(int coins) {
        this.coins = coins;
    }

    public void insertCoin(Coinable cn) {
        if (this.coins <= 0) {
            System.out.println("You have no coins");
        } else {
            boolean coinAccepted = cn.insertCoin();
            if (coinAccepted) {
                coins--;
            }
        }
    }
}

And your GumballMachine that implements the Coinable interface.

class GumballMachine implements Coinable {
    private int gumBalls;

    public GumballMachine(int gumBalls) {
        this.gumBalls = gumBalls;
    }

    @Override
    public boolean insertCoin() {
        if (gumBalls <= 0) {
            System.out.println("There are no gumballs left");
            return false;
        } else {
            System.out.println("A gumball was dispensed!");
            gumBalls--;
            return true;
        }
    }
}

And an example of how all this works

public static void main(String[] args) {
    Person p = new Person(3); // 3 coins
    GumballMachine g = new GumballMachine(2); // 2 gumballs

    p.insertCoin(g);
    p.insertCoin(g);
    p.insertCoin(g); // out of gumballs

    g = new GumballMachine(2); // refill the machine, still have 1 coin
    p.insertCoin(g);
    p.insertCoin(g);
}

Output

A gumball was dispensed!
A gumball was dispensed!
There are no gumballs left
A gumball was dispensed!
You have no coins


问:
Should every member of a team use the same IDE?
Do you think it makes sense to enforce that every member of a team must use the same IDE?

For instance all engineers that are already on the team use IDE X. Two new engineers come and want to use IDE Y instead because that's what they have been using for several years now.

Do you have any experience with "mixed IDE" teams? If so what is it?

答:
I don't think everyone needs to have the "same" IDE, but it would be nice that everyone had a "supported" IDE.

For example, if your IDE is integrated into the code review process as far as commenting and updating code goes, then it would make sense for everyone to be on a supported platform.

If your company is using a collaborative environment such as Rational Team Concert and one or two guys want to use an unsupported IDE (or a different version) while everyone else uses compatible ones, then life may be difficult for the people who have chosen to be outside of the support loop.


问:
Object Oriented Design Question
I have long experience in procedural world and been programming/maintaining OO code in various languages too. Now getting into OO design and feeling the pains of identifying objects from scratch. Been reading several books, articles, etc. on OO. Often times they stop with Person, Employee examples. Identifying and doing it the right way in a real world projects raises several questions.

This is sort of a follow up question from my earlier design review question. Say, I have an object like below:

```<code>public class AddressRecord {
  protected long RecordID;
  protected String AddressLine1;
  protected String AddressLine2;
  protected String City;
  protected String State;
  protected String PostalCode;
  protected String Country;
  protected String FirstName;
  protected String LastName;
  protected String FullName;
  protected String PhoneNumber;
  protected String EmailAddress;
  protected String CompanyName;
  ..
  /* related to my question below */
  public String extractXml() {}
  public HashMap extractHash() {}
  public String extractJson() {}
  ...
}
</code>```

Now, I want to extract the field/values into a hashtable or a XML (proprietary format) or JSON structure without resorting to any libraries like JAXB. I will write some methods (for e.g., extractXml, extrachHash, extractJson) to extract specific fields into the target format.

My question is where should such extraction/conversion methods be? Based on some exposure to OO design books and advice, I was assuming I could have these methods right inside this class.

@Vladislav mentioned that they should actually be outside, like in the controller. I kind of get it, but I am curious to know why? Also, if I want to isolate this extraction logic from the controller code, can I create a class doing just that? Like,

```<code>public class AddressRecordXml {

   public static String extractXml(AddressRecord rec)
   {

   }

   ...
}
</code>```

and then use it in the controller as,

```<code>...
AddressRecord rec = new AddressRecord();
String xmlStr = AddressRecordXml(rec);
...
String resp = transport.process(xmlStr);
...
</code>```

Note: I know there are libraries like JAXB etc to help serialize objects to XML etc. I cannot use those, yet. I am working with Java 1.4 inside an old Sybase EAServer (main programming language being PowerBuilder) and it puts a lots of restrictions. Same reason for HashMap, no Generics etc.

答:
There is a clear separation of concerns:

1) You have your Data (DTO) AddressRecord

2) You have the need for representing the model in several ways

That said, there are (at least) two objects needed:
(1) the DTO itself
(2) an output module

The typical/orthodox OO way of implementing this is via strategy pattern.
The mechanism of handling the different outputformats is abstracted away in an interface implementation - for the sake of the example, let's name it AddressWriter, with one simple method write(). The concrete implementation of the interface encapsules the mechanism. The machanism of extraction, converting to JSON/XML whatever is paced there. The DTO doesn't need to know of JSON or XML, nor does it have to know which values are for which format interesting. It is not its concern.

The advantage is clear: By abstraction ou gain freedom to implement different formats without changing or breaking existing code: You only need another mechanism implementation.

You could call it highly acamdemic - I call it proper design.

Title: Object Oriented Design Question


问:
How do Symbol Tables, Lexers and Parsers work together in a modern design?
I'm working on creating my own scripting language for learning purposes. I've been reading through the Dragon Book and some things are a little unclear to me regarding the Symbol Table as well as where the strings that constitute an identifier actually reside and the ownership. Most of this confusion I think is due to the book using older techniques whereas I'm looking to use C++11.

As I understand it:

The SymbolTable would be a hash_map of some kind using the lexemes as the keys. I.e. string types. I've determined on my own that it's value would then be a tuple containing the SYMBOL_TYPE and a pointer/reference/lookup to a second array that contains the additional info needed for this SYMBOL_TYPE.

I.e. an entry in the SymbolTable could be <SYMBOL_TYPE::VARIABLE,3> which would mean that the Variables array at index 3 would feature this variables type + value + attributes.

I would then do the same for other identifiers like procedures etc.

The Lexer goes through characters until it's produced the longest possible lexeme each time the next Token is requestsed.

Question 1: Where do these pre-existing lexemes reside? For example, if the symbol table is pre-populated with keywords, punctuation, operators etc, who pre-populates it? Does the SymbolTable itself pre-populate itself with a list of keywords + punctuation + operators? Would I then just attempt to match each entry in the symbol table (starting with longest first)?

Question 2: When the Lexer has produced a token, does it add new identifiers to the symbol table? How does it know if this should be a SYMBOL_TYPE::FUNCTION or SYMBOL_TYPE:::VARIABLE? Or does it just populate it with SYMBOL_TYPE::ID and allow the Parser to later update the entry once it's determined the identifiers usage?

I think it can't be left to the Parser because when a new scope is started by the occurrence of a {, the Lexer would need to add a new SymbolTable to a stack otherwise the Token it returns to the Parser would point to the wrong entry... But then the Lexer can't be expected to also add the type and value information to the Variables or Procedures arrays.

The Parser requests each Token in turn from the Lexer.

Question 3: What exactly is needed in this Token type that's returned? At the moment it's just the SYMBOL_TYPE + the index into the SymbolTable. The SymbolTable then links to the corresponding additional list for that SYMBOL_TYPE. But should it be something other than SYMBOL_TYPE, like TOKEN_TYPE and allow the Parser to add to the SymbolTable rather than the Lexer? Because the Lexer can't determine whether an identifier is a variable or procedure. Because the Lexer needs to add them due to different scopes, does the Parser then discard what the Lexer added and add it's own?

I'm confused about who owns the creation and management of the SymbolTable and whether the identifiers in it should be the same as what's passed between the Lexer and Parser.

It seems to me like it would be simpler to have the Lexer only return Tokens which determine whether it's a known keyword/operator/punctuation (each with it's own TOKEN_TYPE) + the string that makes it up (if needed) and the Parser then adds entries to the SymbolTable and subsequent arrays (like the Variables array) when it needs to. It would also see a { and add a new SymbolTable to the stack when neccessary.

Am I mis-interpreting the goal of a SymbolTable?

答:
Usually, the symbol table does not include all strings of the source code. Instead, the symbol table represents the static environment of a program, i.e. the visible variables and possibly their types. During parsing and compilation, the current state of the symbol table indicates which variables are visible.

Certain languages such as C++ can have symbols of different types – variables and type names. These would usually be kept in different symbol tables. However, this is a fairly rare case. Most implementations only track variable names in a symbol table.

As an example, assume this C-like program:

```<code>1: int i = 42;
2: {
3:   char c = 'a';
4:   print_int_char(i, c);
5: }
</code>```

The symbol table starts with a print_int_char function: { "print_int_char": void (*) (int, char) }. Let's assume that this symbol table maps names to types. During parsing, the state is changed as follows:

{ "print_int_char": void (*) (int, char), "i": int } – the i symbol was added.

{ "print_int_char": void (*) (int, char), "i": int } – a nested scope is entered.

{ "print_int_char": void (*) (int, char), "c": char, "i": int } – the c symbol was added.

{ "print_int_char": void (*) (int, char), "c": char, "i": int } – the symbols print_int_char, c, and i are retrieved from the symbol table to facilitate type checking.

{ "print_int_char": void (*) (int, char), "i": int } – the nested scope is left, all symbols defined in that scope are discarded.

Operators, keywords, and syntax fragments such as curly braces are not part of the symbol table, which is used to implement language semantics, such as lexical scopes or static typing. When a variable is encountered that is not found in the symbol table, we can immediately issue a compiler error.

These properties make symbol tables particularly popular in single-pass languages such as C, but when every symbol must be found in the symbol table at parse time, we cannot have functions without a pre-declaration. Therefore, many more modern languages defer symbol table construction until the whole compilation unit has been parsed, and then do a second pass to assert that all symbols can be resolved and to do type checking.

Nested scopes can be implemented with two strategies:

The symbol table is copied when a new scope is entered. When the scope is left, the old symbol table is restored.

The symbol table is a linked list or stack of tables. During symbol resolution, the scope chain is walked upwards until the symbol is found, or the end of the list is reached. Each scope chain entry will only contain the symbols that were defined in that scope. Since it is more elegant and avoids unnecessary copies, this approach is generally more common.

How is the type known when a symbol is added?

Some languages do not have static type information, e.g. Python. Here, a symbol table would only track existence of symbols.

In other languages such as C, the precise type is always known at declaration: the statement int x; declares a variable x of type int.

In languages such as ML/OCaml/Haskell with sophisticated type inference rules, the type of a variable is not immediately known at declaration. However, the type is guaranteed to be known at the end of the compilation unit. Here, the symbol table would map variable names to globally unique type variables that will be assigned once their concrete types are known. There might be another table mapping type variables to types. Read up on Algorithm W to learn more about this.

The symbol table is used as part of semantic analysis and not as part of lexical analysis. However, some languages or implementations might mix these. In particular, C was designed so that the whole compilation incl. parsing, semantic analysis (e.g. type checking) and code generation could happen in a single pass. The grammar of C++ requires that a symbol table is available during parsing to disambiguate types from variables. In other languages, it's not necessary that the parser creates a symbol table. Instead, the table could be generated by a later compiler pass from the resulting abstract syntax tree.

A lexer (if present) would never have to touch the symbol table. Lexers are only used as a simplification for parsers, but are never a necessary part of a language implementation. A lexer in a C-like language would usually return tokens such as <KW_FOR> or <IDENT:int> or <IDENT:i> rather than <TYPENAME:int> or <VARIABLE:i> which are then further categorized by a parser according to their position in a syntax. As an example why this is necessary, consider:

```<code>typedef int III;
III III = 42;
printf("%d", III);
</code>```

Here, the symbol III refers to both a type and a variable, but these are in two different namespaces (= two different symbol tables). However, each reference to this symbol is unambiguous due to its syntactic context.

Body:
Usually, the symbol table does not include all strings of the source code. Instead, the symbol table represents the static environment of a program, i.e. the visible variables and possibly their types. During parsing and compilation, the current state of the symbol table indicates which variables are visible.

Certain languages such as C++ can have symbols of different types – variables and type names. These would usually be kept in different symbol tables. However, this is a fairly rare case. Most implementations only track variable names in a symbol table.

As an example, assume this C-like program:

1: int i = 42;
2: {
3:   char c = 'a';
4:   print_int_char(i, c);
5: }

The symbol table starts with a print_int_char function: { "print_int_char": void (*) (int, char) }. Let's assume that this symbol table maps names to types. During parsing, the state is changed as follows:

{ "print_int_char": void (*) (int, char), "i": int } – the i symbol was added.

{ "print_int_char": void (*) (int, char), "i": int } – a nested scope is entered.

{ "print_int_char": void (*) (int, char), "c": char, "i": int } – the c symbol was added.

{ "print_int_char": void (*) (int, char), "c": char, "i": int } – the symbols print_int_char, c, and i are retrieved from the symbol table to facilitate type checking.

{ "print_int_char": void (*) (int, char), "i": int } – the nested scope is left, all symbols defined in that scope are discarded.

Operators, keywords, and syntax fragments such as curly braces are not part of the symbol table, which is used to implement language semantics, such as lexical scopes or static typing. When a variable is encountered that is not found in the symbol table, we can immediately issue a compiler error.

These properties make symbol tables particularly popular in single-pass languages such as C, but when every symbol must be found in the symbol table at parse time, we cannot have functions without a pre-declaration. Therefore, many more modern languages defer symbol table construction until the whole compilation unit has been parsed, and then do a second pass to assert that all symbols can be resolved and to do type checking.

Nested scopes can be implemented with two strategies:

The symbol table is copied when a new scope is entered. When the scope is left, the old symbol table is restored.

The symbol table is a linked list or stack of tables. During symbol resolution, the scope chain is walked upwards until the symbol is found, or the end of the list is reached. Each scope chain entry will only contain the symbols that were defined in that scope. Since it is more elegant and avoids unnecessary copies, this approach is generally more common.

How is the type known when a symbol is added?

Some languages do not have static type information, e.g. Python. Here, a symbol table would only track existence of symbols.

In other languages such as C, the precise type is always known at declaration: the statement int x; declares a variable x of type int.

In languages such as ML/OCaml/Haskell with sophisticated type inference rules, the type of a variable is not immediately known at declaration. However, the type is guaranteed to be known at the end of the compilation unit. Here, the symbol table would map variable names to globally unique type variables that will be assigned once their concrete types are known. There might be another table mapping type variables to types. Read up on Algorithm W to learn more about this.

The symbol table is used as part of semantic analysis and not as part of lexical analysis. However, some languages or implementations might mix these. In particular, C was designed so that the whole compilation incl. parsing, semantic analysis (e.g. type checking) and code generation could happen in a single pass. The grammar of C++ requires that a symbol table is available during parsing to disambiguate types from variables. In other languages, it's not necessary that the parser creates a symbol table. Instead, the table could be generated by a later compiler pass from the resulting abstract syntax tree.

A lexer (if present) would never have to touch the symbol table. Lexers are only used as a simplification for parsers, but are never a necessary part of a language implementation. A lexer in a C-like language would usually return tokens such as <KW_FOR> or <IDENT:int> or <IDENT:i> rather than <TYPENAME:int> or <VARIABLE:i> which are then further categorized by a parser according to their position in a syntax. As an example why this is necessary, consider:

typedef int III;
III III = 42;
printf("%d", III);

Here, the symbol III refers to both a type and a variable, but these are in two different namespaces (= two different symbol tables). However, each reference to this symbol is unambiguous due to its syntactic context.


问:
What are the drawbacks of sending XML to browsers and let them apply XSLT?
Context

Working as a freelance developer, I often made websites completely based on XSLT. In other words, on every request, an XML file is generated, containing everything we need to know about the page content: the name of the user currently logged in, the top menu entries, if this menu is dynamic/configurable, the text to display in a specific area of the page, etc. Then XSL process (caches, etc.) it to HTML/XHTML page to send to the browser.

It has a good point to make it easier to create small-scale websites, especially with PHP. It is a sort of template engine, but which I prefer to other template engines because it's much more powerful than most of template engines, and because I know it better and like it. It is also possible, when need, to give an access to raw XML data on demand for an automated access, without the need to create separate APIs.

Of course, it will fail completely on any medium-scale or large-scale website, since, even with good caching techniques, XSL still degrades overall website performance and requires more CPU serverside.

Question

Modern browsers have the ability to take an XML file and to transform it with an associated XSL file declared in XML like <?xml-stylesheet href="demo.xslt" type="text/xsl"?>. Firefox 3 can do it. Internet Explorer 8 can do it too.

It means that it is possible to migrate XSL processing from the server to the client side for 50% of users (according on browser statistics on several websites where I may want to implement this). It means that those 50% of users will receive only the XML file at each request, thus reducing their and server's bandwidth (XML file being much shorter than its processed HTML analog), and reducing server's CPU usage.

What are the drawbacks of this technique?

I thought about several ones, but it doesn't apply in this situation:

Difficult implementation and the need to choose, based on the browser request, when to send raw XML and when to transform it to HTML instead. Obviously, the system will not be much more difficult then the actual one. The only change to make is to add XSL file link to every XML, and to add a browser check.

More IO and bandwidth usage, since the XSLT file will be downloaded by the browsers, instead of being cached by the server. I don't think it will be a problem, since XSLT file will be cached by the browsers (like images, or CSS, or JavaScript files are cached actually).

Possibly some problems on client side, like maybe problems when saving a page in some browsers.

Difficulty to debug code: it is impossible to obtain an HTML source the browser is actually using, since the only displayed source is the downloaded XML. On the other hand, I rarely go look at HTML code on client side, and in most cases, it is unusable directly (whitespace being removed).

答:
There's no reason why doing this serverside should not scale as well as generating HTML directly. There's also not much reason for a big constant overhead in comparison to PHP. Appearently there are XSLT > JVM / CLR compilers and I suppose you could even translate it to native code.

However the idea of transporting data and presentation structure seperately is good as such.

It can save a lot of bandwidth and even server performance. But pomeL has mentioned a number of points.

For proper support accross browsers, xslt.js could help.

Personally, I am no fan of XML, so I would use JSON instead and a JS template engine, that will execute in the browser. Or some sort of template engine, that converts template markup into executable js on the server side, which is used for rendering on the client side.

JavaScript is reasonably fast and available virtually everywhere. JSON and JS are far more compact than XML and XSLT.


问:
Is there anything that can be done with recursion that can't be done with loops?
There are times where using recursion is better than using a loop, and times where using a loop is better than using recursion. Choosing the "right" one can save resources and/or result in fewer lines of code.

Are there any cases where a task can only be done using recursion, rather than a loop?

答:
No.

Getting down to the very basics of the necessary minimums in order to compute, you just need to be able to loop (this alone isn't sufficient, but rather is a necessary component). It doesn't matter how.

Any programming language that can implement a Turing Machine, is called Turing complete.  And there are lots of languages that are turing complete.

My favorite language in the way down there of "that actually works?" Turing completeness is that of FRACTRAN, which is Turing complete.  It has one loop structure, and you can implement a Turing machine in it.  Thus, anything that is computable, can be implemented in a language that doesn't have recursion.  Therefore, there is nothing that recursion can give you in terms of computability that simple looping cannot.

This really boils down to a few points:

Anything that is computable is computable on a Turing machine

Any language that can implement a Turing machine (called Turing complete), can compute anything that any other language can

Since there are Turing machines in languages that lack recursion (and there are others that only have recursion when you get into some of the other esolangs), it is necessarily true that there is nothing that you can do with recursion that you cannot do with a loop (and nothing you can do with a loop that you can't do with recursion).

This isn't to say that there are some problem classes that more easily be thought of with recursion rather than with looping, or with looping rather than with recursion. However, these too tools are equally powerful.

And while I took this to the 'esolang' extreme (mostly because you can find things that are Turing complete and implemented in rather strange ways), this doesn't mean that the esolangs are by any means optional.  There is a whole list of things that are accidentally Turing complete including Magic the Gathering, Sendmail, MediaWiki templates, and the Scala type system.  Many of these are far from optimal when it comes to actually doing anything practical, its just that you can compute anything that is computable using these tools.

This equivalence can get particularly interesting when you get into a particular type of recursion known as tail call.

If you have, lets say, a factorial method written as:

int fact(int n) {
    return fact(n, 1);
}

int fact(int n, int accum) {
    if(n == 0) { return 1; }
    if(n == 1) { return accum; }
    return fact(n-1, n * accum);
}
```

This type of recursion will be rewritten as a loop - no stack used.  Such approaches are indeed often more elegant and easier to understand than the equivalent loop being written, but again, for every recursive call there can be an equivalent loop written and for every loop there can be a recursive call written.

There are also times where converting the simple loop into a tail call recursive call can be convoluted and more difficult to understand.

If you want to get into the theory side of it, see the Church Turing thesis.  You may also find the church-turing-thesis on CS.SE to be useful.

Body:
No.

Getting down to the very basics of the necessary minimums in order to compute, you just need to be able to loop (this alone isn't sufficient, but rather is a necessary component). It doesn't matter how.

Any programming language that can implement a Turing Machine, is called Turing complete.  And there are lots of languages that are turing complete.

My favorite language in the way down there of "that actually works?" Turing completeness is that of FRACTRAN, which is Turing complete.  It has one loop structure, and you can implement a Turing machine in it.  Thus, anything that is computable, can be implemented in a language that doesn't have recursion.  Therefore, there is nothing that recursion can give you in terms of computability that simple looping cannot.

This really boils down to a few points:

Anything that is computable is computable on a Turing machine

Any language that can implement a Turing machine (called Turing complete), can compute anything that any other language can

Since there are Turing machines in languages that lack recursion (and there are others that only have recursion when you get into some of the other esolangs), it is necessarily true that there is nothing that you can do with recursion that you cannot do with a loop (and nothing you can do with a loop that you can't do with recursion).

This isn't to say that there are some problem classes that more easily be thought of with recursion rather than with looping, or with looping rather than with recursion. However, these too tools are equally powerful.

And while I took this to the 'esolang' extreme (mostly because you can find things that are Turing complete and implemented in rather strange ways), this doesn't mean that the esolangs are by any means optional.  There is a whole list of things that are accidentally Turing complete including Magic the Gathering, Sendmail, MediaWiki templates, and the Scala type system.  Many of these are far from optimal when it comes to actually doing anything practical, its just that you can compute anything that is computable using these tools.

This equivalence can get particularly interesting when you get into a particular type of recursion known as tail call.

If you have, lets say, a factorial method written as:

int fact(int n) {
    return fact(n, 1);
}

int fact(int n, int accum) {
    if(n == 0) { return 1; }
    if(n == 1) { return accum; }
    return fact(n-1, n * accum);
}

This type of recursion will be rewritten as a loop - no stack used.  Such approaches are indeed often more elegant and easier to understand than the equivalent loop being written, but again, for every recursive call there can be an equivalent loop written and for every loop there can be a recursive call written.

There are also times where converting the simple loop into a tail call recursive call can be convoluted and more difficult to understand.

If you want to get into the theory side of it, see the Church Turing thesis.  You may also find the church-turing-thesis on CS.SE to be useful.


答:
Yes and no. Ultimately, there's nothing recursion can compute that looping can't, but looping takes a lot more plumbing. Therefore, the one thing recursion can do that loops can't is make some tasks super easy.

Take walking a tree. Walking a tree with recursion is stupid-easy. It's the most natural thing in the world. Walking a tree with loops is a lot less straightforward. You have to maintain a stack or some other data structure to keep track of what you've done.

Often, the recursive solution to a problem is prettier. That's a technical term, and it matters.

Title: Is there anything that can be done with recursion that can't be done with loops?

Body:
There are times where using recursion is better than using a loop, and times where using a loop is better than using recursion. Choosing the "right" one can save resources and/or result in fewer lines of code.

Are there any cases where a task can only be done using recursion, rather than a loop?


问:
Are there any actual examples of profitable programmer's "worker's cooperatives"?
http://en.wikipedia.org/wiki/Worker_cooperative

I'm curious whether there are, anywhere in the world, worker's cooperatives that center on a technology business that involves either programming, IT, or some sort of IT or programming related consulting or services.

The wikipedia link above is an overview of the concept. The short form explanation is that a co-op is a worker-owned business. Also there is the notion that every worker owns shares in the business.

I am interested in knowing whether an example of a "programmer's/IT co-op" even exists.

Note: I am not talking about nor asking about a government-funded incubator nor any other socialized, state supported group. I also don't mean "co-working", which is renting an office with other self employed people doing their own thing.

I mean a going, profitable IT business operating in a competitive environment that is worker-owned and run.

答:
There are several examples profiled in the recent publication "A Technology Freelancer's Guide to Starting a Worker Cooperative" which is available through the U.S. Federation of Worker Cooperatives in the link below.  The guide was written by some of the cooperative entrepreneurs that are profiled.

http://www.usworker.coop/howtos/startups
http://electricembers.net/pubs/TechCoopHOWTO.pdf

OwnerDisplayName: Joe


问:
How to handle Data Fetching for Circular Object References in OOP Domain Models
I'm trying to put together some basic models in OOP (C#), and apparently I've got the wrong idea.

If I have a Workman's Comp case, it is applied to a Patient.  It also has one or more PatientVisits applied to the case.  Each PatientVisit though, also has a Patient associated with it, and of course a Patient can have any number of Visits associated with it.

My original thought was to create basic, real-world reflections of the business models by doing something like:

```<code>class Patient {
        int ID;
        string FirstName;
        string LastName;

        List<Visit> Visits;
    }

    class Visit {
        int ID;
        DateTime VisitDate;
        Patient Patient;

        List<DxCode> DxCodes;
    }

    class WCCase {
        int ID;
        Patient Patient;
        DateTime DateEntered;

        List<Visit> Visits;
    }
</code>```

I naively thought that'll be nice, I'll just load up my model and have everything at hand, very semantic and representative of the domain/real-world, right?

So, I can go the opposite route and fill the parent object and store lists of IDs for related models:

```<code>class Patient {
    int ID;
    string FirstName;
    string LastName;

    List<int> VisitIDs;

    public static Patient GetPatient(int id) {}
}

class Visit {
    int ID;
    DateTime VisitDate;
    int PatientID;

    List<DxCode> DxCodes;

    public Static Visit GetVisit(int id) {}
}

class WCCase {
    int ID;
    int PatientID;
    DateTime DateEntered;

    List<int> VisitIDs;

    public static case GetCase(int id) {}
}
</code>```

This of course allows me to load everything on demand (get an ID and grab the object through it's Get*() method), but seems a bit of a step away from the idea of a nicely representative real-world model and more like a mirror of a database table representation.

I'm guessing there must be some middle ground, but I'd sure like some advice on finding it...  Can anyone give some basic examples of how we'd model this without going nuts with references and circulars, etc?

Thanks in advance.

答:
What you are describing is a very common dilemma: On the one hand you
want to keep your domain model simple and ignore the technical details
of data storage as well as common access patterns. On the other hand
this approach is usually not practical because it tends to be very
inefficient. It often happens that accessing one entity requires to
load the whole object graph.

A simple more extreme example: Let's say a social network would model
the friends of a user as a list of user objects.

```<code>class User {
  List<User> friends;
}
</code>```

Loading one user would required to load the whole network! It would
not even be easy to set up because you have circular references.

Option A: Use ids

One way to deal with this problem is to use ids everywhere and fetch
the users for the ids when you need them. Although this solves the
problem of having to load the whole graph, it is not very beautiful
from a modeling point of view.

Option B: Use explicit references

Another alternative is to use reference objects that are responsible
for returning the referenced objects on demand. Be it from a cache or
the database.

```<code>interface UserRef {
   User get();
}

class User {
  List<UserRef> friends;
}
</code>```

If you are not using a persistence framework you will kind of have to
write your own. For performance reasons you will usually want to
specify which references are resolved immediately when the user is
loaded and which will be loaded lazily.

Option C: Stay with the naive approach if its appropriate

Finally, there are some cases where it makes sense to modal a
relationship like you tried it. In case of composition , i.e. an
object consists of other objects and there are no circular references,
and a low and limited cardinality it can make sense. Let's say you
model a car that consists, among other things, of a list of
seats. Even if you don't always want to access the seats, you could
trade efficiency for simplicity here.

Body:
What you are describing is a very common dilemma: On the one hand you
want to keep your domain model simple and ignore the technical details
of data storage as well as common access patterns. On the other hand
this approach is usually not practical because it tends to be very
inefficient. It often happens that accessing one entity requires to
load the whole object graph.

A simple more extreme example: Let's say a social network would model
the friends of a user as a list of user objects.

class User {
  List<User> friends;
}

Loading one user would required to load the whole network! It would
not even be easy to set up because you have circular references.

Option A: Use ids

One way to deal with this problem is to use ids everywhere and fetch
the users for the ids when you need them. Although this solves the
problem of having to load the whole graph, it is not very beautiful
from a modeling point of view.

Option B: Use explicit references

Another alternative is to use reference objects that are responsible
for returning the referenced objects on demand. Be it from a cache or
the database.

interface UserRef {
   User get();
}

class User {
  List<UserRef> friends;
}

If you are not using a persistence framework you will kind of have to
write your own. For performance reasons you will usually want to
specify which references are resolved immediately when the user is
loaded and which will be loaded lazily.

Option C: Stay with the naive approach if its appropriate

Finally, there are some cases where it makes sense to modal a
relationship like you tried it. In case of composition , i.e. an
object consists of other objects and there are no circular references,
and a low and limited cardinality it can make sense. Let's say you
model a car that consists, among other things, of a list of
seats. Even if you don't always want to access the seats, you could
trade efficiency for simplicity here.


答:
I agree with the other questions. There is nothing you can do with recursion you can't do with a loop.

BUT, in my opinion recursion can be very dangerous. First, for some its more difficult to understand what is actually happening in the code. Second, at least for C++ (Java I am not sure) each recursion step has an impact on the memory because each method call causes memory accumulation and initialization of the methods header. This way you can blow up your stack. Simply try recursion of the Fibonacci numbers with a high input value.


答:
For a refreshingly different take on how to structure a modern compiler, see Martin Odersky's talk Compilers are Databases at the JVM Language Summit 2015 about the design of the dotty compiler. (Dotty is a language intended to be an experimentation area for future directions of Scala, likewise, the dotty compiler is an experimentation area for future directions of the Scala compiler.)

The Scala compiler tries to be a single canonical one-stop-shop modern compiler for traditional batch compilation, incremental batch compilation, interactive compilation (REPL, workbook, etc.), IDEs (everything from syntax coloring to autocompletion to refactoring), macros (letting the user run user code in the compiler during compilation), reflection (letting the user run compiler code in the user program during runtime), documentation formatting, static analysis, linting, pretty printing, and a whole lot of other things.

The basic idea of the dotty compiler is that there is no mutable state. Everything is fully immutable and purely functional. This is achieved by taking ideas from purely functional (aka "temporal") databases. Data that in a traditional compiler would change over time (such as a symbol table) is instead represented as a pair of (timestamp, current_value), i.e. as values indexed by time. (They don't use actual time, though, rather a notion of time internal to the compiler, based on the run number and the compiler phase.)

In particular, this means that there is no symbol table. Instead, the role that the symbol table plays in a traditional compiler, is split across multiple data structures, all of which are immutable, some are time-invariant, some are time-varying. These are References, Denotations, and Symbols; the discussion of References starts around 30:30, the discussion of Denotations around 34:26, and the discussion of Symbols around 37:30.

Title: How do Symbol Tables, Lexers and Parsers work together in a modern design?

Body:
I'm working on creating my own scripting language for learning purposes. I've been reading through the Dragon Book and some things are a little unclear to me regarding the Symbol Table as well as where the strings that constitute an identifier actually reside and the ownership. Most of this confusion I think is due to the book using older techniques whereas I'm looking to use C++11.

As I understand it:

The SymbolTable would be a hash_map of some kind using the lexemes as the keys. I.e. string types. I've determined on my own that it's value would then be a tuple containing the SYMBOL_TYPE and a pointer/reference/lookup to a second array that contains the additional info needed for this SYMBOL_TYPE.

I.e. an entry in the SymbolTable could be <SYMBOL_TYPE::VARIABLE,3> which would mean that the Variables array at index 3 would feature this variables type + value + attributes.

I would then do the same for other identifiers like procedures etc.

The Lexer goes through characters until it's produced the longest possible lexeme each time the next Token is requestsed.

Question 1: Where do these pre-existing lexemes reside? For example, if the symbol table is pre-populated with keywords, punctuation, operators etc, who pre-populates it? Does the SymbolTable itself pre-populate itself with a list of keywords + punctuation + operators? Would I then just attempt to match each entry in the symbol table (starting with longest first)?

Question 2: When the Lexer has produced a token, does it add new identifiers to the symbol table? How does it know if this should be a SYMBOL_TYPE::FUNCTION or SYMBOL_TYPE:::VARIABLE? Or does it just populate it with SYMBOL_TYPE::ID and allow the Parser to later update the entry once it's determined the identifiers usage?

I think it can't be left to the Parser because when a new scope is started by the occurrence of a {, the Lexer would need to add a new SymbolTable to a stack otherwise the Token it returns to the Parser would point to the wrong entry... But then the Lexer can't be expected to also add the type and value information to the Variables or Procedures arrays.

The Parser requests each Token in turn from the Lexer.

Question 3: What exactly is needed in this Token type that's returned? At the moment it's just the SYMBOL_TYPE + the index into the SymbolTable. The SymbolTable then links to the corresponding additional list for that SYMBOL_TYPE. But should it be something other than SYMBOL_TYPE, like TOKEN_TYPE and allow the Parser to add to the SymbolTable rather than the Lexer? Because the Lexer can't determine whether an identifier is a variable or procedure. Because the Lexer needs to add them due to different scopes, does the Parser then discard what the Lexer added and add it's own?

I'm confused about who owns the creation and management of the SymbolTable and whether the identifiers in it should be the same as what's passed between the Lexer and Parser.

It seems to me like it would be simpler to have the Lexer only return Tokens which determine whether it's a known keyword/operator/punctuation (each with it's own TOKEN_TYPE) + the string that makes it up (if needed) and the Parser then adds entries to the SymbolTable and subsequent arrays (like the Variables array) when it needs to. It would also see a { and add a new SymbolTable to the stack when neccessary.

Am I mis-interpreting the goal of a SymbolTable?


答:
Setting aside theoretical reasoning, let's have a look at what recursion and loops look like from a (hardware or virtual) machine point of view. Recursion is a combination of control flow that allows to start execution of some code and to return on completion (in a simplistic view when signals and exceptions are ignored) and of data that is passed to that other code (arguments) and that is returned from it (result). Usually no explicit memory management is involved, however there is implicit allocation of stack memory to save return addresses, arguments, results and intermediate local data.

A loop is a combination of control flow and local data. Comparing this to recursion we can see that the amount of data in this case is fixed. The only way to break this limitation is to use dynamic memory (also known as heap) that can be allocated (and freed) whenever needed.

To summarize:

Recursion case = Control flow + Stack (+ Heap)

Loop case = Control flow + Heap

Assuming that control flow part is reasonably powerful, the only difference is in available memory types. So, we are left with 4 cases (expressiveness power is listed in parentheses):

No stack, no heap: recursion and dynamic structures are impossible. (recursion = loop)

Stack, no heap: recursion is OK, dynamic structures are impossible. (recursion > loop)

No stack, heap: recursion is impossible, dynamic structures are OK. (recursion = loop)

Stack, heap: recursion and dynamic structures are OK. (recursion = loop)

If rules of the game are a bit stricter and recursive implementation is disallowed to use loops, we get this instead:

No stack, no heap: recursion and dynamic structures are impossible. (recursion < loop)

Stack, no heap: recursion is OK, dynamic structures are impossible. (recursion > loop)

No stack, heap: recursion is impossible, dynamic structures are OK. (recursion < loop)

Stack, heap: recursion and dynamic structures are OK. (recursion = loop)

The key difference with the previous scenario is that lack of stack memory does not allow recursion without loops to do more steps during execution than there are lines of code.


答:
Your class is fine, SRP is about a class not a function, the whole class is responsible for providing the "Fluffies" from the "Data Source" so you are free in internal implementation.

If you wish to expand the cahing mechanism you can create class respnsible for watching data source

```<code>public class ModelWatcher
{

    private static Dictionary<Type, DateTime> LastUpdate;

    public static bool IsUpToDate(Type entityType, DateTime lastRead) {
        if (LastUpdate.ContainsKey(entityType)) {
            return lastRead >= LastUpdate[entityType];
        }
        return true;
    }

    //call this method whenever insert/update changed to any entity
    private void OnDataSourceChanged(Type changedEntityType) {
        //update Date & Time
        LastUpdate[changedEntityType] = DateTime.Now;
    }
}
public class FluffyManager
{
    private DateTime LastRead = DateTime.MinValue;

    private List<Fluffy> list;

    public List<Fluffy> GetFluffies() {

        //if first read or not uptodated
        if (list==null || !ModelWatcher.IsUpToDate(typeof(Fluffy),LastRead)) {
            list = ReadFluffies();
        }
        return list;
    }
    private List<Fluffy> ReadFluffies() {
    //read code
    }
}
</code>```

Body:
Your class is fine, SRP is about a class not a function, the whole class is responsible for providing the "Fluffies" from the "Data Source" so you are free in internal implementation.

If you wish to expand the cahing mechanism you can create class respnsible for watching data source

public class ModelWatcher
{

    private static Dictionary<Type, DateTime> LastUpdate;

    public static bool IsUpToDate(Type entityType, DateTime lastRead) {
        if (LastUpdate.ContainsKey(entityType)) {
            return lastRead >= LastUpdate[entityType];
        }
        return true;
    }

    //call this method whenever insert/update changed to any entity
    private void OnDataSourceChanged(Type changedEntityType) {
        //update Date & Time
        LastUpdate[changedEntityType] = DateTime.Now;
    }
}
public class FluffyManager
{
    private DateTime LastRead = DateTime.MinValue;

    private List<Fluffy> list;

    public List<Fluffy> GetFluffies() {

        //if first read or not uptodated
        if (list==null || !ModelWatcher.IsUpToDate(typeof(Fluffy),LastRead)) {
            list = ReadFluffies();
        }
        return list;
    }
    private List<Fluffy> ReadFluffies() {
    //read code
    }
}


问:
What do Java developers think of Scala?
I've noted that IDE support is nowhere near as good, but the language itself supports functional programming idioms much more cleanly.</p>

答:
Here is what sucks about Scala:

The null pointer was a pretty bad idea to begin with. Hoare called it his "billion dollar mistake", but Scala is even worse. It has objects named null, Null, None, and Nil. null is for interoperability with Java. Null is the null pointer form W3C DOM specification, None is what null should have been replaced with, and Nil is an empty something.

When language constructs turn out to be hacky it is usually the programmer who is to blame and not the language. In Scala, however, the core language already contains library classes whose only documented behavior is "This is a hack". Don't believe it? Search the scaladoc for scala.xml.Group.

Last not least, Scala is badly documented. Hardly any of the scala classes in the official documentation comes with example code. Scala is significantly harder to learn than Java and requires profound knowledge in computer science.

To avoid being mistaken for a Scala-hater, here is what I love about it:

I have fewer exceptions. I never had a ClassCastException and very few NullPointerExceptions when interacting with Java.

Code is much shorter and more concise than Java

It is intellectually challenging. Java feels like baby language when compared.

Title: What do Java developers think of Scala?

OwnerDisplayName: Stefan D.