Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I am not good at naming, I good at feeling.
Suppose we have this hypothetical function:
function computePowerAndPrintResult(int x){
print(x*x);
}
It screams already in the naming of the function ("And") that something wrong here and personally I never write code like this.
Which principle is being violated here? Is it the single-responsibility principle?
Yes. The name is indeed a giveaway. In violation of the single responsibility principle, the function is responsible for two things: computing the square, and printing the result.
Also good naming sense is being violated: at the very least it should be called computeSquareAndPrintResult because Power without specifying the exponent doesn't make much sense. I'd personally call it printSquareOf so you can call it like printSquareOf(x), which reads very naturally.
No it's not. The single responsibility refers to a class. When a class is doing too much then it is violated. When a function is doing to much though you need to break it down.
Now I'm not saying that it's not an indication that it does.
In my mind, you need a class to compute the power, and a class that will manage the printing.
BUT: Assume that I have a need to implement an API that I would call and it would return the PDF of the compute power. I would need an api that would both calculate and print the result.
I would then create the GetSquareValueOutput which would have the single responsibility to orchestrate getting the data from the SquareValueCalculator class and then print with the Printer class.
This last GetSquareValueOutput might as well be called computePowerAndPrintResult and it would not break a thing. I wouldn't choose the name as it hints at a code smell, but in the end it's just a matter of context.
TL;DR: Change the name to printSquare. Then the name is much shorter, is equally accurate at describing what you do, and yet... if you really want worry about the single responsibility principle, you're still breaking it. Which says more about how SRP can easily be overzealously applied, than this being a bad method.
In depth on that name
'computePower' is a bad name for two reasons:
'Power' is a binary operation (X to the Yth power) and you're not really doing that; you've locking Y to '2', and that operation has a common name too: 'square'.
'compute' is usually superfluous. square already implies that calculation is going on. Look at e.g. java's AtomicInteger or BigInteger which have methods named add (really, in the case of BI, should be plus), but the point is, it's not computePlus. Note that it depends on a few factors; for example, in java it is common to start property getters with get, in a class that has an unrelated property or otherwise square is not as clear as one would like (say, its geometrically related, so square could be misunderstood to refer to the shape instead of the mathematical operation), then this is oversimplifying matters as well.
That means that part of the method name ought to be square and not computePower.
Then we have the andPrintResult part. Here Result is superfluous. What else would it be printing, other than the result?
You have 2 options:
This method should be named square and should return that value and not print anything. Make another method to print things.
'and' being a code smell is.. eh. Maybe. Look, you could name this method printSquare which is short, clear, and contains no and, and yet, it's just as much of a violation of the rule as computePowerAndPrintResults.
In many ways printSquare is a straight violation of SRP, but if you change the name to reportSquare, and the code will compute the square and then report it to the configured (injected via dependency injection for example) 'reporter output stream', all of a sudden it's not a violation of SRP, but all we did was redefine some words, the code remained the same.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I always use one array arguments to a function whenever I need more then 3 parameter.
Example: Consider a function call like this.
processSecondStage($stepTitle, $round, $entryId, $formId, $stepType, $stepAfterApproved, $assigneees, $stageToMove);
I always prefer the below one.
processSecondStage(array(
'stepTitle' => $title,
'round' => $round,
'stepAfterApproved' => $stepAfterApproved,
'entryId' => $_entryId,
'assigneees' => (array)$_POST['flow-asignee'],
'stageToMove' => $currentStep,
'formId' => $targetFormId,
'stepType' => 'approval'
));
Advantage (I might be wrong):
a) Can add more number of parameter
b) Readability
c) Order can be changed easily
d) Default parameter handling is easier
Disadvantage :
a) Code length is increase specially in case when we have less then 3-4 arguments.
Can anyone please help me Know more disadvantage of using the array parameter ?
Whenever I change other developer code (like I am going to do now), then I feel that there are some major disadvantage of using array as parameter because if that was not the case then it should have been a standard practice.
Although I have given example of PHP, but I find this in other language also on which I work.
Thank You.
Arrays are useful as a parameter when things you want to pass are closely related and do not make sense separately. A classical example is a Color that is defined by blue, green, red (and maybe gamma). Combining these parameters into an array (or object in javascript) allows you to swap it out easily.
Always using an array as the single parameter of a function makes you loose out on a parameter list an IDE can give you. For someone reading the code, it is quite a hell to figure out what needs to be passed to a function. It also opens the door to future creep (oh, this function was only making me coffee, but if I add another optional parameter it can also make me tea. Oh, and maybe I can let it make me dinner to. Why not add the functionality to order an attack helicopter too).
In a regular parameter list you can pass things by reference (function pushElement(array &$sortableArray, $element)). This is not expected in a regular array, if it is even possible.
The point about default values is kind of a moot point. Normal parameter lists allow type hinting and default values just fine:
function action(string $action = 'tickle', string $target = 'Polar bear') {
print "I {$action} a {$target}";
}
A single parameter as array probably only really shines when passing some kind of static configuration. You keep the configuration of something separate from the actual code using it, making it easier to modify the configuration. At the same time you leverage the fact that you do not have to send 20 parameters in a very specific order.
In your case the parameter list you give is wildly varied and long, which suggests that your function is doing way too much. Part of it should probably be moved to a constructor and part of it should probably be moved to some kind of Form class.
Parts of the topic are very much opinionated...
The problem you describe is not just parameters as a list vs a sequence of parameters. There are several problems that occur (with both in your example).
Tooling
Ordering of parameters
Semantics
Tooling is probably obvious: If you have only arrays as parameters, no IDE will know what is supposed to be inside. Okay, most IDEs won't know.
Ordering of parameters is usually dictated by the name of the function and/or its semantics. If you drawLine the canonical order of the parameters is ($from, $to). If there is no canonical order, there might be something else wrong with the code... (see below)
Semantics: If you have 3+ parameters (especially if you have way more), it is very likely, that the abstraction is wrong. For example let's assume you have a function createShirt($size="m", int $red, int $blue, int $green, Image $logo, $material="wool"): The order of attributes is arbitrary and the object produced (a shirt) may not need all of those parameters, but you can absolutely use this abstraction. I would much prefer the builder pattern, example:
$shirt = ShirtBuilder::create("m") // verifies m is a size
->setColor(new Color($red,$green,$blue)) // has type-hint color
->setImage($logo) // has type-hint
->setMaterial($material)
->build();
It absolutely is more verbose, but it is apparent you only have to call functions that are needed, you can validate set values at any point (read: function call). The build function could verify that the combination is valid and the Shirt object itself could even be immutable.
However, arrays absolutely do have their place and purpose. But usually it is "providing a list of things of the same type". If your array has only string-keys that are from a very small domain, you probably want an object.
Using objects will trigger questions such as "which parameters should belong to this object?". if there is no semantic reason for a true subset of parameters to appear together, you probably want the command pattern (command objects). and IDEs might provide all the wonders that make using those easy
tl;dr:
Using arrays to hold a list of heterogeneous parameters is probably an anti-pattern (might be warranted in some scenario/language).
Functions/methods with more than 3 parameters suggest too little abstraction (there might be reasons). Use appropriate design patterns.
I'm building a interpreter and i'm now at the point where I need to implement it to handle closures. I understand the concept pretty well but I have a question on why they're designed the way they are.
In terms of how a closure is designed/interpreted there needs to be 3 things:
variable
body of logic that variable is bound to
environment that is saved during the closure's instantiation, this is for free variables that exist within the body to be bound when the closure variable is evaluated.
I understand why all of these things are needed, i'm just wondering about why the 3rd item is needed at all when substitution at the moment of the closure's creation is doing the same thing? Is there anything i'm not accounting for?
Essentially what i'm asking is why not just substitute the free variables with the respective environment values at closure creation instead of passing the environment entirely?
I guess it's a little late, but oh well...
That depends on your computation model (evaluation strategy for example).
If all the data structures [which can get bound by a variable, and in effect enclosed] are immutable in your language your method should work.
It works with pure lexical lisp dialects (eg functional subset of scheme), nice and smooth.
It might not work if:
You pass arguments by reference, as was already mentioned in the comments. Call by value is fine. Also references to immutable object are fine.
Your environment binding and/or lookup causes some side effect. That would be rather exotic, but who knows?
Also, mind you don't have to enclose entire environment, just the free variables of your function's body (easy!).
The only reasons [I am aware of] for implementing closures as body+environment are:
you might want to pass references to mutable objects. This happens i.a. with dictionaries in js and python; it is a bit scary to have closure changing over time, but oh well.
you don't need to write substitution function. Mind it has to keep the scoping correct, so would have to resemble your evaluation function [if your computational model is substitutional] -- so why repeat yourself? Also there is this delicate nature of values: in case of applicative order ("eager evaluation") when you substitute the value in the body, you need it to be lifted to expression who's value is the thing (if by any chance you are implementing LISP variant, think about symbols -- you don't substitute the value HI!, but the expression (quote HI!). This does not apply to cases when all your datastructures evaluate to themselves, like numbers or truth values in most LISPs). These are not problems in general, but introduce some complexity to your interpreter, and simple is good.
the bound value might be something memory-consuming, and the variable you enclose occurs [as a free variable] more than once -- you body will be significantly larger (e.g. your value is a bitmap or sound sample or some enormous matrix or... you get the picture). It is similar problem to computation duplication with lazy evaluation, but wrt memory, not time. This is also usualy not a problem as computer memories are big.
I've ran out of ideas what else might break, but if you're not into checking your computation model "on paper" (by equational reasoning) you should implement it and try the trickiest cases [if any of these applies]: side effects, lazy evaluation, references, mutable objects, combinations of the above. They are definitely not obstacles, just places worth checking.
Hope that helps, good luck with your interpreter!
PS If you like to think about this kind of stuff, check out defunctionalization ("Defunctionalization at Work" by Danvy and Nielsen is a pretty accessible read, and you should be fine with first part to get some inspiration)
validationError([elem1,elem2],type,shiftNo);
or
var arr = [elem1,elem2];
validationError(arr,type,shiftNo);
What I mean to ask is approach 1 of calling the function considered bad ( also does it have any performance ramifications). and for that matter is it a bad approach to declare strings, object and functions inside arguments.
Performance is not an issue, not in a language like JS, Ruby or whatnot. So all we can do is think about code readability. And this case is not strongly related to JS, so will be my examples.
move = ["E2", "E4"];
if chessboard.valid(move, player) {
...
}
This clearly states: "if the move (E2 E4) is valid for this chessboard, then...", you don't even need to look at the docs to know that. If we write that without assigning our array a name, the result looks a little cryptic (still easy to guess, but harder for such a tiny example):
if chessboard.valid(["E2", "E4"], player) {
...
}
What is this supposed to mean? What does valid stand for here? Maybe, it's asking whether these cells contain valid player's pieces? This is a sympthom of a design flaw, more precisely bad naming. It makes bold assumptions about how the chessboard code will be used. We can make it obvious that this array represents a move by renaming the chessboard's method:
if chessboard.valid_move(["E2", "E4"], player) {
...
}
This is better, but you may not have an API that allows your code to stay so readable without some additional naming.
So, I suggest a rule of thumb:
If the array will be used more than once, name it.
If the meaning of the array is not obvious from where it goes (function name), name it.
Don't name it, unless points 1 or 2 apply.
It doesn't make any difference really. Either way, you create a Javascript Array, which basically is an Object and get a reference in return (which you pass to your method). If you don't need to access that array (or other data) later in your code, the second approach is completely fine.
Are the contents of arr ever going to get used again? If so, then option 2 is definitely the way to go. If not... something as simple as this is probably just personal opinion.
Personally, I'd have to say that option 2 is better practice, even though sometimes I'm guilty of using option 1. Option 2 is easier to read, it's easier to follow and it's less likely someone will have to re-read it because they became temporarily confused or lost in flow of thought whilst reading through your code (especially newer programmers). For those reasons it's easier to maintain, you, and potentially future developers working with your code, will likely save time working with it.
The only negatives I can see would be generating an absolutely miniscule amount of overhead, and now you have 2 lines of code instead of 1. But I think that's irrelevant, the tiny potential benefits of option 2 outweigh the tiny negatives of option 1.
It is subjective, but in my opinion it is better to use the second approach.
As #jAndy said there is no difference in the code execution neither the performance of your code, but it is easier to debug and easier to read and understand the second approach.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
As I am writing some code, I am wondering how secure my methods should be. Should I trust the user of my class ? Or check everything ? This implies parameters type checking which may not be a good practice as Javascript is supposed to be duck typed.
Basically this leads to the question of trust. Is there a best practice ? Is there an implicit "contract" ?
Example :
CarsCollection.prototype.get = function ( index ) {
return this.collection[index];
};
Or
CarsCollection.prototype.get = function ( index ) {
var self = this;
if ( ! index ) {
throw new ReferenceError();
}
if ( isNaN ( index ) ) {
throw new TypeError();
}
return self.collection[index];
};
You'll find out how robust your methods are by unit testing them. If you write good tests, you'll quickly find that your methods need to be able to handle all kinds of wack input.
It is up to you how far you want to go, but to be clear: don't just assume that the inputs will be valid.
Personally, I validate the hell out of anything that is coming from another class/module/whatever, even if its not third party. You need to make sure that the entry points to each module are robust. I relax a little more within a given class/module, but still make sure to validate enough to prevent errors.
In your sample code, it looks like other pieces of code outside of CarsCollection will be calling the get method. So, you'll want to validate index for sure.
In general things like framework code and reusable libraries are the prime candidate for extensive argument checking because you (and your current and future colleagues) going to use this code a lot.
You don't have to add argument checks everywhere, just use them when it's sensible.
If you want to specify certain behaviour like: should array_delete_value modify the input argument or return a copy with the value removed? Specify it in the comments and add a test that tests for exactly this behaviour.
If you're worried about performance you can write assert-like statements and remove them in your minification step. This is analogous to compiling with asserts off.
Asserts could look like:
argument("index", index).of_type("number").required();
If you downvoted, could you please leave a comment. Did I miss something? Do you have a competing methodology?
I like to make my code as dummy-proof as possible. This reduces the number of WTF's elicited by developers using my API/function/code. Argument-checking is always a good practice, especially in a dynamically-typed language like JavaScript. So there is nothing wrong with what you are doing. Type checking is permissible in JavaScript also. I find it easier to keep track of a function that explicitly states the types of its arguments. This lessens the cognitive load on the user of your API (i.e., not having to deal with foo(5) and foo("5")) and also lessens your own cognitive-load when you are writing the function since you won't have to deal with the idiosyncrasies of JavaScript's types and can be sure that an argument is the type that you expect.
While this doesn't exactly answer your question, it's important to note that the looseness of javascript makes many of your issues a non-issue (unless you want them to be).
If index is falsey, and you look at collection[index], you'll simply get undefined. I'm honestly not sure if that's a feature of arrays/objects or if the falsey value got coerced to a 0, but either way, it's not officially an error.
If index is not a number, the bracket notation will fall back from looking for an array member to an object property. In the worst case, it will return undefined, but in the best case, you can use the dynamic capabilities of objects to your advantage.
Realize that your current check will fail on CarsCollection.get(0), since 0 is falsey.
Also, isNaN handles if its parameter is null or undefined.
So neither of the things you check for are an error. If it was a fatal error, JavaScript would throw an error itself.
Now, to the question itself, my opinion is that javascript is so loose and uncontained, that most checking is unnecessary. If the using function passes bad parameters, the other programmer should figure out why. It's not like you can hide your code from them. The thing I value most is good documentation (check out jsdoc, then use it). If you define your interface well, the programmer can use it. That's just IMO, though.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
The more I delve into javascript, the more I think about the consequences of certain design decisions and encouraged practices. In this case, I am observing anonymous functions, a feature which is not only JavaScript-provided, but I see strongly used.
I think we can all agree on the following facts:
the human mind does not deal with more than 7 plus minus two entities (Miller's law)
deep indentation is considered bad programming practice, and generally points out at design issues if you indent more than three or four levels. This extends to nested entities, and it's well presented in the python Zen entry "Flat is better than nested."
the idea of having a function name is both for reference, and for easy documentation of the task it performs. We know, or can expect, what a function called removeListEntry() does. Self-documenting, clear code is important for debugging and readability.
While anonymous functions appears to be a very nice feature, its use leads to deeply nested code design. The code is quick to write, but difficult to read. Instead of being forced to invent a named context for a functionality, and flatten your hierarchy of callable objects, it encourages a "go deep one level", pushing your brain stack and quickly overflowing the 7 +/- 2 rule. A similar concept is expressed in Alan Cooper's "About Face", quoting loosely "people don't understand hierarchies". As programmers we do understand hierarchies, but our biology still limits our grasping of deep nesting.
I'd like to hear you on this point. Should anonymous functions be considered harmful, an apparent shiny syntactic sugar which we find later on to be salt, or even rat poison ?
CW as there's no correct answer.
As I see it, the problem you're facing is not anonymous functions, rather an unwillingness to factor out functionality into useful and reusable units. Which is interesting, because it's easier to reuse functionality in languages with first-class functions (and, necessarily, anonymous functions) than in languages without.
If you see a lot of deeply nested anonymous functions in your code, I would suggest that there may be a lot of common functionality that can be factored out into named higher-order functions (i.e. functions that take or return ("build") other functions). Even "simple" transformations of existing functions should be given names if they are used often. This is just the DRY principle.
Anonymous functions are more useful functionally than they are harmful legibly. I think that if you format your code well enough, you shouldn't have a problem. I don't have a problem with it, and I'm sure I can't handle 7 elements, let alone 7 + 2 :)
Actually, hierarchies help to overcome 7+/-2 rule the same way as OOP does. When you're writing or reading a class, you read its content and nothing of outside code so you are dealing with relatively small portion of entities. When you're looking at class hierarchies, you don't look inside them, meaning then again you are dealing with small number of entities.
The same if true for nested functions. By dividing your code into multiple levels of hierarchy, you keep each level small enough for human brain to comprehend.
Closures (or anonymous functions) just help to break your code into slightly different way than OOP does but they doesn't really create any hierarchies. They are here to help you to execute your code in context of other block of code. In C++ or Java you have to create a class for that, in JavaScript function is enough. Granted, standalone class is easier to understand as it is just easier for human to look at it as at standalone block. Function seems to be much smaller in size and brain sometimes think it can comprehend it AND code around it at the same time which is usually a bad idea. But you can train your brain not to do that :)
So no, I don't think anonymous functions are at all harmful, you just have to learn to deal with them, as you learnt to deal with classes.
Amusingly, JavaScript will let you name "anonymous" functions:
function f(x) {
return function add(y) {
return x+y;
};
}
I think closures have enormous benefits which should not be overlooked. For example, Apple leverages "blocks"(closures for C) with GCD to provide really easy multithreading - you don't need to setup context structs, and can just reference variables by name since they're in scope.
I think a bigger problem with Javascript is that it doesn't have block scope(blocks in this case referring to code in braces, like an if statement). This can lead to enormous complications, forcing programmers to use unnecessary closures to get around this Javascript design limitation.
I also think anonymous functions (in latest languages often referred as closures) have great benefits and make code often more readable and shorter. I sometimes am getting really nuts when I have to work with Java (where closures aren't first class language features).
If indentation and too many encapsulated function-variables are the problem then you should refactor the code to have it more modular and readable.
Regarding java-script I think that function-variables look quite ugly and make code cluttered (the encapsulated function(...){} string makes java-script code often less readable). As an example I much prefer the closure syntax of groovy ('{}' and '->' chars).
If a function is not understandable without a name, the name is probably too long.
Use comments to explain cryptic code, don't rely on names.
Who ever came up with the idea of requiring functions to be bound to identifiers did every programmer a disservice. If you've never done functional programming and you're not familiar with and comfortable with functions being first-class values, you're not a real programmer.
In fact, to counter your own argument, I would go so far as to consider functions bound to (global) names to be harmful! Check Crockford's article about private and public members and learn more.