Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

This is valid for many other functions.

get(array,key) or get(key,array) ?
find(array,value) or find(value,array) ?

Etc...

share|improve this question

closed as primarily opinion-based by Jerry Coffin, Malachi, Simon André Forsberg, Edward, konijn Jul 2 at 14:31

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.If this question can be reworded to fit the rules in the help center, please edit the question.

1  
If it can help : rosettacode.org/wiki/Search_a_list –  Josay Feb 25 '13 at 2:47
1  
You use tag:functional-programming, so I take it push returns a new array, instead of updating the existing one. Is this the case? –  Joey Adams Feb 25 '13 at 6:27
    
@JoeyAdams actually no, there's a clone function though... would be too inneficient to be default. –  Dokkat Feb 25 '13 at 14:55
    
removed best-practice in accordance to tag burnination –  Vogel612 Jul 7 at 6:46
add comment

4 Answers 4

If your language uses currying, there is another view:

  • If a function returns a new version of one of its argument, put that argument last.
  • It's convenient to put first arguments that are more likely to be fixed, and put last arguments that are more likely to be variable.

(I'll use Haskell for examples.)

As an example, let's consider map function that has two arguments: a function of type a -> b and a list of a elements [a]. It returns a new list of type [b]. Which of the arguments should be first? The function argument is more likely to be fixed, while the list usually varies. Moreover, it takes a list argument and produces another list, so it is more convenient to put the list argument last. This leads us to:

map :: (a -> b) -> [a] -> [b]

This way, we can compose consecutive maps like

map show . map (^2)

of type [Int] -> [String]. This function takes a list of numbers, squares them and applies show to each of them to create a list of strings. As you can see we didn't even need to use any variables, we can write the expression in a point-free style. The other variant

map' :: [a] -> (a -> b) -> [b]

would have been much less composable - try expressing the above example using map' instead of map.

This ideas can be seen in many many places. For example, inserting an element into a Set:

insert :: Ord a => a -> Set a -> Set a

which allows us to do things like insert 1 . insert 2 . insert 3 of type Set -> Set, which inserts elements 1, 2 and 3 into a given set.

So (in languages with currying) it's more convenient to have push with the value argument first and the array argument second.

For get this principle is not so straightforward, you can have both variants and both are convenient, as with Haskell Map's lookup and (!). (However, lookup seems to be more widely used than (!).)

share|improve this answer
add comment

I always try and put the "most important" elements at the start, which would be the array in this case. I do this primarily so that my methods have more similar prototypes and I know that the first item in the method is going to be the array/list/etc.

For example:

get (array, key)
find(array, value)

Is much nicer to me than:

get (key, array)
find(value, array)

An example recently where I've encountered this is when using EntityFramework I had the DataContext in inconsistent positions in the parameter list, this just involves a little more thought than having it as the first parameter all the time.

A side note, if working in a language where you can, it may be nicer to put the method on the array.

array.get(key)
array.find(value)
share|improve this answer
add comment

Youre question reminds a question I had on the difference between conj and cons function in Clojure.

Both are made for adding elements to a container, but they have a lot of differences. I won't enter in the details of conj which can add the element(s) either at the end or the beginning depending on the structure type passed as argument.

A difference is in the parameters order. cons accepts only one argument and add it at the beginning of the structure, thus it takes the new element as first parameter and the sequence in second (cons 1 '(2 3 4)) returns (1 2 3 4). More precisely it returns a new pair, and AFAIK it does not necessarily evaluates the second parameter. As a consequence cons is designed to work with lazy sequences.

While conj takes as much new elements as you want. As in (conj [1 2 3] 4 5 6) returns [1 2 3 4 5 6]. As a consequence the new elements parameters are pushed to the right of the parameter list. I guess it is because it is a common idiom when a function is supposed to get a variable numbers of arguments, developers expects the "variable part" of the argument list is expected on the right side (as in C++ with default arguments/variadics). But then one could say that the function could have nevertheless been designed to take the new elements on the left and the container on the right as for cons, but I would answer (and I can been wrong since I am not a Clojure guru) that that way of passing parameters is also to reminds developer users that conj will evaluate its first parameter, the sequence, even tough it is a lazy one (AFAIK). At least that works as an idiom in my personal case. It would be good to know the point of view of a language designer on that topic... :-)

My conclusion would be: If you design your function to takes multiple arguments, put the new elements on the right. It's common idiom. When lazy, consider the legacy cons approach. But in the end I guess it won't be really important and it is probably just a matter of taste.

Update: As a general rule, when you don't know what to do for interface design, try to see how your language/standard library is designed. I don't for Javascript, but in C++ most of time it is carefully designed and choices are made for good reason. I think that is a good piece of advice to follow.

share|improve this answer
add comment

Long story short, it's a lot easier to remember -and more logical IMO- if one can read

find(what, where)

instead of

find(where, what)

and that still go with

target.whatToDo(withWhat)

as mentioned by Tyriar in first answer like in

array.get(key)
array.find(value)

so my answer is :

find(key, array)
share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.