example
add(int a, int b) Here we pass two argument int a, int b,
can we pass n argument with different data types like int,float,long,
is it possible?
I means i need to write only one method which handles n Arguments.
Yes, it is possible to pass arguments with different data types to Objective-C methods. I assume you're speaking about Objective-C, since the question is tagged iphone.
For example, you could have a method like:
- (void)foo:(int)foo bar:(float)bar baz:(long)baz {
// ...
}
If you are talking about C, you could have a function:
void myfunc(int foo, float bar, long baz) {
// ...
}
If you want to write functions that have variable sized argument lists (so it can take 1 parameter, or 2 parameters, or 3, ...), I suggest you take a look at this blog post which discusses variable argument lists in Objective-C/Cocoa or Apple's technical Q&A on variable argument lists.
- (int)add:(int)number1 to:(int)number2 {
return number1 + number2;
}
call it using [obj add:2 to:4]; where obj is the object receiving the add message.
You may use any type of arguments in the above to achieve what you have in mind. For example:
- (void)add:(int)number1 to:(float)number2 {
//print result here
}
Standard type conversions etc would apply like in any programming language.
If you are talking about totally arbitrary number of arguments, take a look at Variadic functions in Objective C (Google it). Plenty of good tutorials in the first search results page.
Anything is possible, but I am pretty certain it would require some serious hacking to get it to work for variable data types. If you can change the requirements to be a variable number of specific data type, then you should look at an excellent tutorial at "Cocoa with Love" : variable-argument-lists-in-cocoa
Related
I'm a Swift newbie and am having a bit of trouble understanding what a variadic parameter is exactly, and why it's useful. I'm currently following along with the online Swift 5.3 guide, and this is the example that was given for this type of parameter.
func arithmeticMean(_ numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// returns 3.0, which is the arithmetic mean of these five numbers
arithmeticMean(3, 8.25, 18.75)
// returns 10.0, which is the arithmetic mean of these three numbers
Apparently, the variadic parameter called numbers has a type of Double..., which allows it to be used in the body of the function as a constant array. Why does the function return Double(numbers.count) instead of just numbers.count? And instead of creating a variadic parameter, why not just create a parameter that takes in an array that's outside of the function like this?
func addition(numbers : [Int]) -> Int
{
var total : Int = 0
for number in numbers
{
total += number
}
return total
}
let totalBruhs : [Int] = [4, 5, 6, 7, 8, 69]
addition(numbers: totalBruhs)
Also, why can there only be one variadic parameter per function?
Variadic parameters need (well, not need, but nice) to exist in Swift because they exist in C, and many things in Swift bridge to C. In C, creating a quick array of arbitrary length is not so simple as in Swift.
If you were building Swift from scratch with no backwards compatibility to C, then maybe they'd have been added, and maybe not. (Though I'm betting yes, just because so many Swift developers are used to languages where they exist. But then again, languages like Zig have intentionally gotten rid of variadic parameters, so I don't know. Zig also demonstrates that you don't need variadic parameters to bridge to C, but still, it's kind of nice. And #Rob's comments below are worth reading. He's probably not wrong. Also, his answer is insightful.)
But they're also convenient because you don't need to add the [...], which makes it much nicer when there's just one value. In particular, consider something like print:
func print(_ items: Any..., separator: String = " ", terminator: String = "\n")
Without variadic parameters, you'd need to put [...] in every print call, or you'd need overloads. Variadic doesn't change the world here, but it's kind of nice. It's particularly nice when you think about the ambiguities an overload would create. Say you didn't have variadics and instead had two overloads:
func print(_ items: [Any]) { ... }
func print(_ item: Any) { print([item]) }
That's actually a bit ambiguous, since Array is also a kind of Any. So print([1,2,3]) would print [[1,2,3]]. I'm sure there's some possible work-arounds, but variadics fix that up very nicely.
There can be only one because otherwise there are ambiguous cases.
func f(_ xs: Int..., _ ys: Int...)
What should f(1,2,3) do in this case? What is xs and what is ys?
The function you've shown here doesn't return Double(numbers.count). It converts numbers.count to a Double so it can be divided into another Double. The function returns total / Double(numbers.count).
And instead of creating a variadic parameter, why not just create a parameter that takes in an array that's outside of the function ... ?
I agree with you that it feels intuitive to use arrays for arithmetic functions like “mean”, “sum”, etc.
That having been said, there are situations where the variadic pattern feels quite natural:
There are scenarios where you are writing a function where using an array might not be logical or intuitive at the calling point.
Consider a max function that is supposed to be returning the larger of two values. It doesn’t feel quite right to impose a constraint that the caller must create an array of these values in order to return the larger of two values. You really want to allow a nice, simple syntax:
let result = max(a, b)
But at the same time, as an API developer, there’s also no reason to restrict the max implementation to only allow two parameters. Maybe the caller might want to use three. Or more. As an API developer, we design API’s for naturally calling points for the primary use cases, but provide as much flexibility as we can. So a variadic function parameter is both very natural and very flexible.
There are lots of possible example of this pattern, namely any function that naturally feels like it should take two parameters, but might take more. Consider a union function for two rectangles and you want the bounding rectangle. Again, you don’t want the caller to have to create an array for what might be a simple union of two rectangles.
Another common example would be where you might have a variable number of parameters but might not be dealing with arrays. The classic example would be printf pattern. Or another is where you are interacting with some SQL database and might be binding values to ? placeholders in the SQL or the like (to protect against SQL injection attacks):
let sql = "SELECT book_id, isbn FROM books WHERE title = ? AND author = ?"
let resultSet = db.query(sql, title, author)
Again, in these cases, suggesting that the caller must create an array for this heterogenous collection of values might not feel natural at the calling point.
So, the question isn’t “why would I use variadic parameter where arrays are logical and intuitive?” but rather “why would I force the use of array parameters where it might not be?”
I know that we can use
/// index variable
var i = 0
as a documentation comment for a single variable.
How can we do the same for a loop variable?
The following does not work:
var array = [0]
/// index variable
for i in array.indices {
// ...
}
or
var array = [0]
for /** index variable */ i in array.indices {
// ...
}
Background:
The reason why I don’t use "good" variable names is that I’m implementing a numerical algorithm which is derived using mathematical notation. It has in this case only single letter variable names. In order to better see the connection between the derivation and the implementation I use the same variable names.
Now I want to comment on the variables in code.
The use of /// is primarily intended for use of documenting the API of of a class, struct, etc. in Swift.
So if used before a class, func, a var/let in a class/struct, etc. you are attaching documentation to that code aspect that Xcode understands how to show inline. It doesn’t know how to pickup that information for things inside of function since at this time that is not the intention of /// (it may work for simple var/let but not likely fully on purpose).
Instead use a simple // code comment for the benefit of any those working in the code however avoid over documenting the code since good code is likely fairly self explaining to anyone versed in the language and adding unneeded documentations can get in the way of just reading the code.
This is a good reference for code documentation in Swift at this time Swift Documentation
I woud strongly push back on something like this if I saw it in a PR. i is a massively well adopted "term of art" for loop indices. Generally, if your variable declaration name needs to be commented, you need a better variable name. There are some exceptions, such as when it stores data with complicated uses/invariants that can't be captured in a better way in a type system.
I think commenting is one area that beginners get wrong, mainly from being misled by teachers or by not yet fully understanding the purpose of comments. Comments don't exist to create an english based, psuedo-programming language in which your entire app will be duplicated. Understanding the programming language is a minimal expectation out of contributors to a project. Absolutely no comments should be explaining programming language features. E.g. var x: Int = 0 // declares a new mutable variable called x, to the Int value 0, with the exception of tutorials for learning Swift.
Commenting in this manner might seem like it's helpful, because you could argue it explains things for beginners. That may be the case, but it's suffocating for all other readers. Imagine if novel had to define all the English words they used.
Instead, the goal of documentation to explain the purpose and the use of things. To answer such questions as:
Why did you implement something this way, and not another way?
What purpose does this method serve?
When will this method of my delegate be called?
Case Study: Equatable
For a good example, take a look at the documentation of Equatable
Some things to notice:
It's written for an audience of Swift developers. It uses many things, which it does not explain such as, arrays, strings, constants, variable declaration, assignment, if statements, method calls (such as Array.contains(_:)), string interpolation, the print function.
It explains the general purpose of this protocol.
It explains how to use this protocol
It explains how you can adopt this protocol for your own use
It documents contractual requirements that cannot be enforced by the type system.
Since equality between instances of Equatable types is an equivalence relation, any of your custom types that conform to Equatable must satisfy three conditions, for any values a, b, and c:
a == a is always true (Reflexivity)
a == b implies b == a (Symmetry)
a == b and b == c implies a == c (Transitivity)
It explains possible misconceptions about the protocol ("Equality is Separate From Identity")
I'm filling a few gaps in my existing Swift programming language skills before moving onto the more advanced features.
I have checked Apples... "Swift Programming Language" guide and Google search shows lots of information about the rules around using the parameters, but I am looking for the overall Why , not the How...
Question:
Why is there a need to have parameters and return value types for functions in Swift?
(I am not asking about the parameter names etc., but a higher level (general) question on 'Why')
I have made a number of programs using simple C-Style functions in Swift, without a need for parameters or return values which works fine as I know what the functions should be doing for me.
Simple e.g.
func printName() {
print("John")
}
However, there are 'exceptions' like some in-built Swift functions.
E.g....
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return colors.count
}
etc. for table view or collection view usage .
So the only reason I see for using parameters + return values (type) in functions is to ensure only specific type of data is inputted and outputted.
In other words, its a way to avoid unexpected outcomes. So acting almost like a Switch statement, where if I have a specific condition is met -- a specific output will occur... (in functions... "an action").
Am I correct in this understanding, in trying to understand why / where one needs to use parameters & / or return values types with Functions? Or are there other practical reasons? If so can you provide an example?
Many thanks in advance!!!!
If you don't use parameters, you're tied to use what's visible in your scope.
if your function is inside a ViewController, all properties inside that VC, also global scope variables (horrible)
if your function is in global scope, you can only use global scope symbols (horrible, again)
You really do want to pass in things using parameters. This way you can:
auto check types (compiles is doing for you)
check for optionality
check value ranges
test your functions using Unit Tests. if you use global symbols, you're tied to that symbols, can't change them
less maintenance: changes outside your function doesn't affect you
Also, having a clear return type helps other developers and your future-self to understand what's returning from that function: a tuple? An optional array? A number? Also, having defined output types helps you with testing your functions.
Using only global variables & procedures (chunks of code to process those global vars) could work on a small scale. That's the old approach use with languages like FORTRAN, BASIC, COBOL... The moment your project grows, you need to isolate one part of your code from the other. For that:
use functions & a functional approach
use OOP
Let's imagine a sum function
func sum(a: Int, b:Int) -> Int {
return a + b
}
What happen if we remove the parameter types
func sum(a, b) -> Int {
return a + b // what?
}
Of course this is not allowed by the compiler but let's try to imagine.
Now a and b could be anything (like a String and a UIImage). How could we write the code to sum 2 things and get an Int?
Another test, let's remove the return type
func sum(a:Int, b:Int) -> ??? {
return a + b
}
Now let's try to invoke our crazy function
let tot: Int = sum(1, b: 2)
but since sum could return any kind of value how can we put the result into an Int constant?
All is in the subject, really.
I fail to see what the difference in behavior is between those two methods for x:
// first version
Method m(ByRef x As whatever)
{
// play with x
}
// second version
Method m(Output x As whatever)
{
// play with x
}
There must be some reason why both those modifiers exist, however my "mastery" (uhm) of the language is not enough to understand the difference. I have tried and read the documentation, search it etc, to no avail so far.
So, what is the difference between those two argument modifiers?
Well those are just "prettifiers", they don't do much in terms of actual language behaviour, and only used to provide documentation. Idea is that arguments documented as ByRef provide both input and output, for example you can pass an array to be sorted, and Output arguments only provide output, for example list of errors. Output modifier was introduced later, and a lot of system code still use ByRef for both use cases.
If argument is actually passed by reference is only determined by method caller, and keyword doesn't really matter. You will call your method as ..m(.parameter) to pass variable by reference, and ..m(parameter) to pass variable by value.
Imagine two languages which (apart from the type information) do have exactly the same syntax, but one is statically typed while the other one uses dynamic typing. Then, for every program written in the statically typed language, one can derive an equivalent dynamically typed program by removing all type information. As this is not neccessarily possible the other way around, the class of dynamically typed programs thus is strictly larger than the class of statically typed programs. Let's call this dynamically typed programs, for which there is no mapping of variables to types making them statically typed "real dynamically typed programs".
As both language families are definitly turing-complete, we can be sure that for every such real dynamically typed program there exists a statically typed program doing exactly the same thing, but I often read that "experienced programmers are able to write very elegant code in dynamically typed languages". I thus ask myself: Are there any good examples of real dynamically typed programs, for which any equivalent statically typed programm clearly is much more complex / much less "elegant" (whatever that may mean)?
Do you know of any such examples?
I am sure that for many "elegance" problems of static languages, static type checking itself isn't to blame, but the lack of expressiveness of the static type system implemented in the language and the limited capabilities of the compiler. If this is done "righter" (like in Haskell for example), then suddenly the programs turn out to be terse, elegant .. and safer that their dynamic counterpart.
Here's an illustration (C++ specific, sorry): C++ is so powerful, that it implements a metalanguage with it's template class system. But still, a very simple function is hard to declare:
template<class X,class Y>
? max(X x, Y y)
There is an astounding amount of possible solutions, like ?=boost::variant<X,Y> or computing ?=is_convertible(X,Y)?(X:is_convertible(Y,X):Y:error), none of them really satisfiying.
But now imagine a preprocessor, that could transform an input program into it's equivalent continuation passing style form, where each continuation is a callable object which accepts all possible argument types. A CPS version of max would look like this:
template<class X, class Y, class C>
void cps_max(X x, Y y, C cont) // cont is a object which can be called with X or Y
{
if (x>y) cont(x); else cont(y);
}
The problem is gone, max calls a continuation which accepts X or Y. So, there is a solution for max with static type checking, but we can't express max in it's non-CPS form, untransform(cps_max) is undefined, so to speak. So,we have some argument that max can be done right, but we don't have the means to do so. This is lack of expressiveness.
Update for 2501:
Assume there are some unrelated types X and Y and there is a bool operator<(X,Y). What shouldmax(X,Y) return? Let us further assume, that X and Y both have a member function foo();. How could we make it possible to write:
void f(X x, Y y) {
max(X,Y).foo();
}
returning either X or Y and invoking foo() on the result is no problem for a dynamic language, but close to impossible for most static languages. However, we can have the intended functionality by rewriting f() to use cps_max:
struct call_foo { template<class T> void operator(const T &t) const { t.foo(); } };
void f(X x, Y y) {
cps_max(x,y,call_foo());
}
So this can't be a problem for static type checking, but it looks very ugly and does not scale well beyond simple examples. So what is missing from this static language that we can not provide a static and readable solution.
Yes, check out Eric Raymonds Python Success Story. Basically, it is about how much easier reflection-type tasks are with dynamically typed programming languages.
Groovy and XML
Groovy and Domain-specific language