Hello !
I've noticed that there is not default/varg parameters for functions, there is any plan to include then ?
Cheers !
Hey
Varargs are partially implemented. foo(a, b int, ..)
You can call foo(2,3, 4, 5), but you can't use the values yet. It will be implemented soon.
If by default parameters you mean foo(a int = 4, b int = 0), no V will have no default values.
Again like string/char quotes and optional semi colon, why not use already know grammar for vargas "..." three dots ?
What's the roadblock for default parameters ?
Cheers !
It'll be 3 dots, forgot to mention that.
Default parameters are not going to be implemented, because they complicate the code and the compiler.
It's a bit sad, that default parameters will not be supported as they play IMHO a crucial role in adoption of high-level libraries (and are thus an inevitable prerequisite for building a strong ecosystem and very quickly so). I don't want learn how DBs work internally, how this embedded library solves problem A, B, and also C to start using it. I just want to include it and call the method. Nobody wants to spend time understanding all arguments and nobody wants to read through documentation having hundreds of methods (more than often with different names to make remembering even more difficult) just because there are many combinations of different "default values" (not speaking about code duplication and unnecessary interlinking). This is one very real downside of Go :cry:.
This is why Python wins as the language of choice for everything new. And no, it's not that Python is dynamically typed, it's not about Python's syntax, it's not about duck typing, it's because the enormous library ecosystem is extremely easy to adopt due to sane default values without having any knowledge about the particular library topic while having the opportunity to tweak one or two of the default values extremely easily.
If V wants to stay easy to use, I would strongly recommend picking up the gauntlet and implementing it (even if the simplest implementation should end up being 2 pass with a temporary file instead of making it 1 pass, but highly complicated).
Functions with default args are basically overloaded functions. Overloading adds a lot of weight to the code and makes it less predictable and readable.
More than 4 args shouldn't be used anyway, the convention is to use a config struct for such complex functions.
Functions with default args are basically overloaded functions. Overloading adds a lot of weight to the code and makes it less predictable and readable.
Ahah, now I understand what you mean. If we'll constrain us so much, that we'll look at default args as overloaded functions, then default args absolutely do not make any sense. No doubt about that. What I meant is something like:
class Serial:
def __init__(port=None, baudrate=9600,
bytesize=EIGHTBITS, parity=PARITY_NONE,
stopbits=STOPBITS_ONE, timeout=None,
xonxoff=False, rtscts=False, write_timeout=None,
dsrdtr=False, inter_byte_timeout=None,
exclusive=None):
...
(https://pyserial.readthedocs.io/en/latest/pyserial_api.html )
Would you tell me how the most common defaults looked like? How would you tell me in V? How would you overload this function to achieve similar result? Are you an expert in this domain? Are you an expert in all the domains of all the hundreds of wildly different libraries used in the bigger application you're writing? Will you have time to deeply understand the topic to be in position to very well tell what are the "golden defaults", so that you can finally use them in your code?
More than 4 args shouldn't be used anyway, the convention is to use a config struct for such complex functions.
This makes sense for a (very) low-level language, but not for a high-level one. I can't tell whether V aims to be higher or lower level, but I would prefer it to be very high level as e.g. threaded concurrency (and many other Vs features) is definitely not a builtin for low-level languages. The higher-level the library, the more default args are being used.
Functions with 10 arguments are a sign of a bad architecture.
V structs will have default args, so they can be used to achieve the same functionality:
foo({
port:8080
baudrate: 9600
bytesize: 8
xonxoff: false
})
Thanks @medvednikov, that sounds good to me if the defaults for structs would look and behave like this:
module00.v:
module module00
struct S1 { // note S1 is not pub
f1: 5
f2: 6
f3: 'abc'
f4 string
f5 int
}
pub fn f( args S1 ) int { return args.f5 }
main.v:
import module00
struct S1 { // this is OK - this main.S1 struct is distinct from
// the struct S1 in module00 and
// thus not compatible even though
// the signature and values are the same
f1: 5
f2: 6
f3: 'abc'
f4 string
f5 int
}
result := f( { f4: 'abc' f5: 9 } ) // this is OK
x := S1{ f4: 'def' f5: 3 } // this is OK (the struct main.S1 is being used)
result2 := f( x ) // not OK as module00.S1 is expected but main.S1 was given
Functions with 10 arguments are a sign of a bad architecture.
I think the reality shows us it's not that bad as we used to hear 30 years ago when CPUs have had low number of registers, very few memory (stack could not grow much) and a "context switch" was equal to "function call" (in terms of the feeling "it's really heavy-weight to call a function" whereas nowadays nobody cares even about preemptive context switches between heavy-weight processes... yeah, a bit exaggerating but you got the idea).
My opinion is straightforward - I try to look at functions/procedures in programming languages as mathematical functions especially when it comes to arguments - i.e. if the body of the function is mathematically "a function of 2048 variables", then I'll pass all of them as function arguments. I expect technology to serve us, not us to serve technology.
But the default values struct solution could solve this issue easily if the default struct doesn't have to be global when importing a module in which case I would be really thankful to V and you, the creators and maintainers.
It's already done
@dumblob default struct values are here:
struct Foo {
a int
b int = 10
}
foo := Foo{}
assert foo.a == 0
assert foo.b == 10
@medvednikov that's good news. Do the examples outlined above in https://github.com/vlang/v/issues/453#issuecomment-527794862 work for you (especially the cross-module interaction)?
Most helpful comment
Hey
Varargs are partially implemented.
foo(a, b int, ..)You can call
foo(2,3, 4, 5), but you can't use the values yet. It will be implemented soon.If by default parameters you mean
foo(a int = 4, b int = 0), no V will have no default values.