-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support functions with variable length arguments #77
Comments
With #167 we don't need this annotation. See that issue for a better example of var args. Open question, will the Maybe if your last parameter is |
Proposal: add a // This is the typical way to declare a List(T)'s add() method:
pub fn add(list: &Self, item: T) {
list.ensure_capacity(list._size + 1);
list._buf[list._size] = item;
list._size += 1;
}
// Here is an alternative that is backward compatible in both API and performance:
pub fn add(list: &Self, ...items: []const T) {
list.ensure_capacity(list._size + items.len);
for (items) |item, i| {
list._buf[list._size + i] = item;
}
list._size += items.len;
}
// In the typical case where add() is called with a single parameter,
// the compiler emits code identical to the first case.
// In the case where the caller knows they will add exactly two parameters,
// the method can do a single ensure_capacity().
// If we want the List class to expose ensure_capacity() to callers,
// we can also offer an unchecked add method that skips the capacity check:
pub fn add_unchecked(list: &Self, ...items: []const T) {
for (items) |item, i| {
list._buf[list._size + i] = item;
}
list._size += items.len;
}
// and then the common add method can reuse the above by forwarding the args:
pub fn add(list: &Self, ...items: []const T) {
list.ensure_capacity(list._size + items.len);
list.add_unchecked(...items);
} The The An open question is should varargs functions always be specialized for the number of parameters? The claim about performance in the above example assumes the function will be specialized for 1 argument. However, specializing a varargs function for every different number of parameters may be undesirable bloat. One may argue that varargs functions should be designed for relativley few variations on the number of parameters, since each of these variations will be deliberately written by a programmer at author-time. However, one also may argue that a 0-1-Infinity pattern could be employed. My vote is for complete specialization. Another open question is whether we could relax the restrictions on passing This feature can be combined with an orthogonal feature, the pub fn print_error(error_code: u32, inline fmt: []const u8, ...args: []var) {
const error_name = error_names[error_code];
// this assumes the ++ operator works on compile-time constant-length arrays
// with variable values at each index.
const new_args = []var{error_name, error_code} ++ args;
io.stderr.printf("ERROR: %s(%d): " ++ fmt ++ "\n", ...new_args);
}
// alternatively:
pub fn print_error(error_code: u32, inline fmt: []const u8, ...args: []var) {
const error_name = error_names[error_code];
// this assumes a relaxed requirement on passing `...` arguments.
io.stderr.printf("ERROR: %s(%d): " ++ fmt ++ "\n", error_name, error_code, ...new_args);
} |
Counter proposal: pub fn addUnchecked(list: &Self, items: ...) {
for (items) |item, i| {
list._buf[list._size + i] = item;
}
list._size += items.len;
}
pub fn add(list: &Self, items: ...) {
list.ensureCapacity(list._size + items.len);
// because `items` is of type `(args)` it automatically flattens out when used as a parameter
list.addUnchecked(items);
}
pub fn printError(error_code: u32, comptime fmt: []const u8, args: ...) {
const error_name = error_names[error_code];
io.stderr.printf("ERROR: %s(%d): " ++ fmt ++ "\n", error_name, error_code, args);
} The The |
|
I moved the remaining items to their own issues which are not prioritized for 0.1.0 milestone. |
Here is some brainstorming:
Here, the
print
is annotated with another function that runs to validate function calls. Theanalyze_print_call
function will not actually get output in the translation unit, it is run as a constant expression evaluation at compile time for every print function callsite.The text was updated successfully, but these errors were encountered: