答:
The answer to the question you actually asked is no, but the answer to the question you meant to ask is yes. Adding parentheses does not slow down the code.

You asked a question about optimisation, but parentheses have nothing to do with optimisation. The compiler applies a variety of optimisation techniques with the intention of improving either the size or speed of the generated code (sometimes both). For example, it might take the expression A^2 (A squared) and replace it by A x A (A multiplied by itself) if that is faster. The answer here is no, the compiler does nothing different in its optimisation phase depending on whether parentheses are present are not.

I think you meant to ask whether the compiler still generates the same code if you add unnecessary parentheses to an expression, in places that you think might improve readability. In other words, if you add parentheses is the compiler smart enough to take them out again rather than somehow generating poorer code. The answer is yes, always.

Let me say that carefully. If you add parentheses to an expression that are strictly unnecessary (have no effect whatever on the meaning or order of evaluation of an expression) the compiler will silently discard them and generate the same code.

However, there exist certain expressions where apparently unnecessary parentheses will actually change the order of evaluation of an expression and in that case the compiler will generate code to put into effect what you actually wrote, which might be different from what you intended. Here is an example. Don't do this!

```<code>short int a = 30001, b = 30002, c = 30003;
int d = -a + b + c;    // ok
int d = (-a + b) + c;  // ok, same code
int d = (-a + b + c);  // ok, same code
int d = ((((-a + b)) + c));  // ok, same code
int d = -a + (b + c);  // undefined behaviour, different code
</code>```

So add parentheses if you want to, but make sure they really are unnecessary!

I never do. There is a risk of error for no real benefit.

Footnote: unsigned behaviour happens when a signed integer expression evaluates to a value that is outside the range that it can express, in this case -32767 to +32767. This is a complex topic, out of scope for this answer.

Body:
The answer to the question you actually asked is no, but the answer to the question you meant to ask is yes. Adding parentheses does not slow down the code.

You asked a question about optimisation, but parentheses have nothing to do with optimisation. The compiler applies a variety of optimisation techniques with the intention of improving either the size or speed of the generated code (sometimes both). For example, it might take the expression A^2 (A squared) and replace it by A x A (A multiplied by itself) if that is faster. The answer here is no, the compiler does nothing different in its optimisation phase depending on whether parentheses are present are not.

I think you meant to ask whether the compiler still generates the same code if you add unnecessary parentheses to an expression, in places that you think might improve readability. In other words, if you add parentheses is the compiler smart enough to take them out again rather than somehow generating poorer code. The answer is yes, always.

Let me say that carefully. If you add parentheses to an expression that are strictly unnecessary (have no effect whatever on the meaning or order of evaluation of an expression) the compiler will silently discard them and generate the same code.

However, there exist certain expressions where apparently unnecessary parentheses will actually change the order of evaluation of an expression and in that case the compiler will generate code to put into effect what you actually wrote, which might be different from what you intended. Here is an example. Don't do this!

short int a = 30001, b = 30002, c = 30003;
int d = -a + b + c;    // ok
int d = (-a + b) + c;  // ok, same code
int d = (-a + b + c);  // ok, same code
int d = ((((-a + b)) + c));  // ok, same code
int d = -a + (b + c);  // undefined behaviour, different code

So add parentheses if you want to, but make sure they really are unnecessary!

I never do. There is a risk of error for no real benefit.

Footnote: unsigned behaviour happens when a signed integer expression evaluates to a value that is outside the range that it can express, in this case -32767 to +32767. This is a complex topic, out of scope for this answer.


问:
ASP.NET deployment/maintenance best practices
I have been in the web development industry for around 5 years now, always working in an open source environment. Mostly apache, mysql, and php with a little bit of ruby, using git for version control. But recently took up a job where development is entirely C# ASP.NET MVC.

While I was able to pick up the language etc fairly easily, the other members of my team (with a lot more MS Development experience than me) all have a different way of thinking when it comes to publishing and deployment of the final site, and particularly future changes.

The mentality with the other developers is that once a site has been published it is final. No more changes can be made to the site, when I have asked the reasons behind this, the answers have been it is too dangerous, time consuming or difficult.

From my past experience, updating a site is simply a case of uploading the changed files, which is usually quite quick if it was a little change, or putting the site in maintenance mode while the update occurs.

We recently published an MVC Site, and the business contacted us to update some of the text and add a link to a new pdf document. The rest of my team were quick to say that this should not be done because the site is now live and should not be modified. Is there something I have missed by not being 'brought up' a Microsoft developer?

What are the argument against making modifications to a live web application in production and is this mindset unique to .NET developers?

I genuinely would like to understand this mindset and whether it is justified in a Microsoft development environment, or if this is just an older way of thinking.

NOTE: We use TFS for version control and use publish profiles to determine where the site gets deployed (UAT or Production)

答:
ASP.NET MVC applications are compiled. This means that you can't just upload the changed files, like you do with a PHP website, for example. This also means that when you'll start to update the site, current users will be thrown away (lose their sessions, for example).

There is also much more to do than simply update the files: you have to handle:

Permissions

The new version may require a different set of permissions on the server.

Configuration

The new version may require the Distributed Transaction Coordinator (MSDTC) service to be installed, or may want to use a different SMTP server, or have access to Active Directory, etc. This involves changing both the configuration of the application and of the server itself.

Dependencies

For example, one of the issues which is often encountered by the beginners is that they keep old DLLs in /bin while adding new ones with different names: the application may still use the old ones, which creates a crazy situation where you change the code of the application, but the application behavior remains the same.

Data

What if database schema changed, and the application uses an ordinary SQL server instead of NoSQL? How to perform the change in the schema? How to keep the data correct during the change?

Handling the transition between an old and a new version of the application is a hard task. A few years ago, it was one of the issues, where a new version of application was ready, but took days or weeks to system administrators to deploy. DevOps addresses this issue, but requires for the developers to describe (through code or configuration) the system which will host the application.

The larger is the application, the more complicated is this task.

For a tiny web app, copying source files to the server is enough,

For something larger, you have to have an automated process which deals with the update process, and the rollback in case something goes wrong,

For systems even larger, at every new version, new VMs are created and deployed, and old ones are recycled, ensuring seamless transition of the users from the old to the new version.

Compiled applications simply force/encourage to automate the process earlier.

the business contacted us to update some of the text and add a link to a new pdf document. The rest of my team were quick to say that this should not be done because the site is now live

IMO, there are no real technical reasons for this refusal; they just want to avoid doing it, because, if not automated well, the task is error prone.

What usually happens is that:

The application is deployed for the first time.

The team spends a few hours tweaking the configuration to make it work. Since the team was expected to deliver three weeks ago, everybody rushes, and nobody takes the notes of the changes.

The application is now up and running.

For a few weeks, months or years, some random people change some random stuff on the server: for example they moved a database to a different location, or the SMTP password changed, causing the changes in Web.config.

If you update the new version now, you're back to the first step, and it may take days to recover the correct configuration. Since the website is live, this should be avoided at all costs.

ContentLicense: CC BY-SA 3.0


问:
How can I track programming productivity on a daily basis?
How can I track that I'm developing software more or less productive than the previous days? </p>

答: I'd say the best way to measure your productivity is to set a goal each day for what you want to have done that day, and if you complete it, consider it productive.  It's a fairly subjective measure, but you'll most likely find it much more rewarding than an objective one.</p>

ContentLicense: CC BY-SA 2.5


答:
Do you have project managers, a Development Manager, or someone else other than the other developers?

It makes ZERO sense that you cannot do a deployment after go live.

Of course, these changes need to be scheduled, costed, and resourced amongst other things, but just saying "no" is nonsense.

Title: ASP.NET deployment/maintenance best practices

Body:
I have been in the web development industry for around 5 years now, always working in an open source environment. Mostly apache, mysql, and php with a little bit of ruby, using git for version control. But recently took up a job where development is entirely C# ASP.NET MVC.

While I was able to pick up the language etc fairly easily, the other members of my team (with a lot more MS Development experience than me) all have a different way of thinking when it comes to publishing and deployment of the final site, and particularly future changes.

The mentality with the other developers is that once a site has been published it is final. No more changes can be made to the site, when I have asked the reasons behind this, the answers have been it is too dangerous, time consuming or difficult.

From my past experience, updating a site is simply a case of uploading the changed files, which is usually quite quick if it was a little change, or putting the site in maintenance mode while the update occurs.

We recently published an MVC Site, and the business contacted us to update some of the text and add a link to a new pdf document. The rest of my team were quick to say that this should not be done because the site is now live and should not be modified. Is there something I have missed by not being 'brought up' a Microsoft developer?

What are the argument against making modifications to a live web application in production and is this mindset unique to .NET developers?

I genuinely would like to understand this mindset and whether it is justified in a Microsoft development environment, or if this is just an older way of thinking.

NOTE: We use TFS for version control and use publish profiles to determine where the site gets deployed (UAT or Production)


问:
Licensing: Derivative work and copyright notice
I am currently creating something that has been inspired by another library. It is a complete rewrite on another platform - yet, has the same purpose and functionality and is written in the same language. As far as I understand it, this is still considered a derivative work.

The original piece is licensed under the Apache 2.0 license.

Which steps do I need to take now when publishing my source under the Apache 2.0 license?
Do I have to maintain copyright notices?
If so, it can't obviously be in the source files (which are all new and cannot be mapped to the original piece).

What do I have to do to be on the safe side? What do I have to include when I distribute the sources?

答:
If you only copied ideas from the original library and no actual source code, then your library is not a derived work as far as copyrights are concerned.

Copyrights are about the actual source code, not about the ideas/concepts that are represented in that source code. To protect those ideas/concepts, you need to turn to other intellectual property laws, such as trademarks and patents.

So, if your library is really a full rewrite (no traces of the original can be found), then you can release your library under any license you want, because you own the copyrights to it.

To be nice, you could mention the original library (possibly with a link) in your documentation as being your inspiration.


问:
MVC4 : How to create model at run time?
In my project I am dynamically creating table by giving table name (ex. student) and adding fields to that table and then save table. Now, my table is created in SQL Server database.

Assume table has data and I want to show the data of table (ex student) on WebGrid. But, the problem is I have no model for that table (ex. student). So, how I can create model for newly created table or how I can show the the data on WebGrid?

答:
If you don't know what's in a table, you shouldn't be trying to display it anywhere!  What if it's full of credit card details (Yowch!) or passwords in "anonymously-named" fields (Eek!)?

And you just plump them all up on the screen for all to see?

To me, that's bordering on irresponsible at the very least.

You need to know what's in there before you try doing anything with it.

You say you're creating field dynamically in your database.  OK; it's not a Good way to design your database in my book, but it's A way.  I'd suggest you create metadata tables - just more tables in your database - that describe the real tables that your application currently uses.  You'll need (at least)

one metadata table that describes each real table and

another metadata table that describes each column within each real table.

This metadata can be queried at run time and [accurately] describes each table and field in the database, what it contains and whether you're allowed to display it, amongst other things.  It also documents your database "design", even though it's created "in-flight".

The important thing is that this is all built in to whatever U.I. you use to build your real tables - you need to be filling this stuff in ("writing it down") before you add the field into the database.

Title: MVC4 : How to create model at run time?


问:
Android DB With Some Multi-Language Data
I have a SQLite Database in my Android app with a "Question" table, among others. That table contains "default" or "pre-loaded" data (in this case the questions asked by the app).

Some of its columns are "technical" or "internal" data to be used behind the scenes - like the number of points the question is worth, the type of user that may answer it, etc. - while others are textual data that are presented to the user (e.g. Title, Description, etc.).

Now, I intend to let my app be internationalization-friendly (translatable) so I'm thinking that:

Instead of following what seems to be the 'standard approaches' for multi-language DB design - either creating different columns for the translatable attributes (e.g. name_en, name_es, ...) or a separate table where each row represents a translation of the base object;

...I could simply keep the values for those translatable attributes in my R.Strings resource and have my DatabaseHelper class fetch the text from there, by building the resource name based, for instance, in the question's ID (e.g. q1_name, q2_name, q1_description, ...). This way I could have several R.strings and the DB helper would read from the right one.

I'm a bit unsure about this approach and I'm curious if this is a bad practice and/or I'm missing any potential drawback.

答:
I don't know much about Android standards but I am sure that creating different columns for the translatable attributes is cleary a very bad solution. You would have to alter your table each time you add a  new language and if your application get translated in many languages, you will have to manage that.

The two other solutions are acceptable for me but I would chose the database option if you plan to create an "admin" interface where people could for example add question and solutions...


问:
Does C++ compiler remove/optimize useless parentheses?
Will the code

```<code>int a = ((1 + 2) + 3); // Easy to read
</code>```

run slower than

```<code>int a = 1 + 2 + 3; // (Barely) Not quite so easy to read
</code>```

or are modern compilers clever enough to remove/optimize "useless" parentheses.

It might seems like a very tiny optimization concern, but choosing C++ over C#/Java/... is all about optimizations (IMHO).

答:
Brackets are only there for you to manipulate the order of operator precedence.
Once compiled, brackets no longer exists because the run-time doesn't need them.
The compilation process removes all of the brackets, spaces and other syntactic sugar that you and I need and changes all of the operators into something [far] simpler for the computer to execute.

So, where you and I might see ...

"int a = ((1 + 2) + 3);"

... a compiler might emit something more like this:

Char[1]::"a"

Int32::DeclareStackVariable()

Int32::0x00000001

Int32::0x00000002

Int32::Add()

Int32::0x00000003

Int32::Add()

Int32::AssignToVariable()

void::DiscardResult()

The program is executed by starting at the beginning and executing each instruction in turn.

Operator precedence is now "first-come, first served".

Everything is strongly typed, because the compiler worked all that out while it was tearing the original syntax apart.

OK, it's nothing like the stuff that you and I deal with, but then we're not running it!


答: The typical C++ compiler translates to machine code, not C++ itself. It removes useless parens, yes, because by the time it's done, there are no parens at all. Machine code doesn't work that way.

Title: Does C++ compiler remove/optimize useless parentheses?

Body:
Will the code

```<code>int a = ((1 + 2) + 3); // Easy to read
</code>```

run slower than

```<code>int a = 1 + 2 + 3; // (Barely) Not quite so easy to read
</code>```

or are modern compilers clever enough to remove/optimize "useless" parentheses.

It might seems like a very tiny optimization concern, but choosing C++ over C#/Java/... is all about optimizations (IMHO).


问:
Programming language constructs for cache optimization?
Clearly optimizing cache usages is bound to improve my program efficiency. Surprisingly, I don't see too many programming languages actually having this sort of a feature. So here's my question:

What kind of language constructs have you seen that help improving cache usage?

How to innovate on cache usage since most systems won't easily reveal stuff like their L1 cache size easily? (Windows does have API or maybe /proc/cpuinfo on Linux, but I am looking for something simpler for the intermediate developer)

答:
This is just an off-the-head list.

Concepts

Spatial locality

Temporal locality.

Easily-predictable memory access patterns.

For example, reading/writing megabytes of data sequentially is not at all inefficient, because the CPU can predict the next address and automatically read ahead.

Programming language constructs.

Data alignment directives.

Switching between array of structure and structure of array.

Vectorized data containers provided by high-performance libraries.

The compiler has already done some of the work for you. For example, groups of functions that are closely related (for example, likely to be called in successive sequence) will be compiled into binary instructions and then stored close to each other, so that they reside within the same 4KB page block. There is simply no way for a developer to cater to such details manually.

For native compiled languages, local variables are stored on the stack, and the area closest to the current stack position is likely to be cached. If a large variable (several KBs or more) is allocated from the stack, the CPU may have to evict something else from the cache to make room. On the other hand, if the large variable is used very frequently, then allocating from stack can be justified.


答:
The compiler does not actually ever insert or remove parentheses; it just creates a parse tree (in which no parentheses are present) corresponding to your expression, and in doing so it must respect the parentheses you wrote. If you fully parenthesise your expression then it will also be immediately clear to the human reader what that parse tree is; if you go to the extreme of putting in blatantly redundant parentheses as in int a = (((0))); then you will be causing some useless stress on the neurons of the reader while also wasting some cycles in the parser, without however changing the resulting parse tree (and therefore the generated code) the slightest bit.

If you don't write any parentheses, then the parser must still do its job of creating a parse tree, and the rules for operator precedence and associativity tell it exactly which parse tree it must construct. You might consider those rules as telling the compiler which (implicit) parentheses it should insert into your code, although the parser doesn't actually ever deal with parentheses in this case: it just has been constructed to produce the same parse tree as if parentheses were present in certain places. If you place parentheses in exactly those places, as in int a = (1+2)+3; (associativity of + is to the left) then the parser will arrive at the same result by a slightly different route. If you put in different parentheses as in int a = 1+(2+3); then you are forcing a different parse tree, which will possibly cause different code to be generated (though maybe not, as the compiler may apply transformations after building the parse tree, as long as the effect of executing the resulting code would never be different for it). Supposing there is a difference in the resuting code, nothing in general can be said as to which is more efficient; the most important point is of course that most of the time the parse trees do not give mathematically equivalent expressions, so comparing their execution speed is beside the point: one should just write the expression the gives the proper result.

So the upshot is: use parentheses as needed for correctness, and as desired for readability; if redundant they have no effect at all on execution speed (and a negligible effect on compile time).

And none of this has anything to do with optimisation, which comes along way after the parse tree has been built, so it cannot know how the parse tree was constructed. This applies without change from the oldest and stupidest of compilers to the smartest and most modern ones. Only in an interpreted language (where "compile time" and "execution time" are coincident) could there possibly be a penalty for redundant parentheses, but even then I think most such languages are organised so that at least the parsing phase is done only once for each statement (storing some pre-parsed form of it for execution).


答:
Parentheses are there to tell the compiler in which order expressions should be evaluated. Sometimes they are useless (except they improve or worsen readability), because they specify the order that would be used anyway. Sometimes they change the order. In

```<code>int a = 1 + 2 + 3;
</code>```

practically every language in existence has a rule that the sum is evaluated by adding 1 + 2, then adding the result plus 3. If you wrote

```<code>int a = 1 + (2 + 3);
</code>```

then the parenthesis would force a different order: First adding 2 + 3, then adding 1 plus the result. Your example of parentheses produces the same order that would have been produced anyway. Now in this example, the order of operations is slightly different, but the way that integer addition works, the outcome is the same. In

```<code>int a = 10 - (5 - 4);
</code>```

the parentheses are critical; leaving them out would change the result from 9 to 1.

After the compiler has determined what operations are performed in which order, the parenthesis are completely forgotten. All that the compiler remembers at this point is which operations to perform in which order. So there is actually nothing that the compiler could optimise here, the parentheses are gone.

Body:
Parentheses are there to tell the compiler in which order expressions should be evaluated. Sometimes they are useless (except they improve or worsen readability), because they specify the order that would be used anyway. Sometimes they change the order. In

int a = 1 + 2 + 3;

practically every language in existence has a rule that the sum is evaluated by adding 1 + 2, then adding the result plus 3. If you wrote

int a = 1 + (2 + 3);

then the parenthesis would force a different order: First adding 2 + 3, then adding 1 plus the result. Your example of parentheses produces the same order that would have been produced anyway. Now in this example, the order of operations is slightly different, but the way that integer addition works, the outcome is the same. In

int a = 10 - (5 - 4);

the parentheses are critical; leaving them out would change the result from 9 to 1.

After the compiler has determined what operations are performed in which order, the parenthesis are completely forgotten. All that the compiler remembers at this point is which operations to perform in which order. So there is actually nothing that the compiler could optimise here, the parentheses are gone.


问:
How to adhere to the open-closed principle in practice
I understand the intent of the open-closed principle. It's meant to reduce the risk of breaking something that already works while modifying it, by telling you to try to extend without modifying.

However, I had some trouble understanding how this principle is applied in practice. To my understanding, there are two ways to apply it. Beofore and after a possible change:

Before: program to abstractions and 'predict the future' as much as you can.
For example, a method drive(Car car) will have to change if
Motorcycles are added to the system in the future, so it probably
violates OCP. But the method drive(MotorVehicle vehicle) is less
likely to have to change in the future, so it adheres to OCP.

However, it's quite difficult to predict the future and know in
advance what changes are going to be made to the system.

After: when a change is needed, extend a class instead of modifying it's
current code.

Practice #1 isn't hard to understand. However it's practice #2 that I'm having trouble understanding how to apply.

For example (I took it from a video on YouTube): let's say we have a method in a class that accepts CreditCard objects: makePayment(CraditCard card). One day Vouchers are added to the system. This method doesn't support them so it has to be modified.

When implementing the method in the first place we failed to predict the future and program in more abstract terms (e.g. makePayment(Payment pay), so now we have to change the existing code.

Practice #2 says we should add the functionality by extending instead of modifying. What does that mean? Should I subclass the existing class instead of simply changing it's existing code? Should I make some kind of wrapper around it just to avoid rewriting code?

Or does the principle not even refer to 'how to correctly modify/add functionality', but rather refers to 'how to avoid having to make changes in the first place (i.e. program to abstractions)?

答:
Design principles always have to be balanced against each other.  You can't predict the future, and most programmers do it horribly when they try.  That's why we have the rule of three, which is primarily about duplication, but applies to refactoring for any other design principles as well.

When you only have one implementation of an interface, you don't need to care much about OCP, unless it's crystal clear where any extensions would take place.  In fact, you often lose clarity when trying to over-design in this situation.  When you extend it once, you refactor to make it OCP friendly if that's the easiest and clearest way to do it.  When you extend it to a third implementation, you make sure to refactor it taking OCP into account, even if it requires a little more effort.

In practice, when you only have two implementations, refactoring when you add a third is usually not too difficult.  It's when you let it grow past that point that it becomes troublesome to maintain.


答:
I agree with much of what has been said, however…the over-arch here is that the parentheses are there to coerce order of operation…which the compiler is absolutely doing. Yes, it produces machine code…but, that is not the point and is not what is being asked.

The parentheses are indeed gone : as has been said, they are not part of machine code, which is numbers and not a thing else. Assembly code is not machine code, it is semi-human readable and contains the instructions by name -- not opcode. The machine runs what are called opcodes -- numeric representations of assembly language.

Languages like Java fall into an in-between area as they compile only partially on the machine that produces them. They are compiled to machine specific code on the machine that runs them, but that makes no difference to this question -- the parentheses are still gone after the first compile.


答:
Compilers, regardless of the language, translate all infix math to postfix. In other words, when the compiler sees something like:

```<code>((a+b)+c)
</code>```

it translates it into this:

```<code> a b + c +
</code>```

This is done because while infix notation is easier for people to read, the postfix notation is much closer to the actual steps the computer has to take to get the job done (and because there is already a well-developed algorithm for it.) By definition, postfix has eliminates all issues with order-of-operations or parentheses, which naturally makes things much easier when actually writing the machine code.

I recommend the wikipedia article on Reverse Polish Notation for more information on the subject.

Body:
Compilers, regardless of the language, translate all infix math to postfix. In other words, when the compiler sees something like:

((a+b)+c)

it translates it into this:

 a b + c +

This is done because while infix notation is easier for people to read, the postfix notation is much closer to the actual steps the computer has to take to get the job done (and because there is already a well-developed algorithm for it.) By definition, postfix has eliminates all issues with order-of-operations or parentheses, which naturally makes things much easier when actually writing the machine code.

I recommend the wikipedia article on Reverse Polish Notation for more information on the subject.


答:
I think you are looking too far into the future. Solve the current problem in a flexible way which adheres to open/closed.

Let's say you need to implement a drive(Car car) method. Depending on your language you have a couple of options.

For languages which support overloading (C++), then just use drive(const Car& car)

At some point later you might need drive(const Motorcycle& motorcycle), but it won't interfere with drive(const Car& car). No problem!

For languages which don't support overloading (Objective C), then include the type name in the method -driveCar:(Car *)car.

At some point later you might need -driveMotorcycle:(Motorcycle *)motorcycle, but again, it won't interfere.

This allows drive(Car car) to be closed to modification, but is open to extending to other vehicle types. This minimalist future planning which allows you to get work done today, but keeps you from blocking yourself in the future.

Trying to imagine the most basic types you need can lead to infinite regress. What happens when you want to drive a Segue, a bicycle or a Jumbo jet. How do you construct a single generic abstract type which can account for all devices people get into and use for mobility?

Title: How to adhere to the open-closed principle in practice

Body:
I understand the intent of the open-closed principle. It's meant to reduce the risk of breaking something that already works while modifying it, by telling you to try to extend without modifying.

However, I had some trouble understanding how this principle is applied in practice. To my understanding, there are two ways to apply it. Beofore and after a possible change:

Before: program to abstractions and 'predict the future' as much as you can.
For example, a method drive(Car car) will have to change if
Motorcycles are added to the system in the future, so it probably
violates OCP. But the method drive(MotorVehicle vehicle) is less
likely to have to change in the future, so it adheres to OCP.

However, it's quite difficult to predict the future and know in
advance what changes are going to be made to the system.

After: when a change is needed, extend a class instead of modifying it's
current code.

Practice #1 isn't hard to understand. However it's practice #2 that I'm having trouble understanding how to apply.

For example (I took it from a video on YouTube): let's say we have a method in a class that accepts CreditCard objects: makePayment(CraditCard card). One day Vouchers are added to the system. This method doesn't support them so it has to be modified.

When implementing the method in the first place we failed to predict the future and program in more abstract terms (e.g. makePayment(Payment pay), so now we have to change the existing code.

Practice #2 says we should add the functionality by extending instead of modifying. What does that mean? Should I subclass the existing class instead of simply changing it's existing code? Should I make some kind of wrapper around it just to avoid rewriting code?

Or does the principle not even refer to 'how to correctly modify/add functionality', but rather refers to 'how to avoid having to make changes in the first place (i.e. program to abstractions)?


问:
Should I use initializer blocks in Java?
I recently came across a Java construct I have never seen before and was wondering whether I should use it. It seems to be called initializer blocks.

```<code>public class Test {
  public Test() { /* first constructor */ }
  public Test(String s) { /* second constructor */ }

  // Non-static initializer block - copied into every constructor:
  {
    doStuff();
  }
}
</code>```

The code block will be copied into each constructor, i.e. if you have multiple constructor you do not have to rewrite code.

However, I see three main drawbacks using this syntax:

It is one of the very few cases in Java where the order of your code is important, as you can define multiple code blocks and they will be executed in the order they are written. This seems harmful to me as simply changing the order of code blocks will actually change the code.

I do not really see any benefits by using it. In most cases, the constructors will call each other with some pre-defined values. Even if this is not the case, the code could simply be put into a private method and called from each constructor.

It reduces readability, as you could put the block at the end of the class and the constructor is normally at the beginning of the class. It is quite counter-intuitive to look at a completely different part of a code file if you do not expect that to be necessary.

If my above statements are true, why (and when) was this language construct introduced? Are there any legitimate use cases?

答:
There are two cases where I use initializer blocks.

The first one is for initializing final members. In Java, you can initialize a final member either inline with the declaration, or you can initialize it in the constructor. In a method, it is forbidden to assign to a final member.

This is valid:

```<code>final int val = 2;
</code>```

This is valid too:

```<code>final int val;

MyClass() {
    val = 2;
}
</code>```

This is invalid:

```<code>final int val;

MyClass() {
    init();
}

void init() {
    val = 2;  // cannot assign to 'final' field in a method
}
</code>```

If you have multiple constructors, and if you can't initialize a final member inline (because the initialization logic is too complex), or if the constructors cannot call themselves, then you can either copy/paste the initialization code, or you can use an initializer block.

```<code>final int val;
final int squareVal;

MyClass(int v, String s) {
    this.val = v;
    this.s = s;
}

MyClass(Point p, long id) {
    this.val = p.x;
    this.id = id;
}

{
    squareVal = val * val;
}
</code>```

The other use case I have for initializer blocks is for building small helper data structures. I declare a member, and put values in it right after its declarations in its own initializer block.

```<code>private Map<String, String> days = new HashMap<String, String>();
{
    days.put("mon", "monday");
    days.put("tue", "tuesday");
    days.put("wed", "wednesday");
    days.put("thu", "thursday");
    days.put("fri", "friday");
    days.put("sat", "saturday");
    days.put("sun", "sunday");
}
</code>```

Body:
There are two cases where I use initializer blocks.

The first one is for initializing final members. In Java, you can initialize a final member either inline with the declaration, or you can initialize it in the constructor. In a method, it is forbidden to assign to a final member.

This is valid:

final int val = 2;

This is valid too:

final int val;

MyClass() {
    val = 2;
}

This is invalid:

final int val;

MyClass() {
    init();
}

void init() {
    val = 2;  // cannot assign to 'final' field in a method
}

If you have multiple constructors, and if you can't initialize a final member inline (because the initialization logic is too complex), or if the constructors cannot call themselves, then you can either copy/paste the initialization code, or you can use an initializer block.

final int val;
final int squareVal;

MyClass(int v, String s) {
    this.val = v;
    this.s = s;
}

MyClass(Point p, long id) {
    this.val = p.x;
    this.id = id;
}

{
    squareVal = val * val;
}

The other use case I have for initializer blocks is for building small helper data structures. I declare a member, and put values in it right after its declarations in its own initializer block.

private Map<String, String> days = new HashMap<String, String>();
{
    days.put("mon", "monday");
    days.put("tue", "tuesday");
    days.put("wed", "wednesday");
    days.put("thu", "thursday");
    days.put("fri", "friday");
    days.put("sat", "saturday");
    days.put("sun", "sunday");
}


问:
Helping someone who is not and never will be a professional programmer write code that is more legible and usable to use and interpret
I am Elvis, trying very hard to learn to be Einstein. I work for Mort.

What the hell is this crazy idiot talking about!?!? (You only need to read the first few paragraphs)

If you don't feel like reading that link, basically, I am a professional programmer, and my boss is (this is scarily accurate):

the professional line-of-business programmer who lacks a degree in computer science but has a great deal of familiarity with Office and VBA, and who typically writes productivity applications shared amongst his coworkers

All that said, a large portion of my job is taking his cobbled together code and making it production ready. However, the very poor style and cargo-cultism makes this difficult. This is compounded by the fact that he is unwilling to read programming books or allow me to help him refactor his code.

Are there some other strategies for helping someone who is not a professional programmer, never will be a professional programmer write code going forward that is more legible and usable for me to use and interpret?

答:
When he is really "someone who is not a professional programmer, never will be a professional programmer" as you say and when a large part of your work is really "taking his cobbled together code and making it production ready", it sounds like your two-man team would be more productive when he would leave the programming to you and concentrate on the managerial part of the project.

However, this assumes that you are right. We programmers always tend to disregard code written by other people as much worse than our own. This preconception is really hard to defeat and leads to us underestimating our colleagues. What you consider "cargo cult programming" might be "proven best practices" from his perspective, and what you consider "elegant application of object-oriented patterns" might be "unnecessary overengineering" for him. Hard to tell for me, because I only know your side of the story.

The disdain for other peoples code becomes stronger the more different our programming styles are. In that case that's a positive instinct, because mixing different programming styles in one project makes it very hard to maintain.

When both of you are unable to mimic the style of the other, then you could define clear responsibilities. Make one person responsible for one part of the application and the other person for the other. Define clear interfaces between both modules together, but leave the internal implementation to the one responsible. To make him more aware of bugs in his code, you could write unit-tests for him and point out when his code obviously doesn't behave according to the interface contract you specified together.

Through establishing clear code-ownership you can reach a better coexistence of your different styles. Also, when both of you are responsible for fixing the bugs in their own code, you won't have to navigate each others code often.

ContentLicense: CC BY-SA 4.0


答:
In addition to the initialization of an instance variable that is declared as final (see barjak's answer), I would also mention static initialization block.

You can use them as kind of "static contructor".

That way you can do complex initializations on a static variable a the first time the class is referenced.

Here is an example inspired by barjak's one:

```<code>public class dayHelper(){
    private static Map<String, String> days = new HashMap<String, String>();
    static {
        days.put("mon", "monday");
        days.put("tue", "tuesday");
        days.put("wed", "wednesday");
        days.put("thu", "thursday");
        days.put("fri", "friday");
        days.put("sat", "saturday");
        days.put("sun", "sunday");
    }
    public static String getLongName(String shortName){
         return days.get(shortName);
    }
}
</code>```

Title: Should I use initializer blocks in Java?

Body:
I recently came across a Java construct I have never seen before and was wondering whether I should use it. It seems to be called initializer blocks.

```<code>public class Test {
  public Test() { /* first constructor */ }
  public Test(String s) { /* second constructor */ }

  // Non-static initializer block - copied into every constructor:
  {
    doStuff();
  }
}
</code>```

The code block will be copied into each constructor, i.e. if you have multiple constructor you do not have to rewrite code.

However, I see three main drawbacks using this syntax:

It is one of the very few cases in Java where the order of your code is important, as you can define multiple code blocks and they will be executed in the order they are written. This seems harmful to me as simply changing the order of code blocks will actually change the code.

I do not really see any benefits by using it. In most cases, the constructors will call each other with some pre-defined values. Even if this is not the case, the code could simply be put into a private method and called from each constructor.

It reduces readability, as you could put the block at the end of the class and the constructor is normally at the beginning of the class. It is quite counter-intuitive to look at a completely different part of a code file if you do not expect that to be necessary.

If my above statements are true, why (and when) was this language construct introduced? Are there any legitimate use cases?

Body:
In addition to the initialization of an instance variable that is declared as final (see barjak's answer), I would also mention static initialization block.

You can use them as kind of "static contructor".

That way you can do complex initializations on a static variable a the first time the class is referenced.

Here is an example inspired by barjak's one:

public class dayHelper(){
    private static Map<String, String> days = new HashMap<String, String>();
    static {
        days.put("mon", "monday");
        days.put("tue", "tuesday");
        days.put("wed", "wednesday");
        days.put("thu", "thursday");
        days.put("fri", "friday");
        days.put("sat", "saturday");
        days.put("sun", "sunday");
    }
    public static String getLongName(String shortName){
         return days.get(shortName);
    }
}


问:
What are some famous one-liner or two-liner programs and equations?
I'm experimenting with a new platform and I'm trying to write a program that deals with strings that are no longer than 60 characters and I'd like to populate the data store with some famous or well-known small chunks of code and equations, since programming and math goes along with the theme of my software. The code can be in any language and the equations from any discipline of mathematics, just so long as they're less than a total of 60 characters in length. I suspect people are gonna break out some brainfuck for this one.

For example,

```<code>#include<stdio.h>
int main(){printf ("Hi World\n");return 0;}
</code>```

60 characters exactly!

Thanks so much for your wisdom!

答:
I like the newer feature of C# to return not null value:

```<code>var notnull = userInputName ?? "Captain NEMO";
</code>```

And their lambdas are pretty sweet also:

```<code>Func<int, int, int> addfn = (a, b) => a + b;
Func<int, int> addtwofn = (a) => addfn(a, 2);
var result = addtwofn(5); // returns 7
</code>```

Body:
I like the newer feature of C# to return not null value:

var notnull = userInputName ?? "Captain NEMO";

And their lambdas are pretty sweet also:

Func<int, int, int> addfn = (a, b) => a + b;
Func<int, int> addtwofn = (a) => addfn(a, 2);
var result = addtwofn(5); // returns 7


问:
How to debug weak references?
How can I test (what tools do I use) if my reference graph is correct and if objects are released at appropriate times (and there are no memory leaks)?

In my case I'm using Java, but answers related to another languages are welcome too...

答:
Weak references and the Reference class in general can be checked for its reachability by calling isEnqueued().  This is essentially asking if it is scheduled to be removed by the garbage collector (and hence the object which WeakReference points to is about to be nullified by the way WeakReference works).

However, this offers no guarantee that you'll be able to "catch" an object before it gets removed by the garbage collector.  It may be that one moment its reference is being utilized in another class and the next, that same instance has already gone out of scope and has since been removed by the garbage collector.

An alternative approach could be to keep a list of (normal) references to instances.  When you wish to see if it is the only reference left, create a WeakReference of that instance, and then set the normal reference to null.  If it is the only reference left, then isEnqueued() of the WeakReference of that instance should immediately return true. Technically, the garbage collector could run at any moment, even after the very line where you set the normal instance to null, however it is extremely improbable.  You could probably force the garbage collector to run prior if you want to further reduce this chance.

The only disadvantage of this approach is, yeah, you're potentially holding a bunch of references to objects that would otherwise be deleted.  Though you could remedy this by holding on to a list of SoftReference references to those instances, which is essentially like a WeakReference except that it won't let the reference go unless you absolutely needed more memory.

In this way, you can be sure that this class won't interfere with cleanup, and yet you can still keep track of if an instance would be deleted or not.  After you handle the event, however, you should do the responsible thing and remove your SoftReference afterwards thereby allowing your instance to be set free to roam the Elysian Fields.

I hope that helps.  Let me know if that answered your question.

Title: How to debug weak references?


答:
In looking at your responses in several of the comments I don't know if you realize that what you are experiencing is quite common, particularly when working in specialty fields where it takes domain experts (let's call them the scientist) to figure out how to incorporate and tailor algorithms for problems at hand.

Rather than complain about the scientist and expected them to change, just realize that you shouldn't expect the scientist to care much about "code quality". It is frequently hard to get other software developers to care about "code quality" let alone someone whose main interests lie in the domain and not the programming.

Where you go from here depends largely on the degree of confidence the "scientist" has in your ability to understand their work. If they have confidence that you can understand their code and won't muck it up when you modify things then there usually isn't an issue. They'll rely on your expertise.

However, if the scientist does not want you changing their code then it is highly likely that you haven't "earned" their confidence yet. If that is the case then rather than focusing on fixing the scientist, you should focus on "fixing" yourself. What I mean by that is to take steps towards gaining their confidence. Probably the easiest way to do this is as follows:

As part of your testing process:

Start turning the algorithms into something easier to understand (e.g. diagrams, PDL, math notation)

Learn to understand the algorithms.

Be sure to identify the edge cases.

Ask the scientist if your simplified "alternate" representation is correct

AND MOST IMPORTANTLY identify problems that you found; AND without sounding "accusatory" say something like "I was looking at the algorithm and noticed XYZ is it supposed to do this or is it supposed to do that?". Nothing will gain their confidence better than this bullet.

Once you start finding bugs AND have demonstrated an interest in their area of interest then the odds become much higher that at the very least they'll let you start modifying the code to make it more "professional". Frequently, they won't even feel the need to code up a prototype any longer. They'll just write something up in one of those "alternate" notations that you've taught them (without them even realizing it) and they'll have confidence that you'll know what they mean.

By all means, my first attempt would be to offer some suggestions on how the scientist could best help "communicate" better in order to help you; but it sounds like you've tried that. So the only step that you have control over is what you do. Earn their confidence and almost always the domain expert will be relieved to pass coding off to someone else and not have to worry about all the little details that go into writing code. They'd much rather be focusing on improving algorithms.

Sometimes, all you can do is offer a suggestion and leave it be after that. You won't impress your boss or a senior if you keep harping on something that they've already rejected or decided they don't want to do, even if you are 100% correct. In fact, this will damage a relationship, whether you are the suggestor or suggestee. Just focus on what YOU can do to make your job easier.

Title: Helping someone who is not and never will be a professional programmer write code that is more legible and usable to use and interpret

Body:
I am Elvis, trying very hard to learn to be Einstein. I work for Mort.

What the hell is this crazy idiot talking about!?!? (You only need to read the first few paragraphs)

If you don't feel like reading that link, basically, I am a professional programmer, and my boss is (this is scarily accurate):

the professional line-of-business programmer who lacks a degree in computer science but has a great deal of familiarity with Office and VBA, and who typically writes productivity applications shared amongst his coworkers

All that said, a large portion of my job is taking his cobbled together code and making it production ready. However, the very poor style and cargo-cultism makes this difficult. This is compounded by the fact that he is unwilling to read programming books or allow me to help him refactor his code.

Are there some other strategies for helping someone who is not a professional programmer, never will be a professional programmer write code going forward that is more legible and usable for me to use and interpret?


答:
Both code end up hard coded as 6 :

```<code>movl    $6, -4(%rbp)
</code>```

Check for yourself here

Body:
Both code end up hard coded as 6 :

movl    $6, -4(%rbp)

Check for yourself here


问:
What is the good explanation of Tennent's Correspondence Principle?
I found myself struggling to see what is this principle about and why is it so important for language design.

Basically, it states, that for every expression expr in language should be exactly the same as this construct:

```<code>(function () { return expr; })()
</code>```

Also, I have heard that Ruby obeys this principle, while Python doesn't. I don't understand why this is true, or if it is true at all.

答:
RE Python not following this principle.  Generally, it does follow the principle.  Basic example:

```<code>>>> x = ['foo']
>>> x
['foo']
>>> x = (lambda: ['foo'])()
>>> x
['foo']
</code>```

However, Python defines expressions and statements separately.  Since if branches, while loops, destructive assignment and other statements cannot be used in lambda expressions at all, the letter of the Tennent principle does not apply to them.  Even so, restricting oneself to using only Python expressions still produces a Turing complete system.  So I do not see this as a violation of the principle; or rather, if it does violate the principle, then no language that defines statements and expressions separately can possibly conform to the principle.

Also, if the body of the lambda expression were capturing a stack trace, or doing other introspection in the VM, that could cause differences.  But in my opinion this should not count as a violation.  If expr and (lambda: expr)() necessarily compile to the same bytecode, then the principle really concerns compilers not semantics; but if they can compile to different bytecode, we should not expect VM state to be identical in each case.

A surprise can be encountered using the comprehension syntax, though I believe this is not a violation of the Tennent principle either.  Example:

```<code>>>> [x for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [lambda: x for x in xrange(10)]]  # surprise!
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>> # application of Tennent principle to first expression
... [(lambda: x)() for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [(lambda x: lambda: x)(x) for x in xrange(10)]]  # force-rebind x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> map(lambda f:f(), map(lambda x: lambda: x, xrange(10)))  # no issue with this form
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
</code>```

The surprise is a result of how list comprehensions are defined.  The above 'surprise' comprehension is equivalent to this code:

```<code>>>> result = []
>>> for x in xrange(10):
...   # the same, mutable, variable x is used each time
...   result.append(lambda: x)
...
>>> r2 = []
>>> for f in result:
...   r2.append(f())
...
>>> r2
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
</code>```

Seen this way, the 'surprise' comprehension above is less surprising, and not a violation of the Tennent principle.

OwnerDisplayName: Andrew

Body:
RE Python not following this principle.  Generally, it does follow the principle.  Basic example:

>>> x = ['foo']
>>> x
['foo']
>>> x = (lambda: ['foo'])()
>>> x
['foo']

However, Python defines expressions and statements separately.  Since if branches, while loops, destructive assignment and other statements cannot be used in lambda expressions at all, the letter of the Tennent principle does not apply to them.  Even so, restricting oneself to using only Python expressions still produces a Turing complete system.  So I do not see this as a violation of the principle; or rather, if it does violate the principle, then no language that defines statements and expressions separately can possibly conform to the principle.

Also, if the body of the lambda expression were capturing a stack trace, or doing other introspection in the VM, that could cause differences.  But in my opinion this should not count as a violation.  If expr and (lambda: expr)() necessarily compile to the same bytecode, then the principle really concerns compilers not semantics; but if they can compile to different bytecode, we should not expect VM state to be identical in each case.

A surprise can be encountered using the comprehension syntax, though I believe this is not a violation of the Tennent principle either.  Example:

>>> [x for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [lambda: x for x in xrange(10)]]  # surprise!
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>> # application of Tennent principle to first expression
... [(lambda: x)() for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [(lambda x: lambda: x)(x) for x in xrange(10)]]  # force-rebind x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> map(lambda f:f(), map(lambda x: lambda: x, xrange(10)))  # no issue with this form
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

The surprise is a result of how list comprehensions are defined.  The above 'surprise' comprehension is equivalent to this code:

>>> result = []
>>> for x in xrange(10):
...   # the same, mutable, variable x is used each time
...   result.append(lambda: x)
...
>>> r2 = []
>>> for f in result:
...   r2.append(f())
...
>>> r2
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

Seen this way, the 'surprise' comprehension above is less surprising, and not a violation of the Tennent principle.


问:
What's so bad about creative coding?
I was watching Bob Ross paint some "happy trees" tonight, and I've figured out what's been stressing me out about my code lately.

The community of folks here and on Stack Overflow seem to reject any whiff of imperfection.  My goal is to write respectable (and therefore maintainable and functioning) code, by improving my skills.  Yet, I code creatively.

Let me explain what I mean by "coding creatively":

My first steps in a project are often to sit down and bash out some code.  For bigger things, I plan a bit out here and there, but mostly I just dive in.

I don't diagram any of my classes, unless I'm working with others who are creating other pieces in the project.  Even then, it certainly isn't the first thing I do.  I don't typically work on huge projects, and I don't find the visual very useful.

The first round of code I write will get rewritten many, many times as I test, simplify, redo, and transform the original hack into something reusable, logical, and efficient.

During this process, I am always cleaning.  I remove unused code, and comment anything that isn't obvious.  I test constantly.

My process seems to go against the grain of what is acceptable in the professional developer community, and I would like to understand why.

I know that most of the griping about bad code is that someone got stuck with a former employee's mess, and it cost a lot of time and money to fix.  That I understand.  What I don't understand is how my process is wrong, given that the end result is similar to what you would get with planning everything from the start.  (Or at least, that's what I have found.)

My anxiety over the issue has been so bad lately that I have stopped coding until I know everything there is about every method for solving the particular problem I am working on.  In other words, I have mostly stopped coding altogether.

I sincerely appreciate your input, no matter what your opinions are on the issue.

Edit:  Thank you all for your answers.  I have learned something from each of them.  You have all been most helpful.

答:
I always prefer clear, readable, simple code to any visually presented, UMLed, design-patterned code, where class/interface include pattern names like "ItemVisitor" (?!). Design patterns, OO techniques, and everything else are to formalize rules. That rules come from the common sense.

It is impossible to work without that formalization (unless you work alone on your own project) and the over-formalization increases the projects costs. Never disregard others' needs to understand your code. The best code is the simplest one.

Never hesitate to re-write your code. I'm going to get X downvotes (X>=10) for this, but I'll make it bold: reusability of code is not the most important thing.

Before staring coding you should consider the use-cases that code is going to implement. Because the software is to be used, and not to be developed. Usability, usefulness are two most important targets and it doesn't matter who is going to use that software - another developers of dependent parts of the project, or the end-user.

Title: What's so bad about creative coding?


答:
If your goal is just to keep a log of when objects are no longer being used, I'd look into ReferenceQueue, which should be more efficient than doing your own constant loops of Reference.isEnqueued() checks.

The choice about what kind of reference to use is trickier, and depends on when you want to be alerted and what kind of information about the object you need available. In particular, I'd also look at PhantomReference as an alternative to WeakReference.

It's a bit roundabout, but you add items to the ReferenceQueue by passing the queue into their constructor, e.g.:

```<code>Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
WeakReference<Foo> pr = new WeakReference(targetFoo, refq);
</code>```

In a separate thread, you can loop and wait for when changes occur:

```<code>Reference<Object> ref = fooQueue.remove(); // Blocks, poll() is also possible
</code>```

In this way, you can have code that monitors when certain objects are no longer strongly-reachable.

P.S.: Since the original Foo may be effectively gone, one way to maintain information about it is to make your own subclass of Reference, one that stores information about the Foo so that you can access it later.

```<code>Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
// Use custom subclass of WeakReference
MyReference<Foo> ref = new MyReference(targetFoo, refq);
ref.setStuff("hello");

// Later, in another thread, etc.

MyReference<Object> ref = (MyReference<Object>) fooQueue.remove();
String msg = ref.getStuff();
</code>```

Title: How to debug weak references?

Body:
How can I test (what tools do I use) if my reference graph is correct and if objects are released at appropriate times (and there are no memory leaks)?

In my case I'm using Java, but answers related to another languages are welcome too...

Body:
If your goal is just to keep a log of when objects are no longer being used, I'd look into ReferenceQueue, which should be more efficient than doing your own constant loops of Reference.isEnqueued() checks.

The choice about what kind of reference to use is trickier, and depends on when you want to be alerted and what kind of information about the object you need available. In particular, I'd also look at PhantomReference as an alternative to WeakReference.

It's a bit roundabout, but you add items to the ReferenceQueue by passing the queue into their constructor, e.g.:

Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
WeakReference<Foo> pr = new WeakReference(targetFoo, refq);

In a separate thread, you can loop and wait for when changes occur:

Reference<Object> ref = fooQueue.remove(); // Blocks, poll() is also possible

In this way, you can have code that monitors when certain objects are no longer strongly-reachable.

P.S.: Since the original Foo may be effectively gone, one way to maintain information about it is to make your own subclass of Reference, one that stores information about the Foo so that you can access it later.

Foo targetFoo; /* stuff */
ReferenceQueue<Object> refq = new ReferenceQueue<Object>();
// Use custom subclass of WeakReference
MyReference<Foo> ref = new MyReference(targetFoo, refq);
ref.setStuff("hello");

// Later, in another thread, etc.

MyReference<Object> ref = (MyReference<Object>) fooQueue.remove();
String msg = ref.getStuff();


问:
When should I use ZeroMQ and when should I use Akka?
My understanding of Akka is that it allows you to define groups of mini-threads ("Actors") and then have them communicate with each other (and do work) using events.

My understanding of ZeroMQ is that its a TCP socket library that allows threads to communicate with each other over TCP/ports.

My question: these seem like very similar concepts. However, I'm sure that in reality, they are meant to solve entirely different problems. So:

Intention-wise, what is the difference between these two tools? What different problems do they solve? Are there clear/concrete use cases where one is preferable to the other?

答:
You're right, they are separate technologies.

Akka uses ZeroMQ under the covers.  From their documentation:

Akka provides a ZeroMQ module which abstracts a ZeroMQ connection and therefore allows interaction between Akka actors to take place over ZeroMQ connections.

Akka provides an implementation of the Actor Model whereas ZeroMQ is trying to avoid your having to implement a brokered Message Queue system of some sort.

OwnerDisplayName: herpylderp


问:
Why is Software Development so far from being an engineering discipline?
I'm a strong advocate for Software Engineering, but even I must admit that we do not have many of the same tools, priniciples, and laws as other engineering disciplines.  Why is this?  And, what should we do to get there?</p>

答:
Two major reasons:

People don't want most of their software to be well designed, engineered solutions. While people don't want bugs in the software controlling a 747, they are clearly happy to allow them in their word processor if it means it costs $20 instead of $20,000.

Software exists primarily in an imaginary universe that usually crosses into this universe in explicitly defined areas. Much of the operation of software is essentially free from any physical limitations, and you can do just about anything as long as you have enough cpu and memory space, which more often than not you do.

Compare that to other disciplines, where you are dominated by physical constraints. Things have mass, they have tensile strengths, they have size, they have tolerance. Materials corrode, change, and have other interactions. Software is essentially information. It has no real size, and a 1 in software is an ideal 1. There are no tolerances on everything like in the physical world.

Consequently, there are very few first principles that are universal in software development. Almost every 'rule' or 'best practice' can be violated, and there are often situations where violating them is the right course of action for the given task. The lack of first principles is what prevents most software development from being the same kind of discipline as other engineering disciplines.

That's why the flight computer, where its requirements are dictated by the laws of the universe, can be engineered through a traditional process, and a line-of-business app, where you can do pretty much just about anything you want, won't be, nor should it.


问:
Forking an application for an "enterprise" customer
Note: this is mostly a technical question but I have to explain the business background first.

THE BUSINESS PART

I have a really interesting situation on my hands, at least interesting for me.

For the last 3.5 years I've been building a business/application called Snip Salon Software. It's scheduling software for hair salons. Significantly, I've specifically targeted hair salons as opposed to nail salons or tanning salons, which have different needs.

The business has experienced a certain level of success but nothing spectacular so far. I have 6 salons in my local area using the product.

Some time ago I was approached by a couple of entrepreneurs in the lash salon industry, which has different scheduling needs from hair salons. (The beauty industry is a surprisingly complex space!) These guys would basically like me to white-label my product for them so they can sell it as part of a "business in a box" type package they offer to start-up lash technicians.

THE TECHNICAL PART

So the challenge I'm faced with is:

I don't want to have one application that serves both hair salons and lash salons. I think it would quickly turn into a nightmare.

I don't want to have applications running mostly the same code. That would be silly.

And it's not just the features - all the branding, etc. will almost certainly be different for each version.

So what I think I want to do is first fork the codebase and set up separate hosting, etc. for the lash salon application. Then, over time, maybe I want to factor out the common parts (e.g. appointment reminder emails) into modules (I'm using Ruby on Rails, so I'm talking Rails engines) and then let each fork of my application use the same copy of each module. I would of course situate it so that each engine only contained functionality that was common to the two forks of the application.

My question: from a technical perspective, how would you handle this situation?

Feel free to chime in on the business side, too.

答:
I would have gone the other way - instead of making the common parts a reusable library, you should implement a plugins architecture and create plugins for the different types of saloons.

You'll have the main application code, which includes the common codebase and some infrastructure for the plugins(e.g. interfaces to be implemented in the plugins), and the plugins themselves will be different projects. You should also make it possible to create bundles of the application+specific plugins, so lash saloon guys can have a lash saloon bundle that'll be easy for their customers to install.

The main advantage of the plugins architecture over the shared modules architecture is that the main application needs to have a lot of boilerplate code for orchestrating the different modules\plugins. In the shared modules architecture you'll have to replicate that boilerplate code in each fork, but with the plugins architecture you only need it once, in the main application.


问:
Identify this programming style
Some of the legacy code I've inherited uses the fact that C# supports multiple assignment to write code like:

```<code>void DisableControls()
{
    ddlStore.Enabled                =
    ddlProgram.Enabled              =
    ddlCat.Enabled                  =
    btnSaveProxy.Enabled            =
    btnCancelProxy.Enabled          =
    btnViewMassManagerProxy.Enabled =
    grdPromo.Enabled                = false;
}
</code>```

It's a very pretty style, with all the = lined up neatly, and the value being assigned down at the bottom, but it's also a rather annoying one to work with.  (And yes, those are tabs lining things up, not spaces).

I would like to know what, if anything, this style implies about the original coder,  since I've only seen it on a few occasions before.  Does it indicate a C++ background?  .NET 1.1?  Just someone's personal preference?

Is there any reason that the chained assignment like this would be more efficient than individually setting each control's .Enabled?  Less so? (This part was answered by @gnat's comment: This way makes it easy to insert btnWhatever.Enabled = as new buttons are added and delete as some buttons are deleted)

Edit: Other elements of this person's style, assuming the whole file was written by one person (likely but not certain), include putting function arguments on the next line, and putting commas at the beginning of a line instead of the end of the previous line.  Example:

```<code>PromoUpdate[] GetPromoUpdates(
                            StateField field)
{
    List<PromoUpdate> updates   = new List<PromoUpdate>();
    foreach (PromoOptInState p in field.States.Where(
                                                    x => x.IsDirty))
    {
        updates.Add(new PromoUpdate() {
            promoCode   = p.Code
            , optIn     = p.IsOptedIn
        });
    }
    return updates.ToArray();
}
</code>```

It's very weird.

答:
That's a somewhat unique style.  I have seen somewhat frequent alignment of assignment operators in C, but not in a chained manner.  So you would see something like:

```<code>int foo    = 1;
int bar    = 2;
int bazbiz = 3;
</code>```

With the idea of calling out all assignments in one block and making it explicitly clear "this is where I'm assigning things."

Some would argue it improved readability if the compiler didn't provide default values for your variables.

Using it with chained assignments seems a bit more unusual.  Most cases I have seen of that looked like:

```<code>int foo = bar = bazbiz = 0;
</code>```

Title: Identify this programming style

Body:
That's a somewhat unique style.  I have seen somewhat frequent alignment of assignment operators in C, but not in a chained manner.  So you would see something like:

int foo    = 1;
int bar    = 2;
int bazbiz = 3;

With the idea of calling out all assignments in one block and making it explicitly clear "this is where I'm assigning things."

Some would argue it improved readability if the compiler didn't provide default values for your variables.

Using it with chained assignments seems a bit more unusual.  Most cases I have seen of that looked like:

int foo = bar = bazbiz = 0;


答:
I'm gonna go out on a limb and say Haskell, of all things.

Take a look at Johan Tibell's style guide here, or the code samples here. You'll see some of the same features there, like deep indentation on new lines or commas going before list elements.

I'm working in a project that has a fair share of people with Haskell background, and it's not hard to come across similar styling.

Agreed that it looks weird in a 'braces' language.

Title: Identify this programming style

Body:
Some of the legacy code I've inherited uses the fact that C# supports multiple assignment to write code like:

```<code>void DisableControls()
{
    ddlStore.Enabled                =
    ddlProgram.Enabled              =
    ddlCat.Enabled                  =
    btnSaveProxy.Enabled            =
    btnCancelProxy.Enabled          =
    btnViewMassManagerProxy.Enabled =
    grdPromo.Enabled                = false;
}
</code>```

It's a very pretty style, with all the = lined up neatly, and the value being assigned down at the bottom, but it's also a rather annoying one to work with.  (And yes, those are tabs lining things up, not spaces).

I would like to know what, if anything, this style implies about the original coder,  since I've only seen it on a few occasions before.  Does it indicate a C++ background?  .NET 1.1?  Just someone's personal preference?

Is there any reason that the chained assignment like this would be more efficient than individually setting each control's .Enabled?  Less so? (This part was answered by @gnat's comment: This way makes it easy to insert btnWhatever.Enabled = as new buttons are added and delete as some buttons are deleted)

Edit: Other elements of this person's style, assuming the whole file was written by one person (likely but not certain), include putting function arguments on the next line, and putting commas at the beginning of a line instead of the end of the previous line.  Example:

```<code>PromoUpdate[] GetPromoUpdates(
                            StateField field)
{
    List<PromoUpdate> updates   = new List<PromoUpdate>();
    foreach (PromoOptInState p in field.States.Where(
                                                    x => x.IsDirty))
    {
        updates.Add(new PromoUpdate() {
            promoCode   = p.Code
            , optIn     = p.IsOptedIn
        });
    }
    return updates.ToArray();
}
</code>```

It's very weird.


问:
Why does Java support brackets behind variables and even behind method signatures?
Java allows this:

```<code>class X{
    int i,j[]; // j is an array, i is not
}
</code>```

and even worse, it allows this:

```<code>class X{
    int foo(String bar)[][][] // foo actually returns int[][][]
    { return null; }
}
</code>```

Okay, the reason for this might be that it was lent from C/C++. However, Java meant to be easier than C/C++. Why did the Java inventors decide to allow this hard-to-read construct. The convoluted types of C where the variable name is in the middle of the type are just hard to read and provoke programming errors.

Especially the brackets behind the method signature. I have never seen these in use and that is for a good reason. No one looks behind the signature when checking the return type of a method. While the first example may save some keystrokes (because int does not have to be written twice), the brackets behind the signature do not even save any, so I see absolutely no gain here.

So is there a good reason for this (especially the second one) that I am missing?

答:
The question can be divided into "Why does Java C support brackets behind variables and even behind method signatures?" and "Why would Java inherit so much from C?"; Java also inherited other weird syntax, especially that for switch (why not use curly braces as for everything else and use : and break ?).

To answer the first question - I believe back in the 70s in language design they didn't focus that much on readability but rather on performance. Back then programs weren't that complex or large so readability wasn't a main concern.

To answer the second question - back in the middle '90s when Java appeared most programmers worked in C and C++; C++ had a large success because it was a superset of C by adding OOP. Java simplified C++ as much as possible but tried to keep it close as syntax as much as as possible so that programmers can transit more easily from a language to another.

I actually believe that most Java programmers aren't even aware the code presented is a valid one (at least the second one) and hence do not use it when writing. The main thing that lead to this is a great thing called - Java Code Conventions which is most likely to be read by programmers than the language specification itself. Also this kind of stuff is a disadvantage of backwards compatibility.


答: From a business perspective, I think you're right to go with the simplest possible method of splitting the codebase and then gradually working on rejoining them.  While it might sound best, from a technical perspective, to rearchitect and rewrite your core application, it doesn't make sense to put in all that work up front unless you're absolutely certain that the lash project will be a profitable long-term business relationship - for all you know, they could flake out on you & be gone in 6 months.

Title: Forking an application for an "enterprise" customer

Body:
Note: this is mostly a technical question but I have to explain the business background first.

THE BUSINESS PART

I have a really interesting situation on my hands, at least interesting for me.

For the last 3.5 years I've been building a business/application called Snip Salon Software. It's scheduling software for hair salons. Significantly, I've specifically targeted hair salons as opposed to nail salons or tanning salons, which have different needs.

The business has experienced a certain level of success but nothing spectacular so far. I have 6 salons in my local area using the product.

Some time ago I was approached by a couple of entrepreneurs in the lash salon industry, which has different scheduling needs from hair salons. (The beauty industry is a surprisingly complex space!) These guys would basically like me to white-label my product for them so they can sell it as part of a "business in a box" type package they offer to start-up lash technicians.

THE TECHNICAL PART

So the challenge I'm faced with is:

I don't want to have one application that serves both hair salons and lash salons. I think it would quickly turn into a nightmare.

I don't want to have applications running mostly the same code. That would be silly.

And it's not just the features - all the branding, etc. will almost certainly be different for each version.

So what I think I want to do is first fork the codebase and set up separate hosting, etc. for the lash salon application. Then, over time, maybe I want to factor out the common parts (e.g. appointment reminder emails) into modules (I'm using Ruby on Rails, so I'm talking Rails engines) and then let each fork of my application use the same copy of each module. I would of course situate it so that each engine only contained functionality that was common to the two forks of the application.

My question: from a technical perspective, how would you handle this situation?

Feel free to chime in on the business side, too.


答:
```<code>/*********************************************************************
 * People who do indent that way also tend to write pretty comments. *
 * It looks so very pretty, so very professional. Except it's not.   *
 *********************************************************************/
</code>```

Suppose a variable needs to be renamed for some reason. That simple change might mean lots of superfluous changes because the original author succumbed to the "pretty code" programming style. You as the maintainer have to look at the entire body of code to see if you have broken the prettiness of the code.

Suppose the pretty commentary is flat out wrong. It doesn't describe why the code exists or what the code does. It's pretty, but wrong. Perhaps the original author rethought the design but didn't change the pretty comment. Perhaps some previous maintenance programmer fixed a bug but didn't fix the pretty comment. Perhaps that happened over and over.

There's a big difference between beautiful code and overly pretty code. Beautiful code doesn't need tons of makeup.

Update

That code aligned on the equal signs certainly does look prettier, and is perhaps easier to read, particularly when the targets on the left hand side have only slightly dissimilar lengths. This alignment also serves as a form of self-documenting code to show that that block of assignment statements are somehow related to one another. For these reasons, Steve McConnell advocated aligning the equals signs in a block of assignment statements in the first edition of Code Complete.

However, he withdrew this recommendation in subsequent editions. Instead he explicitly admonished against this style:

Do not align right sides of assignment statements.

His rationale for completely reversing his recommendation in this regard was that the huge maintenance cost associated with this style does not justify that slight increase in readability and comprehensibility.

Regarding the comma-first style, I've seen it and I don't like it. I put it in the same class as yoda conditions (if (42 == foo) do_something(); and if ("foobar".equals(baz)) do_something_else();). To me, both the comma-first and yoda conditions are too jarring to how I normally read and think.

All of this is of course a programming religious issue. Some people love their block formatted assignment statements, others love that comma-first style, yet others love their yoda conditions. My own rule: When I'm maintaining someone else's code I had better adapt to that author's style. New code? If the project give some leeway on style, I'll write that new code in my own preferred style.

Title: Identify this programming style

Body:
/*********************************************************************
 * People who do indent that way also tend to write pretty comments. *
 * It looks so very pretty, so very professional. Except it's not.   *
 *********************************************************************/

Suppose a variable needs to be renamed for some reason. That simple change might mean lots of superfluous changes because the original author succumbed to the "pretty code" programming style. You as the maintainer have to look at the entire body of code to see if you have broken the prettiness of the code.

Suppose the pretty commentary is flat out wrong. It doesn't describe why the code exists or what the code does. It's pretty, but wrong. Perhaps the original author rethought the design but didn't change the pretty comment. Perhaps some previous maintenance programmer fixed a bug but didn't fix the pretty comment. Perhaps that happened over and over.

There's a big difference between beautiful code and overly pretty code. Beautiful code doesn't need tons of makeup.

Update

That code aligned on the equal signs certainly does look prettier, and is perhaps easier to read, particularly when the targets on the left hand side have only slightly dissimilar lengths. This alignment also serves as a form of self-documenting code to show that that block of assignment statements are somehow related to one another. For these reasons, Steve McConnell advocated aligning the equals signs in a block of assignment statements in the first edition of Code Complete.

However, he withdrew this recommendation in subsequent editions. Instead he explicitly admonished against this style:

Do not align right sides of assignment statements.

His rationale for completely reversing his recommendation in this regard was that the huge maintenance cost associated with this style does not justify that slight increase in readability and comprehensibility.

Regarding the comma-first style, I've seen it and I don't like it. I put it in the same class as yoda conditions (if (42 == foo) do_something(); and if ("foobar".equals(baz)) do_something_else();). To me, both the comma-first and yoda conditions are too jarring to how I normally read and think.

All of this is of course a programming religious issue. Some people love their block formatted assignment statements, others love that comma-first style, yet others love their yoda conditions. My own rule: When I'm maintaining someone else's code I had better adapt to that author's style. New code? If the project give some leeway on style, I'll write that new code in my own preferred style.


问:
Looping Exhaustive Test Cases - A Good Practice?
Sometimes we have code like this:

```<code>private static final List<Goat> INEDIBLE_GOATS = [GOAT_A, GOAT_B, GOAT_C]

void eatGoat(Goat goat) {
   if(INEDIBLE_GOATS.contains(goat)) {
       throw new CantEatGoatException();
   }
   ...
}
</code>```

Should it best tested (along with whatever tests for the actual eating) as:

```<code>for(Goat goat: INEDIBLE_GOATS) {
   // forgive abuse of syntax
   assertThrows(CantEatGoatException, eatGoat(goat));
}
</code>```

Or more like?

```<code>assertThrows(CantEatGoatException, eatGoat(GOAT_A));
</code>```

Should tests verify each and every sort of inedible goat? Or should they test a representative goat from the list and trust that it works for the other goats?

答: The second test seems more accurate to me. If you put a Goat within your List, you expect that Goat to be a foobarable Goat (that is, you expect to get true from your method).


问:
How is quality important to the programmer, the person?
I didn't ask how the quality of the software is important to the product itself, the customers/users, the manager or the company. I want to know how it is important to the programmer that build it.

I'll be interested in any books (please specify the chapter), articles, blog post, and of course your personal opinion on the subject regardless your experience.

答:
The quality of what I worked on is of the utmost importance to me - sometimes to my detriment (failed deadlines mostly). As long as I can take pride in what I've done on the project, then that's what really matters to me.

Quality of the product as a whole, is mostly a bonus.

Consider that I'm coming from a viewpoint where, as an employee, the software I've made has always been for someone else, so I've never really had any emotional ownership for the product; just the code inside it.


答:
Seems like you're just pushing the logic around.  How about:</p>

```<code>assertTrue(FOOBARABLE_GOATS.contains(goat));
</code>```

Title: Looping Exhaustive Test Cases - A Good Practice?

Body:
Sometimes we have code like this:

```<code>private static final List<Goat> INEDIBLE_GOATS = [GOAT_A, GOAT_B, GOAT_C]

void eatGoat(Goat goat) {
   if(INEDIBLE_GOATS.contains(goat)) {
       throw new CantEatGoatException();
   }
   ...
}
</code>```

Should it best tested (along with whatever tests for the actual eating) as:

```<code>for(Goat goat: INEDIBLE_GOATS) {
   // forgive abuse of syntax
   assertThrows(CantEatGoatException, eatGoat(goat));
}
</code>```

Or more like?

```<code>assertThrows(CantEatGoatException, eatGoat(GOAT_A));
</code>```

Should tests verify each and every sort of inedible goat? Or should they test a representative goat from the list and trust that it works for the other goats?

Body:
Seems like you're just pushing the logic around.  How about:

assertTrue(FOOBARABLE_GOATS.contains(goat));


问:
A license like the LGPL, but compatible with JavaScript
I have written a library that is quite extensive and has taken up a lot of my time, so I would like to license it properly. The LGPL seems to have many of the things I want, but does not work with Javascript or other interpreted languages.

Here are the things I want my license to say:

My library can be used in commercial application (either web or desktop applications).

My library can be used in open source applications (again, any platform is fine).

You may not redistribute my unmodified library in any form, except for when the javascript is downloaded to the client's browser.

I would like to remain as the copyright owner.

If possible, I would like users of my library to be able to use other libraries under any license (though this is less important).

I am fine with distributing source of my library, and I'll have to since it's JS, the thing I don't want is others distributing my unmodified library and saying it is purely their work. I am ok with people modifying and redistributing the library, though I would rather they submitted their work to me and I would give them credit. If they do modify and redistribute the library, they must give me partial credit.

I have also thought about using the MIT license, but it clearly states that people could redistribute my library unmodified, which is the most important thing to me, to make that impossible.

I sincerely apologize if an identical question has been asked on this network, I have done several days' research and have not found one (this is the closest I've gotten, but the answer didn't help me).

Also, IANAL so if any of this is legally contradictory or impossible, please explain rather than just stating that it is impossible.

答:
This is legally contradictory.

What makes a license "open source" is that it gives the user the right to modify and distribute the source.  Indeed, some licenses, like the GPL, compel the user to distribute the source, though others, like the MIT license, simply say that the users may do this.  To quote the Open Source Foundation

The program must include source code, and must allow distribution in source code as well as compiled form. Where some form of a product is not distributed with source code, there must be a well-publicized means of obtaining the source code for no more than a reasonable reproduction cost preferably, downloading via the Internet without charge. The source code must be the preferred form in which a programmer would modify the program. Deliberately obfuscated source code is not allowed. Intermediate forms such as the output of a preprocessor or translator are not allowed.

In terms of "retaining copyright", this is pretty easy.  As long as you don't explicitly give up your copyright, or explicitly assign it to someone else, you retain it.

If you are talking about letting users modify your source, and then distribute it, that pretty much lets them make a trivial modification, but I gather that when you say you want to let users modify, you mean, you want to let them submit changes to you that you can decide to use (or not.)  No special license is needed for that.

It sounds to me that you really just want to use a basic closed source license.


问:
Why don't languages include implication as a logical operator?
It might be a strange question, but why there is no implication as a logical operator in many languages (Java, C, C++, Python Haskell - although as last one have user defined operators its trivial to add it)? I find logical implication much clearer to write (particularly in asserts or assert-like expressions) then negation with or:</p>

```<code>encrypt(buf, key, mode, iv = null) {
    assert (mode != ECB --> iv != null);
    assert (mode == ECB || iv != null);
    assert (implies(mode != ECB, iv != null)); // User-defined function
}
</code>```

答:
Eiffel has Implication

It actually has even more. It has a number of semi-strict operators as well as strict.

The reason programmers do not use such things is because they are never trained to know precisely what they are, how to use them, and when to use them -- as well as how to design with them. Because they are never trained, they never ask for it from the compiler writers, which is why the compiler people do not bother putting such mechanisms in the compiler. When Computer Science students and Shade-tree programmers begin getting a more rounded education, then the compilers will start catching up.

It turns out that once you have a language with such Boolean operators and you know how to design with them and use them, then you use them.

In Eiffel the use of the "implies" keyword is rather prominent because of Design-by-Contract due to the Boolean-heavy nature of contract assertions. There are some contracts that can only be written properly and efficiently with the "implies" operator. This then begs the comment that languages without contracts are further without cause to look at, train, and implement the use of implication.

Add to this that most programmers are "math-and-logic-weak" tells us the remainder of the story. Even if you are math-and-logic-heavy in your education, when one chooses a language that does not implement constructs such as implication, then one tends to think such things are unnecessary or not useful. One rarely questions the language and gets into an echo-chamber of: "Well the compiler guys don't see the need" and "Well the programmers don't see the need" -- endless and vicious circle.

Instead, the compiler people need to back up to the theory, write a language notation that is suggested or implied by the theory (e.g. Object Oriented Theory) regardless of what the unwashed masses of programmers think or ask for. From there, professors, teachers, and other professionals need to expertly train young mush-minds based on raw theory and NOT "theory-through-the-language-lens". When this happens, people will suddenly wake up and realize what they have been missing and what has been foisted on them.

Right now -- there is so much theory out there that masquerades as Object Oriented, but is just O-O-through-a-glass-darkly-of-[pick-your-language]. One cannot read most "theory" books on O-O because they want to interpret what the theory is through the lens of some language. Totally false and incorrect. It would be like teaching math-based-on-my-calculator or my slide rule. NO -- one allows reality to teach one about itself and then uses a notation to describe what one observes -- that's called "science". This other mash called O-O-based-on-language-X is so skewed as to barely represent reality.

So, step away from the language, take a look at raw theory, and begin again. Do not let limitations, constraints, and paint-jobs of a language tell you what the theory is. Simply let the reality of the theory dictate its own notation and then move from there into formulating a language.

From there, you will start to get how implication and "implies" is not only useful, but elegant and very cool!

Have a great one!