It depends upon your situation. We did it because we started selling our system in China and knew that it would immediately get pirated by many corporations there.
Watermarking is a good thing, but it suffers the same problems that all the other schemes do: The code can be bypassed by editing the executable. CRC checks against the executable's size (to see if there have been changes) also get edited out.
This is what crackers ofter do, literally change the executable to not execute functions, or change the evaluation results of a license check - this prevents the watermark or dongle failures.
You have to really obfuscate and hide your licensing, honeypot it with standard licensing code, but include some well hidden code that is in a non obvious place, is evaluated routinely so that it doesn't look like one time startup code, and doesn't emit a license warning, it just subtly screws up the software's operation.
The standard licensing will point out license issues to your legitimate customers, the obfuscated code will cause problems for the 'cracked' versions. We had to do something similar to this before selling our product in China because our *very* expensive system was sure to be pirated by corporations there.
...in order to defeat someone seriously interested in breaking your copy protection. Misdirection is key.
Dongles, node locked licenses, networked licenses - all rather easily crackable and to be honest - primarily seemed to be designed to eke out maximum revenue from people who actually bought the software.
The only thing likely to give you some serious protection is to obfuscate your licensing scheme. The best way I've found to do this is to have a non-obvious component actually doing the licensing evaluation (periodically as part of some normal functional operation) and if that fails to subtly screw up the operation of the software. You still want to have standard 'relatively easy to tear out' protection so that legitimate users get notifications of a bad configuration or license, but what you're trying to do is make the software useless for people pushing it on a torrent/warez site.
For example, let's say this is Windoze software and you've got some COM+/MTS components in it. Don't have the main executable do anything other than the standard license checking. The DCOM/COM+ object will actually do the quiet validation, and if the licensing fails, it doesn't warn the user, it simply signals another DCOM/COM+ object to operate slightly differently, then that one does something wonky to screw up the experience.
Ultimately, there's no ultimate protection possible, but if you make it hard enough, people will likely avoid trying until the benefits outweigh the effort. Hopefully by that time you're profitable;).
No. I allow my library providers to abstract browser behaviour and trust that if any browser behaves significantly differently in future (notably in this case violating the W3C recommendations for the DOM API) that the library will adjust for this. This is one of the advantages of using the libraries you are arguing against.
How on earth am I arguing against libraries? Lol. I'm arguing against you relying on the user catching the error, and acceptance testing catching the error, and your "staggering" assumption that these errors are '...not error conditions that could plausibly occur at the user level...' (I pluralized your quote.) You're literally arguing that you don't have to account for these types of errors because (a)they could not plausibly occur at the user level and (b)they would be caught at acceptance testing. Well, which is it? Will they be caught by users at acceptance testing or not? Acceptance testing has to be performed as an end user would experience, so if it isn't plausible that these errors could percolate to the user, how would acceptance testing catch them?
I find it a little disengenous to suggest that I'm arguing against libraries because I think you're being cavalier with error handling.
Err.. no. By "acceptance testing" I mean an automated test in an environment like Selenium or something similar that is run on every code check-in with all target browsers and which won't allow anyone to make modifications to the code while a test is failing.
I'm sorry but unless you're referring to hardware black-box testing, acceptance testing involves the customer whether it is user acceptance testing or automated in some fashion. What you are describing is regression testing.
While you appear to be making a lot of assumptions about the practices I apply to my work on the basis of a three-line code example which you haven't been able to identify any *actual* problems with, only potential problems that don't apply in the specific circumstances we were discussing.
You're really making an effort not to "get it." I have identified actual problems with your idea of "elegant." You simply seem to ignore them. Nobody said the code doesn't work, but your approach to writing elegant code has clear and objective software engineering weaknesses which I have described to you at length. It doesn't mean you don't know what you're doing, it doesn't mean it doesn't work perfectly, it does mean that a codebase littered with "elegant" coding like you provided is problematic (again, for the reasons I have already proscribed.)
Given this situation the actual operations performed by the code in question seem particularly relevant, as that code is all you have to go on in making your assessment.
Indeed, and that assessment is about your claim of "elegance."
And you still haven't justified why you believe any of the following are bad practices:
I didn't claim that closures are bad practices, I claim that the way that you use an anonymous function without any context as to why you need and call it "elegant" is a poor software engineering choice.
* use of closures (which, if it is a bad practice, means the entire field of functional programming is apparently doomed to failure)
A bit melodramatic are we? I'm somehow against closures because I believe you're using an anonymous function in a line of code with multiple evaluations and disagree totally with you that it is "elegant."
* use of fluent interfaces (which, if it is a bad practice, means that several prominent and well-respected writers on software engineering best practices are completely and utterly wrong)
I think an objective objective observer would find the mess you posted simply method chaining. Maybe you should read up more on what the purpose of a fluent interfa
Yes, I have, and yes, I agree that they do; however, a functional approach doesn't mean scattering anonymous functions throughout your code and then calling it elegant and re-usable because you (a)find it clear and you (b)can cut and paste the code wherever you need to re-use it.
They woke the sleeping giant that was Intel...
on
AMD: What Went Wrong?
·
· Score: 1
...Intel had basically sat back on its a**, AMD make some great design decisions and Intel said "Oh sh**, how'd we suddenly become second...?" From that moment on there was only going to be one winner in the PC chip space.
This is not an error condition that could plausibly occur at the user level. For it to happen, the referenced element would have to not be defined on the page, yet the page completed loading without error. Any form of acceptance testing will catch the possibility of such a condition before deployment.
Wow. Staggering. You are able to predict the way different browsers on different operating systems will work in the near and distant future!
You also have an incredible amount of faith in what you termed "acceptance testing" - in other words, let the user (the acceptance tester) catch the error.
And even if it does, what's the cost? A feature stops working, gracefully, because the method used to integrate it into the page was intentionally one based on the principle of graceful degradation
You seem to continually getting confused between talking about practices and talking about the specific operations you put in your "elegant" line of code. Who cares what the particular line of code does, I don't. What I am pointing out about your line of code are the bad practices you are exemplifying as "elegant."
What's the cost? Time, money, frustration. People who code the way you do in your example make things more difficult for anyone else to find, fix, and test problems. The cost in one anonymous single line "elegant" function? Minimum, but measurable. The costs when someone like you have been working on a product for a long time, littering the code base with your 'elegance'? Large.
As you're a software engineer, I assume that you're aware of the finding that the cost of code both in terms of time to originally write and time required for maintenance over the life of the project is proportional to the number of lines, regardless of how many features those lines implement?
Actually, you've convenient left out the impact of good engineering practices on both the time to implement or extend, and the effort to support and maintain. You're apparently a "pound of cure" kind of person. Maybe you're just used to dealing with small projects, such as a series of web pages. So that you find that cutting corner on engineering gives you a better profit margin. It doesn't unless spending more time fixing things is part of your business model.
You're really not going to be successful trying to argue that making code less testable and maintainable is a good thing; although you keep pretending that someone is saying the code is untestable and unmaintainable which are, of course, different things. Any code is testable in some fashion, and any code is maintainable is some fashion.
The typical OO approach of putting them in an object simply doesn't work properly
Why do they have to be in an object? This isn't some OO approach to engineering practices. You shouldn't write C code that looks like the example provided. It would be just as bad.
FFs, you really don't understand basic software engineering principles.
Don't confuse that with someone saying "you can't program" - they are different things.
How are the two ways you demonstrated for returning different in clarity? They basically aren't. They're total crap either way because of the rest of your "elegant" code, lol.
Why is it a bad practice to perform evaluations in your return statements if you are a software engineer? Because anyone who has to debug your glob of strung together operations will need to actually change the code in order to evaluate its operations. This is bad. Is it a felony? No. Is it better software engineering to already have code in place that can be debugged without changing any code? Does this mean that you cannot (not to be confused with should or should not) perform multiple evaluations in a single line of code? Of course not, but the goal should be to avoid it. Not celebrate it as "elegant."
All of the rest of your "points" are exactly the same, poor engineering practices (some laughably poor such as the one where you claim the code is "very reusable" because you can cut & paste it on any page you need it on!)
One of your statements hints at the fundamental difference between the way programmers and software engineers think...
Yes, you need to be vaguely familiar with jquery to understand what I wrote, but if you aren't familiar with the tools I'm using, what are you doing trying to maintain my code?
That, in a nutshell is the difference. It isn't "your code" that somebody else has to maintain. It belongs to the company, or the client.
If you want to write code just for yourself, nobody care how badly engineered it is; but, if you're writing code for someone who is paying you to do it, you should make every reasonable effort to make it easy to debug, reuse, and extend.
The difference between a programmer and a software engineer in this case is that their definition of "reasonable effort" is apparently vastly different.
I was debugging very similar code only yesterday, and didn't find it even remotely difficult.
- The staggering naivete this statement exhibits is amazing. Is every programmer working on a project going to have the same skills? The same levels of familiarity with a giving API or framework that you do? Is everyone just supposed to be you? Lol.
Writing test cases for a nested function is likely to be just as challenging, yet the function I wrote *must* be nested, because it is required to have access to a copy of an outer-function local variable
The very fact that you're trying to argue that it is just as easy to write test cases for anonymous functions as it is for non-anonymous functions is ridiculous. Trying to artificially constrain the non-anonymous function to being nested is also disingenuous.
You also seem to be ignoring that it is clearly and unequivocally simpler to test a function that belongs to one object/class/namespace and is used in multiple locations than it is to test functions on a per usage basis as would be the case of an anonymous function.
Anonymous functions do have important usage cases, i.e. when you must manage a very particular scoping issue.
The reason that JavaScript code is littered with them is because people find them convenient. Plain and simple.
I contend that you're only saying that because you're unfamiliar with the environment. To anyone who knows it more than moderately well, what I wrote is clear, obvious, and the natural way of doing it. What other way should it be done?
I contend that you don't understand what the word "elegant" means, much less what good engineering practices are.
Are you familiar with any other programming environment in a professional capacity? It seems highly doubtful. I am familiar with the environment, as well as many others. It's why I can recognize the problems that you obviously don't see.
I disagree completely. Programming an imperative language sloppily in such a way that it makes a logical representation that barely looks similar to functional programming (Haskell-ish shall we say) in no way connotates an advantage.
You also seem to be missing the point the original code submitting was making. He/she was suggesting that this code was an example of elegant web programming, lol.
Hell, people who want to embrace functional programming in JavaScript are more likely to agree with my assessment of the code. One of the advantages to using a functional programming style is abstraction and code reuse. Functional programming methods stand up better over time in a code base because they're implicitly more likely to be agnostic of state.
I'm sorry, but it really isn't worth my time to try and explain to you all that is wrong with your reasoning above, so I'll just address your first paragraph and your humorous 'functions.'
In which case it returns an *empty jQuery object*, not NULL. newToggleElement then would be a clone of the empty jQuery object, so its ok to use.click() on it (verified in the console). So this code is safe, and will *not* cause Javascript errors assuming jQuery has been loaded (safe to assume).
You are arguing that you don't need to bother checking if a valid object comes back because it won't throw up a runtime error. Wow, let's just push the error identification onto the user then, right? Lol. I mean, seriously, it is bad enough that you don't check to see if something is a valid operation when it very well might now be, but then it's ok for it to fail silently?
The rest of the arguments simply expose that you're not used to creating re-usable software components, or you're being disingenuous in your examples. You act as if you should be using this in the non-anymous function, you shouldn't. Everything used in that function should be passed to it unless it is a global exposed by a framework you are using. I will presume you're just being disingenous because I doubt you don't know how to write a function properly. Your really poor function attempts are indeed unclear in their operation because that's how you wrote them (again, presumably on purpose rather than through incompetence.)
Now stop trolling about stuff you don't understand
There are many times when an anonymous function or class is the simplest, idiomatic (in the language in question) thing to do.
Yes, I agree, especially about it being idiomatic with JavaScript. It isn't idiomatic because that's how you should be doing in in JavaScript, it is idiomatic because tons of JavaScript programmers do it that way.
I also agree that it can be very simple, but it is also equally simple for it to not be an anonymous function. Is it as "easy" as doing it anonymously? No. Is it better from an engineering practices standpoint? Yes. Writing test cases for anonymous functions seems likely to be 'challenging';).
Event handlers in Java and GWT frequently are anonymous inner classes, but it often ends up being easier to read than writing a custom class that handles each different event
Event handlers in Java and GWT are often found to be anonymous, but they shouldn't be. Most of the time if you find people using anonymous functions/methods it is because they have not architected the solution to their problem properly to account for some edge case (especially in Java) or they are just lazy. I disagree pretty strongly that it is easier to read than writing a custom class that handles those events for many reasons, but mostly because of the opportunities for centralization of the code, re-use opportunities, and the ability to create tests for that class.
Now, all of that aside, there are surely cases where an anonymous function could/would be appropriate, but they are exceptions - not the general rule.
Similarly, consider that since he was typing it from memory, he may have taken shortcuts that he might not use in production code, just as one often writes a Perl one-liner differently than one would a Real Program
I can only comment on the code he/she actually submitted in support of "some of the most elegant web programming I have ever seen."
I think people (on both sides of the JavaScript debate) are mixing up the differences between what you can do with the language and what people tend to do with the language.
The code that was given was, imho, the antithesis of what a software engineer should produce. Does it mean it doesn't work? No. Does it mean it isn't clever? No. Does it mean it is buggy? No. It is, however, poor software engineering.
Well, it is unsafe, is anti-reusability, unclear, and impossible to debug without rewriting it to see why it doesn't work or suddenly stopped working. Defining a function inline to your statement, and in that function performing evaluations in your return call that are based upon objects that may be null when you execute an operation on them?
There's no need to go verbose for verbositys sake, and that piece of script is pretty neat.
There is a need to go verbose for the sake of everyone else who may ever have to work in the same codebase.
If you place a completely green web-developer in front of it, sure, he might have a hard time reading it, but if jQuery is a tool you use, and webdevelopment what you do, then this really shouldn't be much of a problem at all.
I'm not trying to denigrate you in any way, but this type of attitude is the difference between programming and software engineering. It is the discipline to do extra work that is tangibly less fun than doing clever or fun things.
I don't enjoy long variable names. I don't enjoy modified Hungarian notation. I don't enjoy seeing an obfuscating and clever way to manipulate something but then do it a more plodding and clear (if equally efficient) way. I enjoy software architecture, but I don't enjoy writing up the design. I don't enjoy the ridiculously long meetings involved in matching up the design to the spec to the requirements. I don't enjoy putting in long comments to make absolutely sure someone coming in to fix a bug in the future is aware of the caveats of the possible changes they could make.
I do these things because I need to do them for the sake of the codebase/product/Company/Investors.
Simple: clear, debuggable, logically organized, and debuggable code.
Don't define functions inline of your statement. Don't perform evaluations in your return statements. Avoid calling methods/functions on objects via the return of another evaluator.
The code sample he provided is counter to reusability, readability, unsafe in that it doesn't evaluate possible nulls, and arguably impossible to debug.
It has nothing to do with being a JavaScript guy or not. It has everything to do with the difference between being a programmer and a software engineer. They are two different things.
JavaScript can do amazing things, but it's a total disaster if you're coming from a more traditionalist background.
Let me give you a taste of what's to come for you:).
Let's say you have an Applet/ActiveX Control/Plugin of some type that your company has built and needs to be scriptable from JS, and it must also be able to call into JS (JavaScript devs can register for events, notifications, console/logging messages, et cetera...)
You add a new feature to your Company's doohickey. Now you need to test it properly.
Your customer set requires that you need to test on OSX Snow Leopard, OSX Lion, Windows XP, Vista, Win 7, OpenSUSE, Redhat, and Ubuntu. On each of these operating systems you need to test on the most popular browsers, so you get jiggy with Safari, Firefox, Opera, IE7, IE8, IE9, Konquerer, et cetera... Then you, depending upon the plugin's architecture, need to test on both 32-bit and 64-bit versions of the plugin in each browser on each operating system.
That's not even getting started with Mobile, or JRE versions, or different deployment types, code signing, et cetera, ad nauseum, ad infinitum.
If you think you don't need to test like that, you're in for a rude awakening my friend... For example, this very testing led to our discovering that in Firefox, on Windows 7 rapid LiveConnect usage between an Applet and JavaScript is perfectly fine if the applet has focus, or another windows has focus, but causes total freezing of Firefox/Java Plugin IF THE FOCUS GOES TO ANOTHER ELEMENT ON THE SAME WEB PAGE. How's that for crazy sh**?:) LOL.
Anyhow.
Browser application development is a nightmare.
I would pay good money for them to rip JavaScript out and everyone get together (yeah, I know, pipe dream) and come up with a client side scripting language that rocked oldSk00l.
First and foremost, self-discipline. Yes, I know, it is hard.
Be prepared to go unrewarded for your "extra efforts" which are in actuality basic software engineering tenets.
Do NOT design at the keyboard. You can be agile without designing at the keyboard, you can be a traditional waterfaller without designing at the keyboard, you can be a spiralist without designing at the keyboard. When you find yourself making design decisions at the keyboard, unless they are truly trivial (and the litmus for this will change with experience) WALK AWAY from the keyboard.
Ensure that the people who assign you work understand the caveats of what they are currently asking you to do. Even if this makes people think you are being negative, give them the information they don't even realize they need to make better decisions. YOU are the expert on what will happen when implementation happens. For example, if your product manager or account manager or <insert PHP - pointy haired person - here> wants a milestone that includes features that are poorly defined (either through their own recalcitrance or through, most likely, a customer who doesn't know what they really want) it is your responsibility to be the a**hole negative nerd who makes it CRYSTAL CLEAR the implications of doing such a thing. That doesn't mean you don't do it, it means you sacrifice whatever small amount of political capital you have with them to ensure that everyone is on the same page about the potential outcomes. You're going to be shocked by what people can 'pretend' to not recall;).
Think about problems in a fashion designed to allow for systemic flexibility because, just like in war, everything goes to plan until the first shot is fired.
Think about the long term viability and accessibility of the code you write (good variable names - really, I know you've heard it a thousand times probably, but it makes all the difference in the world.) When the choice comes down between 'clever' and 'clear', unless you have a really compelling reason to be 'clever' - go with 'clear.' The codebase isn't a place to show off your 'chops' - it is a place to think about all the people that will or may come into it behind you and they may be clueless or very inexperienced. Comment your code, another 'I have heard it a thousand times' one I know, but people just don't seem to do it because IT TAKES DISCIPLINE.
If you haven't done much with software patterns, pick up 2 or 3 books about them (both local and network patterns) because, although dry, they often contain the 'wisdom of the ages' for people new to software. Hell, just two weeks ago I was discussing a feature our Services team was implementing for a solution (I run Engineering, we produce products that the Services team [and external parties] uses to implement solutions) and they needed to simulate a physical machine. They were at a total loss about how to accomplish this (no snickering you experienced developers - especially game guys!) When I broached the topic of state machines they all went sort of glossy eyed (like some fish I'd just reeled up from 200 feet down.) After I explained for a few minutes I got a lot of head nodding. The next day I wrote up a little Java applet (yech) that demonstrated a crude approximation of the machine and used a state machine for managing it. Suddenly, everyone in Services is all about state machines (it is pretty funny actually - they have a shiny new hammer and they are wandering around looking for nails.)
There are dozens of things we could discuss but aside from the final thing I'll recommend below, remember, you don't want to just be a programmer (so it sounds) so to be a software engineer you need to have all the abilities of a programmer but also spend time thinking about the process, efficacy, flexibility, and extensibility of how you will implement solutions to problems.
The very last thing, and very important although many people who call themselves software engineers ignore it, is to be technol
Illumina sells sequencing reagents to China 10x (ten times) cheaper than to customers in the USA.
This is likely, although I don't know about this specific case, due to it being a growing and unstable market. Unless Illumina is some counter-corporation Corporation, they will charge what they believe the market will bear; ergo, you get relative equilibrium (in general.)
Actually you only have to purchase a compatible OS. I can run Windows 7 in a VM (I do this on my hysterically overpriced Mac Desktop Pro) and use VS just fine.
...is to stay a private company. If you capitalize through an IPO or become public in some other (there are obscure ways to do this) fashion, you're unlikely to retain your values for long.
You actually become legally beholden to maximizing shareholder value. You really can be criminally prosecuted for not doing something unethical that would have generated relatively substantial revenue.
It depends upon your situation. We did it because we started selling our system in China and knew that it would immediately get pirated by many corporations there.
Watermarking is a good thing, but it suffers the same problems that all the other schemes do: The code can be bypassed by editing the executable. CRC checks against the executable's size (to see if there have been changes) also get edited out.
This is what crackers ofter do, literally change the executable to not execute functions, or change the evaluation results of a license check - this prevents the watermark or dongle failures.
You have to really obfuscate and hide your licensing, honeypot it with standard licensing code, but include some well hidden code that is in a non obvious place, is evaluated routinely so that it doesn't look like one time startup code, and doesn't emit a license warning, it just subtly screws up the software's operation.
The standard licensing will point out license issues to your legitimate customers, the obfuscated code will cause problems for the 'cracked' versions. We had to do something similar to this before selling our product in China because our *very* expensive system was sure to be pirated by corporations there.
...in order to defeat someone seriously interested in breaking your copy protection. Misdirection is key.
Dongles, node locked licenses, networked licenses - all rather easily crackable and to be honest - primarily seemed to be designed to eke out maximum revenue from people who actually bought the software.
The only thing likely to give you some serious protection is to obfuscate your licensing scheme. The best way I've found to do this is to have a non-obvious component actually doing the licensing evaluation (periodically as part of some normal functional operation) and if that fails to subtly screw up the operation of the software. You still want to have standard 'relatively easy to tear out' protection so that legitimate users get notifications of a bad configuration or license, but what you're trying to do is make the software useless for people pushing it on a torrent/warez site.
For example, let's say this is Windoze software and you've got some COM+/MTS components in it. Don't have the main executable do anything other than the standard license checking. The DCOM/COM+ object will actually do the quiet validation, and if the licensing fails, it doesn't warn the user, it simply signals another DCOM/COM+ object to operate slightly differently, then that one does something wonky to screw up the experience.
Ultimately, there's no ultimate protection possible, but if you make it hard enough, people will likely avoid trying until the benefits outweigh the effort. Hopefully by that time you're profitable ;).
No. I allow my library providers to abstract browser behaviour and trust that if any browser behaves significantly differently in future (notably in this case violating the W3C recommendations for the DOM API) that the library will adjust for this. This is one of the advantages of using the libraries you are arguing against.
How on earth am I arguing against libraries? Lol. I'm arguing against you relying on the user catching the error, and acceptance testing catching the error, and your "staggering" assumption that these errors are '...not error conditions that could plausibly occur at the user level...' (I pluralized your quote.) You're literally arguing that you don't have to account for these types of errors because (a)they could not plausibly occur at the user level and (b)they would be caught at acceptance testing. Well, which is it? Will they be caught by users at acceptance testing or not? Acceptance testing has to be performed as an end user would experience, so if it isn't plausible that these errors could percolate to the user, how would acceptance testing catch them?
I find it a little disengenous to suggest that I'm arguing against libraries because I think you're being cavalier with error handling.
Err.. no. By "acceptance testing" I mean an automated test in an environment like Selenium or something similar that is run on every code check-in with all target browsers and which won't allow anyone to make modifications to the code while a test is failing.
I'm sorry but unless you're referring to hardware black-box testing, acceptance testing involves the customer whether it is user acceptance testing or automated in some fashion. What you are describing is regression testing.
While you appear to be making a lot of assumptions about the practices I apply to my work on the basis of a three-line code example which you haven't been able to identify any *actual* problems with, only potential problems that don't apply in the specific circumstances we were discussing.
You're really making an effort not to "get it." I have identified actual problems with your idea of "elegant." You simply seem to ignore them. Nobody said the code doesn't work, but your approach to writing elegant code has clear and objective software engineering weaknesses which I have described to you at length. It doesn't mean you don't know what you're doing, it doesn't mean it doesn't work perfectly, it does mean that a codebase littered with "elegant" coding like you provided is problematic (again, for the reasons I have already proscribed.)
Given this situation the actual operations performed by the code in question seem particularly relevant, as that code is all you have to go on in making your assessment.
Indeed, and that assessment is about your claim of "elegance."
And you still haven't justified why you believe any of the following are bad practices:
I didn't claim that closures are bad practices, I claim that the way that you use an anonymous function without any context as to why you need and call it "elegant" is a poor software engineering choice.
* use of closures (which, if it is a bad practice, means the entire field of functional programming is apparently doomed to failure)
A bit melodramatic are we? I'm somehow against closures because I believe you're using an anonymous function in a line of code with multiple evaluations and disagree totally with you that it is "elegant."
* use of fluent interfaces (which, if it is a bad practice, means that several prominent and well-respected writers on software engineering best practices are completely and utterly wrong)
I think an objective objective observer would find the mess you posted simply method chaining. Maybe you should read up more on what the purpose of a fluent interfa
Yes, I have, and yes, I agree that they do; however, a functional approach doesn't mean scattering anonymous functions throughout your code and then calling it elegant and re-usable because you (a)find it clear and you (b)can cut and paste the code wherever you need to re-use it.
...Intel had basically sat back on its a**, AMD make some great design decisions and Intel said "Oh sh**, how'd we suddenly become second...?" From that moment on there was only going to be one winner in the PC chip space.
Lol... How about "driving while negotiating an SSL Cert with an unresponsive server"? ;)
...we all rode powered luges!
I've seen lots of video of them under ideal scenarios.
Let's get some crash video! :)
Hydroplaning, black ice, big potholes, road debris, silver-hairs stomping on the brakes, et cetera.
Should be entertaining, if disconcerting, to say the least.
This is not an error condition that could plausibly occur at the user level. For it to happen, the referenced element would have to not be defined on the page, yet the page completed loading without error. Any form of acceptance testing will catch the possibility of such a condition before deployment.
Wow. Staggering. You are able to predict the way different browsers on different operating systems will work in the near and distant future!
You also have an incredible amount of faith in what you termed "acceptance testing" - in other words, let the user (the acceptance tester) catch the error.
And even if it does, what's the cost? A feature stops working, gracefully, because the method used to integrate it into the page was intentionally one based on the principle of graceful degradation
You seem to continually getting confused between talking about practices and talking about the specific operations you put in your "elegant" line of code. Who cares what the particular line of code does, I don't. What I am pointing out about your line of code are the bad practices you are exemplifying as "elegant."
What's the cost? Time, money, frustration. People who code the way you do in your example make things more difficult for anyone else to find, fix, and test problems. The cost in one anonymous single line "elegant" function? Minimum, but measurable. The costs when someone like you have been working on a product for a long time, littering the code base with your 'elegance'? Large.
As you're a software engineer, I assume that you're aware of the finding that the cost of code both in terms of time to originally write and time required for maintenance over the life of the project is proportional to the number of lines, regardless of how many features those lines implement?
Actually, you've convenient left out the impact of good engineering practices on both the time to implement or extend, and the effort to support and maintain. You're apparently a "pound of cure" kind of person. Maybe you're just used to dealing with small projects, such as a series of web pages. So that you find that cutting corner on engineering gives you a better profit margin. It doesn't unless spending more time fixing things is part of your business model.
You're really not going to be successful trying to argue that making code less testable and maintainable is a good thing; although you keep pretending that someone is saying the code is untestable and unmaintainable which are, of course, different things. Any code is testable in some fashion, and any code is maintainable is some fashion.
The typical OO approach of putting them in an object simply doesn't work properly
Why do they have to be in an object? This isn't some OO approach to engineering practices. You shouldn't write C code that looks like the example provided. It would be just as bad.
FFs, you really don't understand basic software engineering principles.
Don't confuse that with someone saying "you can't program" - they are different things.
How are the two ways you demonstrated for returning different in clarity? They basically aren't. They're total crap either way because of the rest of your "elegant" code, lol.
Why is it a bad practice to perform evaluations in your return statements if you are a software engineer? Because anyone who has to debug your glob of strung together operations will need to actually change the code in order to evaluate its operations. This is bad. Is it a felony? No. Is it better software engineering to already have code in place that can be debugged without changing any code? Does this mean that you cannot (not to be confused with should or should not) perform multiple evaluations in a single line of code? Of course not, but the goal should be to avoid it. Not celebrate it as "elegant."
All of the rest of your "points" are exactly the same, poor engineering practices (some laughably poor such as the one where you claim the code is "very reusable" because you can cut & paste it on any page you need it on!)
One of your statements hints at the fundamental difference between the way programmers and software engineers think...
Yes, you need to be vaguely familiar with jquery to understand what I wrote, but if you aren't familiar with the tools I'm using, what are you doing trying to maintain my code?
That, in a nutshell is the difference. It isn't "your code" that somebody else has to maintain. It belongs to the company, or the client.
If you want to write code just for yourself, nobody care how badly engineered it is; but, if you're writing code for someone who is paying you to do it, you should make every reasonable effort to make it easy to debug, reuse, and extend.
The difference between a programmer and a software engineer in this case is that their definition of "reasonable effort" is apparently vastly different.
I was debugging very similar code only yesterday, and didn't find it even remotely difficult.
- The staggering naivete this statement exhibits is amazing. Is every programmer working on a project going to have the same skills? The same levels of familiarity with a giving API or framework that you do? Is everyone just supposed to be you? Lol.
Writing test cases for a nested function is likely to be just as challenging, yet the function I wrote *must* be nested, because it is required to have access to a copy of an outer-function local variable
The very fact that you're trying to argue that it is just as easy to write test cases for anonymous functions as it is for non-anonymous functions is ridiculous. Trying to artificially constrain the non-anonymous function to being nested is also disingenuous.
You also seem to be ignoring that it is clearly and unequivocally simpler to test a function that belongs to one object/class/namespace and is used in multiple locations than it is to test functions on a per usage basis as would be the case of an anonymous function.
Anonymous functions do have important usage cases, i.e. when you must manage a very particular scoping issue.
The reason that JavaScript code is littered with them is because people find them convenient. Plain and simple.
I contend that you're only saying that because you're unfamiliar with the environment. To anyone who knows it more than moderately well, what I wrote is clear, obvious, and the natural way of doing it. What other way should it be done?
I contend that you don't understand what the word "elegant" means, much less what good engineering practices are.
Are you familiar with any other programming environment in a professional capacity? It seems highly doubtful. I am familiar with the environment, as well as many others. It's why I can recognize the problems that you obviously don't see.
I disagree completely. Programming an imperative language sloppily in such a way that it makes a logical representation that barely looks similar to functional programming (Haskell-ish shall we say) in no way connotates an advantage.
You also seem to be missing the point the original code submitting was making. He/she was suggesting that this code was an example of elegant web programming, lol.
Hell, people who want to embrace functional programming in JavaScript are more likely to agree with my assessment of the code. One of the advantages to using a functional programming style is abstraction and code reuse. Functional programming methods stand up better over time in a code base because they're implicitly more likely to be agnostic of state.
I'm sorry, but it really isn't worth my time to try and explain to you all that is wrong with your reasoning above, so I'll just address your first paragraph and your humorous 'functions.'
In which case it returns an *empty jQuery object*, not NULL. newToggleElement then would be a clone of the empty jQuery object, so its ok to use .click() on it (verified in the console). So this code is safe, and will *not* cause Javascript errors assuming jQuery has been loaded (safe to assume).
You are arguing that you don't need to bother checking if a valid object comes back because it won't throw up a runtime error. Wow, let's just push the error identification onto the user then, right? Lol. I mean, seriously, it is bad enough that you don't check to see if something is a valid operation when it very well might now be, but then it's ok for it to fail silently?
The rest of the arguments simply expose that you're not used to creating re-usable software components, or you're being disingenuous in your examples. You act as if you should be using this in the non-anymous function, you shouldn't. Everything used in that function should be passed to it unless it is a global exposed by a framework you are using. I will presume you're just being disingenous because I doubt you don't know how to write a function properly. Your really poor function attempts are indeed unclear in their operation because that's how you wrote them (again, presumably on purpose rather than through incompetence.)
Now stop trolling about stuff you don't understand
Stop pretending to be a software engineer.
There are many times when an anonymous function or class is the simplest, idiomatic (in the language in question) thing to do.
Yes, I agree, especially about it being idiomatic with JavaScript. It isn't idiomatic because that's how you should be doing in in JavaScript, it is idiomatic because tons of JavaScript programmers do it that way.
I also agree that it can be very simple, but it is also equally simple for it to not be an anonymous function. Is it as "easy" as doing it anonymously? No. Is it better from an engineering practices standpoint? Yes. Writing test cases for anonymous functions seems likely to be 'challenging' ;).
Event handlers in Java and GWT frequently are anonymous inner classes, but it often ends up being easier to read than writing a custom class that handles each different event
Event handlers in Java and GWT are often found to be anonymous, but they shouldn't be. Most of the time if you find people using anonymous functions/methods it is because they have not architected the solution to their problem properly to account for some edge case (especially in Java) or they are just lazy. I disagree pretty strongly that it is easier to read than writing a custom class that handles those events for many reasons, but mostly because of the opportunities for centralization of the code, re-use opportunities, and the ability to create tests for that class.
Now, all of that aside, there are surely cases where an anonymous function could/would be appropriate, but they are exceptions - not the general rule.
Similarly, consider that since he was typing it from memory, he may have taken shortcuts that he might not use in production code, just as one often writes a Perl one-liner differently than one would a Real Program
I can only comment on the code he/she actually submitted in support of "some of the most elegant web programming I have ever seen."
I think people (on both sides of the JavaScript debate) are mixing up the differences between what you can do with the language and what people tend to do with the language.
The code that was given was, imho, the antithesis of what a software engineer should produce. Does it mean it doesn't work? No. Does it mean it isn't clever? No. Does it mean it is buggy? No. It is, however, poor software engineering.
Why not?
Well, it is unsafe, is anti-reusability, unclear, and impossible to debug without rewriting it to see why it doesn't work or suddenly stopped working. Defining a function inline to your statement, and in that function performing evaluations in your return call that are based upon objects that may be null when you execute an operation on them?
There's no need to go verbose for verbositys sake, and that piece of script is pretty neat.
There is a need to go verbose for the sake of everyone else who may ever have to work in the same codebase.
If you place a completely green web-developer in front of it, sure, he might have a hard time reading it, but if jQuery is a tool you use, and webdevelopment what you do, then this really shouldn't be much of a problem at all.
I'm not trying to denigrate you in any way, but this type of attitude is the difference between programming and software engineering. It is the discipline to do extra work that is tangibly less fun than doing clever or fun things.
I don't enjoy long variable names.
I don't enjoy modified Hungarian notation.
I don't enjoy seeing an obfuscating and clever way to manipulate something but then do it a more plodding and clear (if equally efficient) way.
I enjoy software architecture, but I don't enjoy writing up the design.
I don't enjoy the ridiculously long meetings involved in matching up the design to the spec to the requirements.
I don't enjoy putting in long comments to make absolutely sure someone coming in to fix a bug in the future is aware of the caveats of the possible changes they could make.
I do these things because I need to do them for the sake of the codebase/product/Company/Investors.
Simple: clear, debuggable, logically organized, and debuggable code.
Don't define functions inline of your statement.
Don't perform evaluations in your return statements.
Avoid calling methods/functions on objects via the return of another evaluator.
The code sample he provided is counter to reusability, readability, unsafe in that it doesn't evaluate possible nulls, and arguably impossible to debug.
It has nothing to do with being a JavaScript guy or not. It has everything to do with the difference between being a programmer and a software engineer. They are two different things.
$(".hideable").before(function () {
var hideableElement = this;
return $("#showhidecontrol").clone().click(function () { hideableElement.toggleClass("hidden"); })});
I'm sorry, but you're simply giving credence to what he's saying with something like that.
I would never let one of my engineers check code in that looked like that (much less do it myself.) Talk about a lack of clarity, lol...
Amen brother... And keep the Scotch cheap. No use wasting the good stuff - you'll be bathing in it before long.
JavaScript can do amazing things, but it's a total disaster if you're coming from a more traditionalist background.
Let me give you a taste of what's to come for you :).
Let's say you have an Applet/ActiveX Control/Plugin of some type that your company has built and needs to be scriptable from JS, and it must also be able to call into JS (JavaScript devs can register for events, notifications, console/logging messages, et cetera...)
You add a new feature to your Company's doohickey. Now you need to test it properly.
Your customer set requires that you need to test on OSX Snow Leopard, OSX Lion, Windows XP, Vista, Win 7, OpenSUSE, Redhat, and Ubuntu. On each of these operating systems you need to test on the most popular browsers, so you get jiggy with Safari, Firefox, Opera, IE7, IE8, IE9, Konquerer, et cetera... Then you, depending upon the plugin's architecture, need to test on both 32-bit and 64-bit versions of the plugin in each browser on each operating system.
That's not even getting started with Mobile, or JRE versions, or different deployment types, code signing, et cetera, ad nauseum, ad infinitum.
If you think you don't need to test like that, you're in for a rude awakening my friend... For example, this very testing led to our discovering that in Firefox, on Windows 7 rapid LiveConnect usage between an Applet and JavaScript is perfectly fine if the applet has focus, or another windows has focus, but causes total freezing of Firefox/Java Plugin IF THE FOCUS GOES TO ANOTHER ELEMENT ON THE SAME WEB PAGE. How's that for crazy sh**? :) LOL.
Anyhow.
Browser application development is a nightmare.
I would pay good money for them to rip JavaScript out and everyone get together (yeah, I know, pipe dream) and come up with a client side scripting language that rocked oldSk00l.
First and foremost, self-discipline. Yes, I know, it is hard.
Be prepared to go unrewarded for your "extra efforts" which are in actuality basic software engineering tenets.
Do NOT design at the keyboard. You can be agile without designing at the keyboard, you can be a traditional waterfaller without designing at the keyboard, you can be a spiralist without designing at the keyboard. When you find yourself making design decisions at the keyboard, unless they are truly trivial (and the litmus for this will change with experience) WALK AWAY from the keyboard.
Ensure that the people who assign you work understand the caveats of what they are currently asking you to do. Even if this makes people think you are being negative, give them the information they don't even realize they need to make better decisions. YOU are the expert on what will happen when implementation happens. For example, if your product manager or account manager or <insert PHP - pointy haired person - here> wants a milestone that includes features that are poorly defined (either through their own recalcitrance or through, most likely, a customer who doesn't know what they really want) it is your responsibility to be the a**hole negative nerd who makes it CRYSTAL CLEAR the implications of doing such a thing. That doesn't mean you don't do it, it means you sacrifice whatever small amount of political capital you have with them to ensure that everyone is on the same page about the potential outcomes. You're going to be shocked by what people can 'pretend' to not recall ;).
Think about problems in a fashion designed to allow for systemic flexibility because, just like in war, everything goes to plan until the first shot is fired.
Think about the long term viability and accessibility of the code you write (good variable names - really, I know you've heard it a thousand times probably, but it makes all the difference in the world.) When the choice comes down between 'clever' and 'clear', unless you have a really compelling reason to be 'clever' - go with 'clear.' The codebase isn't a place to show off your 'chops' - it is a place to think about all the people that will or may come into it behind you and they may be clueless or very inexperienced. Comment your code, another 'I have heard it a thousand times' one I know, but people just don't seem to do it because IT TAKES DISCIPLINE.
If you haven't done much with software patterns, pick up 2 or 3 books about them (both local and network patterns) because, although dry, they often contain the 'wisdom of the ages' for people new to software. Hell, just two weeks ago I was discussing a feature our Services team was implementing for a solution (I run Engineering, we produce products that the Services team [and external parties] uses to implement solutions) and they needed to simulate a physical machine. They were at a total loss about how to accomplish this (no snickering you experienced developers - especially game guys!) When I broached the topic of state machines they all went sort of glossy eyed (like some fish I'd just reeled up from 200 feet down.) After I explained for a few minutes I got a lot of head nodding. The next day I wrote up a little Java applet (yech) that demonstrated a crude approximation of the machine and used a state machine for managing it. Suddenly, everyone in Services is all about state machines (it is pretty funny actually - they have a shiny new hammer and they are wandering around looking for nails.)
There are dozens of things we could discuss but aside from the final thing I'll recommend below, remember, you don't want to just be a programmer (so it sounds) so to be a software engineer you need to have all the abilities of a programmer but also spend time thinking about the process, efficacy, flexibility, and extensibility of how you will implement solutions to problems.
The very last thing, and very important although many people who call themselves software engineers ignore it, is to be technol
Illumina sells sequencing reagents to China 10x (ten times) cheaper than to customers in the USA.
This is likely, although I don't know about this specific case, due to it being a growing and unstable market. Unless Illumina is some counter-corporation Corporation, they will charge what they believe the market will bear; ergo, you get relative equilibrium (in general.)
Actually you only have to purchase a compatible OS. I can run Windows 7 in a VM (I do this on my hysterically overpriced Mac Desktop Pro) and use VS just fine.
...is to stay a private company. If you capitalize through an IPO or become public in some other (there are obscure ways to do this) fashion, you're unlikely to retain your values for long.
You actually become legally beholden to maximizing shareholder value. You really can be criminally prosecuted for not doing something unethical that would have generated relatively substantial revenue.
Taking your company to an IPO *is* selling out.
Please make all checks payable to Dr. Madoff, Otisville, New York.