ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.1k stars 2.49k forks source link

[community] Zigsts -- hub for submiting snippets not quite generic enough to be "official examples" #17331

Closed expikr closed 6 months ago

expikr commented 1 year ago

It would be nice to have a centralized searchable hub for sharing stackoverflow-esq gists, but instead of being a response to needy questioners, it's for people who solved a particular hitch in their realworld usages and wanted to immortalize it as a self-contained gist, easy for future references and allowing others to be helped by it as well as receiving suggestions for improvements or remarks on similar scenarios encountered by others.

Looking through the wiki's community learning resources section, they are all oriented towards more holistic and generalize-able learning materials, such as zig-by-example, so they're not quite well suited to the gists-style samples where they may be domain- or API-specific "aha, that's how you use it in Zig" usages that are nevertheless helpful as a part of a searchable collection.

Another advantage of this solver-submitted rather than questioner-initiated format is that the resulting submission is likely guaranteed to be a real-world solution that the submitters themselves find worthy of being emblemed, as opposed to a bare-minimum solution to get answer points that might have misunderstood the question to begin with.

Being a hub for third-party submission also absolves the first party of the burden to guarantee the quality/correctness of the entries like you'd expect of the ziglang.org examples.

Right now Github Gists is pretty much the only such type of environment, however because it's generic to all languages rather than Zig-focused, it's not very easy to search for domain-specific usages restricted to Zig. It's also not ideal to have a vendor lock-in platform for your knowledge repository, especially for one where it would potentially be massively collaborative.

Selfhosting such a hub provides the advantage of having full control as well as affording more specialization in the submissions exclusive to Zig.


This proposal is motivated by me trying to work out how to hand-write Windows GUI messageloop from scratch, initially to submit to ziglang's examples section. The MessageBox example was simple enough, after it was submitted I then wrote a barebones example for window creation, trying to keep it as minimal as possible but still ended up with the following monstrosity:

```zig const std = @import("std"); const win = std.os.windows; const WINAPI = win.WINAPI; pub export fn wWinMain( hInstance: win.HINSTANCE, hPrevInstance: ?win.HINSTANCE, lpCmdLine: ?win.LPWSTR, nCmdShow: win.INT, ) callconv(WINAPI) win.INT { _ = hPrevInstance; _ = lpCmdLine; const _wch = std.unicode.utf8ToUtf16LeStringLiteral; var wc = WNDCLASSEXW{ .lpfnWndProc = WindowProc, .hInstance = hInstance, .lpszClassName = _wch("Test Window Class"), }; _ = RegisterClassExW(&wc); const hwnd = CreateWindowExW( 0, wc.lpszClassName, _wch("Test Window"), 0x00080000, // WS_SYSMENU 0, 0, 640, 480, null, null, hInstance, null, ); if (hwnd) |window| { _ = ShowWindow(window, nCmdShow); var msg : MSG = undefined; while(true) { switch(GetMessageW(&msg,null,0,0)) { 0 => break, -1 => break, else => { _ = DispatchMessageW(&msg); } } } } return 0; } pub export fn WindowProc( hwnd: win.HWND, uMsg: win.UINT, wParam: win.WPARAM, lParam: win.LPARAM, ) callconv(WINAPI) win.LRESULT { const pos = GetMessagePos(); const time = GetMessageTime(); const info = GetMessageExtraInfo(); const debug_data = .{ @intFromPtr(hwnd), uMsg, wParam, @as(usize,@bitCast(lParam)), info, time, pos.x, pos.y }; const debug_str = if (8==@sizeOf(usize)) "H=0x{X}, M=0x{X:0>4}, W=0x{X:0>16}, L=0x{X:0>16}, I=0x{X:0>16}, T={}, X={}, Y={}" else "H=0x{X}, M=0x{X:0>4}, W=0x{X:0>8 }, L=0x{X:0>8 }, I=0x{X:0>8 }, T={}, X={}, Y={}"; std.log.debug(debug_str, debug_data); switch(uMsg) { 0x0002 => { // WM_DESTROY _ = PostQuitMessage(0); }, 0x0010 => { // WM_CLOSE _ = DestroyWindow(hwnd); }, else => {}, } return DefWindowProcW(hwnd, uMsg, wParam, lParam); } extern "user32" fn GetMessagePos() callconv(WINAPI) extern struct {x:i16, y:i16}; extern "user32" fn GetMessageTime() callconv(WINAPI) u32; extern "user32" fn GetMessageExtraInfo() callconv(WINAPI) usize; extern "user32" fn GetMessageW(*MSG, ?win.HWND, win.UINT, win.UINT) callconv(WINAPI) win.BOOL; extern "user32" fn DispatchMessageW(*const MSG) callconv(WINAPI) win.LRESULT; extern "user32" fn PostQuitMessage(i32) callconv(WINAPI) void; extern "user32" fn RegisterClassExW(*const WNDCLASSEXW) callconv(WINAPI) win.ATOM; extern "user32" fn CreateWindowExW(win.DWORD, [*:0]const u16, [*:0]const u16, win.DWORD, i32, i32, i32, i32, ?win.HWND, ?win.HMENU, win.HINSTANCE, ?win.LPVOID) callconv(WINAPI) ?win.HWND; extern "user32" fn ShowWindow(win.HWND, i32) callconv(WINAPI) win.BOOL; extern "user32" fn DestroyWindow(win.HWND) callconv(WINAPI) win.BOOL; extern "user32" fn DefWindowProcW(win.HWND, win.UINT, win.WPARAM, win.LPARAM) callconv(WINAPI) win.LRESULT; const WNDCLASSEXW = extern struct { cbSize: win.UINT = @sizeOf(WNDCLASSEXW), style: win.UINT = 0, lpfnWndProc: *const fn (hwnd: win.HWND, uMsg: win.UINT, wParam: win.WPARAM, lParam: win.LPARAM) callconv(WINAPI) win.LRESULT, cbClsExtra: i32 = 0, cbWndExtra: i32 = 0, hInstance: win.HINSTANCE, hIcon: ?win.HICON = null, hCursor: ?win.HCURSOR = null, hbrBackground: ?win.HBRUSH = null, lpszMenuName: ?[*:0]const u16 = null, lpszClassName: [*:0]const u16, hIconSm: ?win.HICON = null, }; const MSG = extern struct { hWnd: ?win.HWND, message: win.UINT, wParam: win.WPARAM, lParam: win.LPARAM, time: win.DWORD, pt: win.POINT, lPrivate: win.DWORD }; ```

As @kristoff-it said, the messagebox example was small enough that it being platform-specific is not a problem. This windowing example is obviously too long, but it still contained enough fundamental sample usages that it's worth being referable somewhere.

Especially for a new programming language, textbooks are constrained by needing to illustrate as many concepts in as few examples as possible, so it cannot afford having many examples illustrating the same concept repeatedly. Having a volume of concrete real-world usages (that aren't quite full-blown repositories that you have to wade through in its entirety) to illustrate the same concept goes a long way in making the learning curve much, much more approachable.

BratishkaErik commented 1 year ago

IMHO this issue should be moved to https://github.com/ziglang/www.ziglang.org/issues (unless you want some kind of internal support like zig gist upload? But in this case (I guess) internal support part will be rejected)

nektro commented 6 months ago

this idea would be better imo as a community effort

expikr commented 6 months ago

If https://zigbin.io can have a discovery directory then it essentially solves this need in its entirety.