Generic function in Vala - function

I wrote a maximum() generic function in Vala.
However, it does not compile.
Here it is:
T maximum<T>(T a, T b) {
return a > b ? a : b;
}
void main() {
stdout.printf("%d\n", maximum(10, 2));
}
I got the following error:
generics.vala:2.12-2.16: error: Relational operation not supported for types `T' and `T'
Do you know how I can fix this function to be able to compile it?
Thanks.

Generic direct comparison and various other operations aren't supported by current Vala. You may want to use and implement Gee.Comparable interface to use a compare_to() method instead.

Related

Error returned when trying to run a basic function in dart

I'm new to dart (coming from a python background), and I'm struggling to make a function work. I've created the following function:
void main() {
int number = 22;
Function evenChecker(int number) {
if ((number%2) == 0) {
print('$number is even');
} else {
print('$number is odd');
}
}
}
but is get the following error:
Error: A non-null value must be returned since the return type 'Function' doesn't allow null.
bin/hello_dart_project.dart:4
- 'Function' is from 'dart:core'.
Additionally, if anyone has any suggestions about a good dart learning resource, I'd highly appreciate the advice.
^
Unlike Python or JavaScript, there is no keyword to define functions in dart. Instead, we declare functions by starting with their return type:
void evenChecker(...) {...}
^^^^
// This is the return type. "void" means "returns the value null" or "doesn't return anything"

Solidity - OpenZeppeling/utils/Counters question

When we use the Counters library, we init it usually as such
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
so far all good. Using Counters library methods for Counters.Counter (the struct in the library) and assigning _tokenIds to point to that struct. (+-? cool.)
What confuses me is the function definitions inside Counters; i.e
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
The function takes in a varaible called counter ? is it not expecting an argument ?
Where is the link between our defined _tokenIds to the smaller-case counter ?
I don't know why I find this so confusing but it seems like something's missing to me (even tho I know its not missing, just failing to understand).
Thanks in advance.
The using <library> for <type> expression allows you to use functions of the library on variables of this type. And it automatically passes the variable as the first argument of the function when you're calling it as a member function.
So in your case, Counters.current(_tokenIds) (library function) is the same as _tokenIds.current() (member function).
Docs: https://docs.soliditylang.org/en/v0.8.14/contracts.html#using-for

How to create an async variadic function in Vala

Is it possible to create an async variadic function in Vala? If yes, how?
I couldn't find anything related in the Vala tutorial provided on the gnome website or in any example of code. My conclusion is that it's not possible, because vala requires async functions to have fixed arguments. But then, i don't know how to achieve something similar to a variadic function.
Example of code (non async, working without issues):
void long_function(string first_val, ...) {
var list = va_list();
string? second_val = list.arg();
print("%s,%s\n", first_val, second_val);
}
void main() {
long_function("a", "b");
}
Example of async code (not working):
async void long_function(string first_val, ...) {
var list = va_list();
string? second_val = list.arg();
print("%s,%s\n", first_val, second_val);
}
void main() {
long_function.begin("a", "b");
}
The error returned by the vala compiler (compiled with: vala --pkg gio-2.0 main.vala) is
main.vala:7.28-7.30: error: Argument 2: Cannot convert from `unowned string' to `void GLib.AsyncReadyCallback? (GLib.Object?, GLib.AsyncResult)'
My real use case scenario is (pseudo code):
async void fetch_from_api_with_params(...) {
// ExternalLibrary is a function which accepts a string with a url and any number of POST parameters
ExternalLibrary.fetch_from_url.begin("http://example.com", va_list());
// ...
}
Sadly, this is not possible with Vala. Vala uses C's variadic arguments system and GLib's co-routine system. Unfortunately, the two aren't compatible. Depending on your needs, you might be able to pass an array of Variant.

How can I create a function which accepts a function with specific parameters as an argument?

I'd like to create a function which accepts a function that accepts specific types of parameters as an argument. For example:
myFn(Function paramFn) {
paramFn([1, 2, 3]);
}
How can I ensure that paramFn accepts a List<int> as an only parameter?
You can use typedef to define the signature you want like described in Kul's answer or you can simply inline the function signature in the parameter:
myFn(void paramFn(List<int> l)) {
paramFn([1, 2, 3]);
}
You can use typedef to associate a symbol with a function that satisfies the signature you want. Something like
typedef void ParamFn(List<int> l);
myFn(ParamFn f) {
f('abc'); // compile time error
f([1,2,3]); // works fine
}
That's what typedefs are for, although I'm not sure how rigid the strong mode will enforce it yet.

What Does "Overloaded"/"Overload"/"Overloading" Mean?

What does "Overloaded"/"Overload" mean in regards to programming?
It means that you are providing a function (method or operator) with the same name, but with a different signature.
For example:
void doSomething();
int doSomething(string x);
int doSomething(int a, int b, int c);
Basic Concept
Overloading, or "method overloading" is the name of the concept of having more than one methods with the same name but with different parameters.
For e.g. System.DateTime class in c# have more than one ToString method. The standard ToString uses the default culture of the system to convert the datetime to string:
new DateTime(2008, 11, 14).ToString(); // returns "14/11/2008" in America
while another overload of the same method allows the user to customize the format:
new DateTime(2008, 11, 14).ToString("dd MMM yyyy"); // returns "11 Nov 2008"
Sometimes parameter name may be the same but the parameter types may differ:
Convert.ToInt32(123m);
converts a decimal to int while
Convert.ToInt32("123");
converts a string to int.
Overload Resolution
For finding the best overload to call, compiler performs an operation named "overload resolution". For the first example, compiler can find the best method simply by matching the argument count. For the second example, compiler automatically calls the decimal version of replace method if you pass a decimal parameter and calls string version if you pass a string parameter. From the list of possible outputs, if compiler cannot find a suitable one to call, you will get a compiler error like "The best overload does not match the parameters...".
You can find lots of information on how different compilers perform overload resolution.
A function is overloaded when it has more than one signature. This means that you can call it with different argument types. For instance, you may have a function for printing a variable on screen, and you can define it for different argument types:
void print(int i);
void print(char i);
void print(UserDefinedType t);
In this case, the function print() would have three overloads.
It means having different versions of the same function which take different types of parameters. Such a function is "overloaded". For example, take the following function:
void Print(std::string str) {
std::cout << str << endl;
}
You can use this function to print a string to the screen. However, this function cannot be used when you want to print an integer, you can then make a second version of the function, like this:
void Print(int i) {
std::cout << i << endl;
}
Now the function is overloaded, and which version of the function will be called depends on the parameters you give it.
Others have answered what an overload is. When you are starting out it gets confused with override/overriding.
As opposed to overloading, overriding is defining a method with the same signature in the subclass (or child class), which overrides the parent classes implementation. Some language require explicit directive, such as virtual member function in C++ or override in Delphi and C#.
using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}
public class Line : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}
An overloaded method is one with several options for the number and type of parameters. For instance:
foo(foo)
foo(foo, bar)
both would do relatively the same thing but one has a second parameter for more options
Also you can have the same method take different types
int Convert(int i)
int Convert(double i)
int Convert(float i)
Just like in common usage, it refers to something (in this case, a method name), doing more than one job.
Overloading is the poor man's version of multimethods from CLOS and other languages. It's the confusing one.
Overriding is the usual OO one. It goes with inheritance, we call it redefinition too (e.g. in https://stackoverflow.com/users/3827/eed3si9n's answer Line provides a specialized definition of Draw().