{"action":"created","issue":{"url":"https://api.github.com/repos/andrewrk/zig/issues/132","repository_url":"https://api.github.com/repos/andrewrk/zig","labels_url":"https://api.github.com/repos/andrewrk/zig/issues/132/labels{/name}","comments_url":"https://api.github.com/repos/andrewrk/zig/issues/132/comments","events_url":"https://api.github.com/repos/andrewrk/zig/issues/132/events","html_url":"https://github.com/andrewrk/zig/issues/132","id":138345053,"number":132,"title":"expression type which enables variable argument functions","user":{"login":"andrewrk","id":106511,"avatar_url":"https://avatars.githubusercontent.com/u/106511?v=3","gravatar_id":"","url":"https://api.github.com/users/andrewrk","html_url":"https://github.com/andrewrk","followers_url":"https://api.github.com/users/andrewrk/followers","following_url":"https://api.github.com/users/andrewrk/following{/other_user}","gists_url":"https://api.github.com/users/andrewrk/gists{/gist_id}","starred_url":"https://api.github.com/users/andrewrk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andrewrk/subscriptions","organizations_url":"https://api.github.com/users/andrewrk/orgs","repos_url":"https://api.github.com/users/andrewrk/repos","events_url":"https://api.github.com/users/andrewrk/events{/privacy}","received_events_url":"https://api.github.com/users/andrewrk/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/andrewrk/zig/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/andrewrk/zig/milestones/1","html_url":"https://github.com/andrewrk/zig/milestones/0.1.0","labels_url":"https://api.github.com/repos/andrewrk/zig/milestones/1/labels","id":1513550,"number":1,"title":"0.1.0","description":"","creator":{"login":"andrewrk","id":106511,"avatar_url":"https://avatars.githubusercontent.com/u/106511?v=3","gravatar_id":"","url":"https://api.github.com/users/andrewrk","html_url":"https://github.com/andrewrk","followers_url":"https://api.github.com/users/andrewrk/followers","following_url":"https://api.github.com/users/andrewrk/following{/other_user}","gists_url":"https://api.github.com/users/andrewrk/gists{/gist_id}","starred_url":"https://api.github.com/users/andrewrk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andrewrk/subscriptions","organizations_url":"https://api.github.com/users/andrewrk/orgs","repos_url":"https://api.github.com/users/andrewrk/repos","events_url":"https://api.github.com/users/andrewrk/events{/privacy}","received_events_url":"https://api.github.com/users/andrewrk/received_events","type":"User","site_admin":false},"open_issues":29,"closed_issues":39,"state":"open","created_at":"2016-01-18T21:44:08Z","updated_at":"2016-07-29T20:12:30Z","due_on":null,"closed_at":null},"comments":0,"created_at":"2016-03-04T01:09:36Z","updated_at":"2016-07-29T20:12:30Z","closed_at":"2016-07-29T20:12:30Z","body":"Here is my proposal for an expression type which makes it possible to have variable argument functions. It requires a lot of advanced stuff that isn't implemented yet, such as:\r\n\r\n * generics (see #22)\r\n * inline parameters: the parameter must always be evaluated at compile time at the callsite, and then the function becomes inline\r\n * expressions as parameters: these must always be inline, and then you use `@eval` to evaluate the expression.\r\n * `@can_implicit_cast` the idea of this builtin is to tell you if an implicit cast is allowed. but this will probably be replaced by having the template string contain the types just like C's printf.\r\n * having an array as the last parameter in a function allowing you to call it with any number of arguments with matching types. We might add syntax for this to make it more explicit.\r\n\r\nSo, with this example, calling `os.printf(\"int: %  string: %\", 3, some_string);` would effectively result in this code, after inlining the function calls:\r\n\r\n```zig\r\nswitch (os.print_str(\"int: \")) {\r\n    error.Ok => |count| {\r\n        switch (os.print_u64(3)) {\r\n            error.Ok => |count_2| {\r\n                switch (os.print_str(\" string: \")) {\r\n                    error.Ok => |count_3| {\r\n                        switch (os.print_str(some_string)) {\r\n                            error.Ok => |count_4| {\r\n                                switch (os.flush()) {\r\n                                    error.Ok => count + count_2 + count_3 + count_4,\r\n                                    else => |err| err,\r\n                                }\r\n                            },\r\n                            else => |err| err,\r\n                        }\r\n                    },\r\n                    else => |err| err,\r\n                }\r\n            },\r\n            else => |err| err,\r\n        }\r\n    },\r\n    else => |err| err,\r\n}\r\n```\r\n\r\n### io.zig\r\n\r\n```zig\r\nstruct OutStream {\r\n    fd: isize,\r\n    buffer: [4 * 1024]u8,\r\n    index: isize,\r\n\r\n    fn print_one(T: type)(os: &OutStream, raw_value: T) -> %isize {\r\n        return switch (@typeof(value)) {\r\n            i64 => os.print_i64(value),\r\n            u64 => os.print_u64(value),\r\n            f64 => os.print_f64(value),\r\n            []u8 => os.print_str(value),\r\n            else => unreachable{},\r\n        }\r\n    }\r\n\r\n    pub print(os: &OutStream, inline format: []const u8, inline args: []expr) -> %isize {\r\n        var next_arg: isize = 0;\r\n        var print_count: isize = 0;\r\n        var start: isize = 0;\r\n        for (format) |c, i| {\r\n            if (c == '%') {\r\n                const slice = format[start...i];\r\n                if (slice.len > 0) {\r\n                    print_count += os.print_str(slice) %% |err| return err;\r\n                }\r\n                start = i + 1;\r\n\r\n                const arg = args[next_arg];\r\n                next_arg += 1;\r\n\r\n                const raw_value = @eval(arg);\r\n                // this casting allows number literals and string literals to work\r\n                // since we need to cast those types before invoking a generic function\r\n                const value = if (@can_implicit_cast(i64, raw_value)) {\r\n                    i64(raw_value)\r\n                } else if (@can_implicit_cast(u64, raw_value)) {\r\n                    u64(raw_value)\r\n                } else if (@can_implicit_cast([]u8, raw_value)) {\r\n                    ([]u8)(raw_value)\r\n                } else if (@can_implicit_cast(f64, raw_value)) {\r\n                    f64(raw_value)\r\n                } else {\r\n                    raw_value\r\n                }\r\n                const T = @typeof(value);\r\n                print_count += os.print_one(T)(value) %% |err| return err;\r\n            }\r\n        }\r\n\r\n        if (next_arg != args.len) unreachable{};\r\n\r\n        return print_count;\r\n    }\r\n\r\n    pub printf(os: &OutStream, args: []expr) -> %isize {\r\n        const result = os.print(args) %% |err| return err;\r\n        os.flush() %% |err| return err;\r\n        return result;\r\n    }\r\n\r\n    pub fn print_i64(os: &OutStream, x: i64) -> %isize {\r\n        // ...\r\n    }\r\n\r\n    pub fn print_u64(os: &OutStream, x: u64) -> %isize {\r\n        // ...\r\n    }\r\n\r\n    pub fn print_f64(os: &OutStream, x: f64) -> %isize {\r\n        // ...\r\n    }\r\n\r\n    pub fn print_str(os: &OutStream, str: []const u8) -> %isize {\r\n        // ...\r\n    }\r\n\r\n    pub fn print_byte(os: &OutStream, c: u8) -> %void {\r\n        // ...\r\n    }\r\n\r\n    pub fn flush(os: &OutStream) -> %void {\r\n        // ...\r\n    }\r\n}\r\n\r\npub fn assert(inline arg: expr) {\r\n    if (!@compile_var(\"is_release\")) {\r\n        if (!@eval(arg)) unreachable{};\r\n    }\r\n}\r\n```\r\n\r\n### main.zig\r\n```zig\r\nconst io = @import(\"std\").io;\r\n\r\npub fn main() {\r\n    %%io.stdout.printf(\"string: {}  integer: {}  float: {}\\n\", \"hello\", 3, 5.0);\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/andrewrk/zig/issues/comments/236281773","html_url":"https://github.com/andrewrk/zig/issues/132#issuecomment-236281773","issue_url":"https://api.github.com/repos/andrewrk/zig/issues/132","id":236281773,"user":{"login":"andrewrk","id":106511,"avatar_url":"https://avatars.githubusercontent.com/u/106511?v=3","gravatar_id":"","url":"https://api.github.com/users/andrewrk","html_url":"https://github.com/andrewrk","followers_url":"https://api.github.com/users/andrewrk/followers","following_url":"https://api.github.com/users/andrewrk/following{/other_user}","gists_url":"https://api.github.com/users/andrewrk/gists{/gist_id}","starred_url":"https://api.github.com/users/andrewrk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andrewrk/subscriptions","organizations_url":"https://api.github.com/users/andrewrk/orgs","repos_url":"https://api.github.com/users/andrewrk/repos","events_url":"https://api.github.com/users/andrewrk/events{/privacy}","received_events_url":"https://api.github.com/users/andrewrk/received_events","type":"User","site_admin":false},"created_at":"2016-07-29T20:12:30Z","updated_at":"2016-07-29T20:12:30Z","body":"Superseded by #167"}}
{"actor":{"display_login":"andrewrk"}}