Function and Arguments - coding-style

What does Robert C Martin meant by saying
Output arguments are harder to understand than input arguments. When
we read a function, we are used to the idea of information going in to
the function through arguments and out through the return value. We
don’t usually expect information to be going out through the
arguments. So output arguments often cause us to do a double-take.
in his book 'The Clean Code' in chapter 3 Functions when he is talking about arguments in functions and which argument is he referring to here?

He means that we shouldn't have function that modifies input arguments.
As an example (from "Clean Code"):
public void appendFooter(StringBuffer report)
He says report is rather output argument here because this function
modifies it. Much better would be to have Report object and call:
report.appendFooter();
or instead of:
public void changeContactDetails(Person person)
do
person.changeContactDetails()

Related

lua (Syntax): Calling a function that returns more than 1 value, and using those values as arguments, but without extra lines of variable assignment?

I have a situation where I need to call the following:
function xy(i)
return i,i+8
end
And use its output in another function.
function addition(x,y)
return x+y
end
Is there a way to get this to work more elegantly than writing it like:
i.e. i=10; x,y=xy(10); addition(x,y)--28
I'm looking for something like:
i.e. i=10; addition(xy(10)--where I somehow get two arguments here)
Both functions are generics used elsewhere, merging isn't viable, possible edits to what/how they return might be.
At least as of Lua 5.1, the following works 'as requested'.
When a function call is the last (or the only) argument to another call, all results from the first call go as arguments. [There are several examples using print.]
function xy(i)
return i,i+8
end
function addition(x,y)
return x+y
end
addition(xy(10)) -- 28
A more wordy way, that might be useful to decompose in similar cases needing a little bit more flexibility, is to convert the result to a table and then use unpack (added in 5.1). This approach is result -> table -> unpack -> arguments (per above).
addition(unpack({xy(10)})) -- 28
Here are both approaches in replit.

Understanding Js.Promise.resolve(. ) dot syntax in ReasonML

I'm trying to understand the docs:
https://reasonml.github.io/docs/en/promise
In the usage section there is:
let myPromise = Js.Promise.make((~resolve, ~reject) => resolve(. 2));
Why is there is dot before the 2? What does it mean and what does it do?
(. ) as used here, in function application, means the function should be called with an uncurried calling convention.
When used in a function type, like the type of resolve here, (. 'a) => unit, it means the function is uncurried.
Ok, so what the hell does that mean? Wweeellll, that's a bit of a story. Here goes:
What is uncurrying?
Uncurrying is the opposite of currying, so let's explain that first and then compare.
Currying is the process of transforming a function that takes multiple arguments into a series of functions that take exactly one argument each and return either the final return value or a function taking the next argument. In Reason/OCaml this is done automatically for us, and is why in OCaml function types have arrows between its arguments (e.g. 'a -> 'b -> 'ret). You can write function types in this way in Reason too ('a => 'b => 'ret), but by default it's hidden by the syntax (('a, 'b) => 'ret), which is meant well but might also make it more difficult to understand why functions behave unexpectedly in some circumstances.
In uncurried languages supporting first-class functions you can also curry functions manually. Let's look at an example in ES6. This is a normal "uncurried" ES6 function:
let add = (a, b) => a + b;
and this is its curried form:
let add = a => b => a + b;
and with parentheses to emphasize the separate functions:
let add = a => (b => a + b);
The first function takes the argument a, then returns a function (that closes over a) which takes the argument b and then computes the final return value.
This is cool because we can easily partially apply the a argument without using bind, but it's a bit inconvenient to apply all arguments to it at once, since we have to call each function individually:
let result = add(2)(3);
So not only does Reason/OCaml automatically curry functions upon creation, but it also provides a calling convention that lets us conveniently apply multiple arguments too.
And this all works great! ...as long as every function is curried. But then we want to hang out and talk with JavaScript, where most functions are not (but see Ramda for one notable exception). To be able to call uncurried JavaScript functions we need an uncurried calling convention, and to be able to create functions that can be called as expected from JavaScript we need an uncurried function type.
Why does resolve need to be uncurried?
An even better question might be "why aren't all external functions uncurried"? The answer is that they actually are, but the type and calling convention can often both be inferred at compile-time. And if not it can often be "reflected" at runtime by inspecting the function value, at a small (but quickly compounding) cost to performance. The exceptions to this are where it gets a bit muddy, since the documentation doesn't explain exactly when explicit uncurrying is required for correct functioning, and when it isn't required but can be beneficial for performance reasons. In addition, there's actually two annotations for uncurried functions, one which can infer the calling convention and one which requires it to be explicit, as is the case here. But this is what I've gathered.
Let's look at the full signature for Js.Promise.make, which is interesting because it includes three kinds of uncurried functions:
[#bs.new]
external make :
([#bs.uncurry] (
(~resolve: (. 'a) => unit,
~reject: (. exn) => unit) => unit)) => t('a) = "Promise";
Or in OCaml syntax, which I find significantly more readable in this case:
external make : (resolve:('a -> unit [#bs]) ->
reject:(exn -> unit [#bs]) -> unit [#bs.uncurry]) -> 'a t = "Promise" [##bs.new]
The first kind of function is make itself, which is an external and can be inferred to be uncurried because all externals are of course implemented in JavaScript.
The second kind of function is the callback we'll create and pass to make. This must be uncurried because it's called from JavaScript with an uncurried calling convention. But since functions we create are curried by default, [#bs.uncurry] is used here to specify both that it expects an uncurried function, and that it should be uncurried automatically.
The third kind of function is resolve and reject, which are callback functions passed back from JavaScript and thus uncurried. But these are also 1-ary functions, where you'd think the curried and uncurried form should be exactly the same. And with ordinary monomorphic functions you'd be right, but unfortunately resolve is polymorphic, which creates some problems.
If the return type had been polymorphic, the function might actually not be 1-ary in curried form, since the return value could itself be a function taking another argument, which could return another function and so on. That's one downside of currying. But fortunately it isn't, so we know it's 1-ary.
I think the problem is even more subtle than that. It might arise because we need to be able to represent 0-ary uncurried functions using curried function types, which are all 1-ary. How do we do that? Well, if you were to implement an equivalent function in Reason/OCaml, you'd use unit as the argument type, so let's just do that. But now, if you have a polymorphic function, it might be 0-ary if it's monomorphized as unit and 1-ary otherwise. And I suppose calling a 0-ary function with one argument has been deemed unsound in some way.
But why, then, does reject need to be uncurried, when it's not polymorphic?
Well... my best guess is that it's just for consistency.
For more info, see the manual (but note that it confuses currying with partial application)

es6- arrow function- no duplicate named arguments

I can't understand well about the last ways of arrow functions have:
No duplicate named arguments- arrow functions cannot have duplicate
named arguments in strict or nonstrict mode, as opposed to nonarrow
functions that cannot have duplicate named arguments only in strict
mode.
The above paragraph was picked from Book "Understanding ECMAScript 6" wrote by Nicholas C. Zakas in 'Function' chapter.
According to description above, I know that arrow function has not arguments like other function.
I can understand well the sentence before half, but the other half start by "as opposed to...".
What's that mean "nonarrow functions that cannot have duplicate named arguments only in strict mode."
In fact, functions in strict mode also have arguments. I have no idea what the author mean.
It means that the following is valid JavaScript:
function bar(foo, foo){}
It is not, however, when using strict mode:
'use strict';
function bar(foo, foo){}
// SyntaxError: duplicate formal argument foo
With arrow functions, duplicate named arguments are always, regardless of strict or non-strict mode, invalid.
(foo, foo) => {}
// SyntaxError: duplicate argument names not allowed in this context
According to description above, I know that arrow function has not arguments like other function.
Not sure whether you understood this correctly. Arrow functions can have parameters, it just does not have arguments.

What is an "argument"?

Assuming I have this code:
function question($argument)
{
var $q = "What does ($argument) mean?";
}
Can any tell me is there any other word (or phrase) that defines what an argument is?
I'm asking this because English is my second language, and I can't for life find a word in my language that defines "argument" in "programming".
I understand how arguments work, and what they are for, I just need a synonym word or phrase to be able to translate it to my language to make it easy to use and understand.
The best thing that I came up with (in my language) is (Passed Variable(s)), does that sound right? Is there any better wording?
Thanks
Parameters
Does that help?
("Passed Variables" is close ... and might work fine in your language)
I wouldn't use "passed variable" because arguments do not have to be variables.
Perhaps the most common usage of the term is seen in this example. Consider
// A function definition
function f(x, y) {
....
}
// A function call
f(57/p*q+4, z);
Most people would call x and y parameters, and call 57/p*q+4 and z arguments. Note that parameters are variables (unless the language has pattern-matching, not too common) and that arguments can be arbitrary expressions.
Now you may hear people call x and y "formal parameters" while the arguments are "actual parameters" but IMHO this distinction is a little old-fashioned. I may be wrong though.
The thing is that the argument is the expression that is passed to the parameter in a function call. So maybe "passed expression" is better than "passed variable" at the very least. Have fun translating. One fun thing about the vocabulary of computing is that almost every word (function, procedure, type, label, constant, variable, expression, declaration, statement, operator, argument, parameter, etc.) is just borrowed from a plain old English word. There aren't too many novel terms.
On the calling side it's an argument, on the function side it's a parameter.
"Parameter" vs "Argument"
An argument is what you pass into a function (also known as a subroutine). Arguments are also known as parameters. A function might take an argument and use it to calculate something or modify the argument itself.
Arguments are the variables of the functions that works during calling them.
And
parameters are also the variables of the functions that works during returning value to the program by that function.

scala coalesces multiple function call parameters into a Tuple -- can this be disabled?

This is a troublesome violation of type safety in my project, so I'm looking for a way to disable it. It seems that if a function takes an AnyRef (or a java.lang.Object), you can call the function with any combination of parameters, and Scala will coalesce the parameters into a Tuple object and invoke the function.
In my case the function isn't expecting a Tuple, and fails at runtime. I would expect this situation to be caught at compile time.
object WhyTuple {
def main(args: Array[String]): Unit = {
fooIt("foo", "bar")
}
def fooIt(o: AnyRef) {
println(o.toString)
}
}
Output:
(foo,bar)
No implicits or Predef at play here at all -- just good old fashioned compiler magic. You can find it in the type checker. I can't locate it in the spec right now.
If you're motivated enough, you could add a -X option to the compiler prevent this.
Alternatively, you could avoid writing arity-1 methods that accept a supertype of TupleN.
What about something like this:
object Qx2 {
#deprecated def callingWithATupleProducesAWarning(a: Product) = 2
def callingWithATupleProducesAWarning(a: Any) = 3
}
Tuples have the Product trait, so any call to callingWithATupleProducesAWarning that passes a tuple will produce a deprecation warning.
Edit: According to people better informed than me, the following answer is actually wrong: see this answer. Thanks Aaron Novstrup for pointing this out.
This is actually a quirk of the parser, not of the type system or the compiler. Scala allows zero- or one-arg functions to be invoked without parentheses, but not functions with more than one argument. So as Fred Haslam says, what you've written isn't an invocation with two arguments, it's an invocation with one tuple-valued argument. However, if the method did take two arguments, the invocation would be a two-arg invocation. It seems like the meaning of the code affects how it parses (which is a bit suckful).
As for what you can actually do about this, that's tricky. If the method really did require two arguments, this problem would go away (i.e. if someone then mistakenly tried to call it with one argument or with three, they'd get a compile error as you expect). Don't suppose there's some extra parameter you've been putting off adding to that method? :)
The compile is capable of interpreting methods without round brackets. So it takes the round brackets in the fooIt to mean Tuple. Your call is the same as:
fooIt( ("foo","bar") )
That being said, you can cause the method to exclude the call, and retrieve the value if you use some wrapper like Some(AnyRef) or Tuple1(AnyRef).
I think the definition of (x, y) in Predef is responsible. The "-Yno-predefs" compiler flag might be of some use, assuming you're willing to do the work of manually importing any implicits you otherwise need. By that I mean that you'll have to add import scala.Predef._ all over the place.
Could you also add a two-param override, which would prevent the compiler applying the syntactic sugar? By making the types taking suitably obscure you're unlikely to get false positives. E.g:
object WhyTuple {
...
class DummyType
def fooIt(a: DummyType, b: DummyType) {
throw new UnsupportedOperationException("Dummy function - should not be called")
}
}

Resources