Giter VIP home page Giter VIP logo

Comments (11)

haze avatar haze commented on May 27, 2024 2

here is a curl example

// compile with `zig build-exe zig-curl-test.zig --library curl --library c $(pkg-config --cflags libcurl)`
const std = @import("std");
const cURL = @cImport({
    @cInclude("curl/curl.h");
});

pub fn main() !void {
    var arena_state = std.heap.ArenaAllocator.init(std.heap.c_allocator);
    defer arena_state.deinit();
    var allocator = &arena_state.allocator;

    // global curl init, or fail
    if (cURL.curl_global_init(cURL.CURL_GLOBAL_ALL) != .CURLE_OK)
        return error.CURLGlobalInitFailed;

    // curl easy handle init, or fail
    const handle = cURL.curl_easy_init() orelse return error.CURLHandleInitFailed;
    // defer curl cleanup
    defer {
        cURL.curl_easy_cleanup(handle);
        cURL.curl_global_cleanup();
    }

    var response_buffer = std.ArrayList(u8).init(allocator);
    defer response_buffer.deinit();

    // setup curl options
    if (cURL.curl_easy_setopt(handle, .CURLOPT_URL, "https://ziglang.org") != .CURLE_OK)
        return error.CouldNotSetURL;

    // set write function callbacks
    if (cURL.curl_easy_setopt(handle, .CURLOPT_WRITEFUNCTION, writeToArrayListCallback) != .CURLE_OK)
        return error.CouldNotSetWriteCallback;
    if (cURL.curl_easy_setopt(handle, .CURLOPT_WRITEDATA, &response_buffer) != .CURLE_OK)
        return error.CouldNotSetWriteCallback;

    // perform
    if (cURL.curl_easy_perform(handle) != .CURLE_OK)
        return error.FailedToPerformRequest;

    std.log.info("Got response of {} bytes", .{response_buffer.items.len});
    std.debug.print("{}\n", .{response_buffer.items});
}

fn writeToArrayListCallback(data: *c_void, size: c_uint, nmemb: c_uint, user_data: *c_void) callconv(.C) c_uint {
    var buffer = @intToPtr(*std.ArrayList(u8), @ptrToInt(user_data));
    var typed_data = @intToPtr([*]u8, @ptrToInt(data));
    buffer.appendSlice(typed_data[0 .. nmemb * size]) catch return 0;
    return nmemb * size;
}

from www.ziglang.org.

pfgithub avatar pfgithub commented on May 27, 2024 2

@macarc You need to do memory allocation, like this for example

const std = @import("std");

fn LinkedList(comptime T: type) type {
    return struct {
        data: T,
        next: ?*LinkedList(T),

        pub fn from_list(values: []const T, alloc: *std.mem.Allocator) error{OutOfMemory}!?*LinkedList(T) {
            if (values.len == 0) return null;

            const tail = values[1..];
            const allocated = try alloc.create(LinkedList(T));
            allocated.* = LinkedList(T) {
                .data = values[0],
                .next = try from_list(tail, alloc)
            };
            return allocated;
        }
    };
}

pub fn main() !void {
     var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
     defer arena.deinit();
     const alloc = &arena.allocator;

    // i32 is a type, not a value!
    const i32LinkedList = LinkedList(i32);

    const values: []const i32 = &[_]i32{1,2,3,4};
    const x = try i32LinkedList.from_list(values, alloc);
    var v = x.?;
    while (true) {
        v = v.next orelse break;
        std.debug.print("{}", .{v.data});
    }
}

It's a bit awkward because it uses recursion to set up the linked list and that requires defining an explicit error set

Yours does work at comptime if you switch the pointers in LinkedList to *const pointers

        next: ?*const LinkedList(T),
        pub fn fromList(…) ?*const LinkedList(T) {
…
    const x = comptime i32LinkedList.from_list(values);
    var v = x.?;
    while (true) {
        v = v.next orelse break;
        std.debug.print("{}", .{v.data});
    }

from www.ziglang.org.

kristoff-it avatar kristoff-it commented on May 27, 2024

@pfgithub submitted some code samples and suggested some ideas to explore, link: #78 (comment)

I've added the provided examples to the website (Learn -> Code Examples), you can find them here: http://ziglang.github.io/www.ziglang.org/learn/samples/

@pfgithub I think they look nice, as you can see I've also wired them to the doctest tool, would you mind working on some of the bullet points you mentioned in your comment? :D

I'm copying over the list for convenience:

Other possible snippets that could be useful

  • Arena memory allocation
  • Error handling with try / catch / if and defer / errdefer
  • "Use comptime to write release-aware code" (comptime alternatives to #ifdef)
  • Optionals and if / orelse
  • constructing structs with @Type()
  • basic io like reading from stdin and writing to files
  • exporting a c library
  • std.json
  • packed struct bitfields
  • async/await
  • build system

from www.ziglang.org.

macarc avatar macarc commented on May 27, 2024

I think the front page should have something with comptime in it, since it is quite unique.

e.g.

const std = @import("std");

fn LinkedList(comptime T: type) type {
    return struct {
        data: T,
        next: ?*LinkedList(T),

        pub fn from_list(values: []const T) ?*LinkedList(T) {
            if (values.len == 0) return null;

            const tail = values[1..];
            return &LinkedList(T) {
                .data = values[0],
                .next = from_list(tail)
            };
        }
    };
}

pub fn main() void {
    // i32 is a type, not a value!
    const i32LinkedList = LinkedList(i32);

    const values: []const i32 = &[_]i32{1,2,3,4};
    const x = i32LinkedList.from_list(values);
    std.debug.print("{}", .{x});
}

I'm pretty new to Zig, so forgive me if this is wrong somehow, but this kind of shortish example.

from www.ziglang.org.

pfgithub avatar pfgithub commented on May 27, 2024

An io example

const std = @import("std");

pub fn main() !u8 {
    // an arena allocator only frees memory at the very end when deinit is called.
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const alloc = &arena.allocator;

    const stdout_w = std.io.getStdOut().writer();
    const stdin_r = std.io.getStdIn().reader();

    const args = try std.process.argsAlloc(alloc);
    // defer std.process.argsFree(args) // this is not necessary because the arena will free automatically

    for (args[1..]) |arg| {
        if (std.mem.eql(u8, arg, "--help")) {
            try stdout_w.writeAll(
                \\Usage:
                \\    io [options…]
                \\Options:
                \\    --help: Print this message
            );
            return 0;
        }
        try stdout_w.writeAll("Unknown arg, see --help");
        return 1;
    }

    try stdout_w.writeAll("What is your name? ");
    const name = try stdin_r.readUntilDelimiterAlloc(alloc, '\n', 200);
    // defer alloc.free(name);
    // the last argument is max_bytes. this should be set to a reasonable length, or std.math.maxInt(usize)
    // if you want your program to fill up all the memory when someone gives it a huge file.

    try stdout_w.print("Hi {}! My name is zig!\n", .{name});

    return 0;
}

I also tried to make an async example but it doesn't seem like you can read from stdin write to stdout at the same time which would make for a much better example. Also I don't know how async works so I'm not sure if atomicLoad/atomicStore are needed.

const std = @import("std");

pub const io_mode = .evented; // this variable is read by lib/std/start.zig and sets a variable at comptime to make stdlib functions use async/await

fn reader(num: *i32) !void {
    const stdin = std.io.getStdIn().reader();
    const stdout = std.io.getStdOut().writer();

    while (true) {
        try stdin.skipUntilDelimiterOrEof('\n');
        try stdout.print("{}\n", .{@atomicLoad(i32, num, .Unordered)});
    }
}

fn spin(num: *i32) void {
    while (true) {
        std.time.sleep(1 * std.time.ns_per_s);
        @atomicStore(i32, num, @atomicLoad(i32, num, .Unordered) + 1, .Unordered);
    }
}

pub fn main() !void {
    var num: i32 = 0;
    var reader_frame = async reader(&num);
    var spin_frame = async spin(&num);

    await spin_frame;
    try await reader_frame;
}

from www.ziglang.org.

ityonemo avatar ityonemo commented on May 27, 2024

I realize this is a tall order, but if you can get it below 40-45col, it will look good on most mobile phones.

from www.ziglang.org.

kristoff-it avatar kristoff-it commented on May 27, 2024

Thanks all for helping out with this, especially @pfgithub. By having a few examples to put on the page I was able to reason about other design constraints that I think are important for making the "Code Examples" section clear in intent and useful for users.

More specifically, we have the problem that other code samples are present both in the language reference, and in the "in-depth overview" section. I think we should avoid overlapping with those other sections and, without clear guidelines, it's easy to end up with a "Code Examples" section that ends up being a less complete mix of what's already available.

This consideration hopefully helps us shrink the scope of this section, allowing us to be more effective with our efforts, and also make users perceive "code examples" as something useful in its own right.

My current idea is to make "Code Examples" a small-scale "cookbook", where we put examples of small-ish applications that accomplish something, in a way that you would not find in the language reference. Rust has a full-fledged cookbook which we could take inspiration from, although it should be clear that since we are at a different maturity level, we can only do a very strict subset of what they have there.

It would be nice, eventually, to grow the code examples section to a real cookbook (hosted somewhere else maybe). That said, I don't think we currently need to only add things that would make sense in a cookbook, we mostly should make sure not to overlap with the other sections. As an example, I wouldn't qualify the Fizz Buzz snippet as a proper cookbook recipe, but it's still different enough from that what is present in the docs.

With regards to the examples already contributed, I think all of them fit the general idea of not overlapping with the other two sections, with the exception of the queue example, which is too similar to what's already explained here, in my opinion.

Opinions?

from www.ziglang.org.

kristoff-it avatar kristoff-it commented on May 27, 2024

I realize this is a tall order, but if you can get it below 40-45col, it will look good on most mobile phones.

Yeah that's not easy. I could probably add a bit of JS magic to lower the fontsize a bit in order to fit a few more columns, or we could have two different examples, one for big screens, one for small. The two examples could be entirely different, or the same just with different, hand-crafted formatting.

from www.ziglang.org.

haze avatar haze commented on May 27, 2024

I think the best reference for me has been go by example. It would have some overlap with other areas if we were to implement it for zig (but go also has this issue). The more complex examples on the go by example pages like context, file system stuff, random, signals, etc., are useful. I think we should also consider the fact that @Sobeston's ziglearn has similar examples.

RE: fontsize;
we could probably abuse vertical over horizontal height for mobile viewing, I don't know how you'd display different text based on display size / device, but that's probably the smartest idea

from www.ziglang.org.

pfgithub avatar pfgithub commented on May 27, 2024

Adding this css makes code blocks a bit easier to read on mobile

@media only screen and (max-width:600px) {
  pre {
    max-width: 100vw;
    margin-left: -20px;
    margin-right: -20px;
    overflow-x: scroll;
    -webkit-overflow-scrolling: touch;
    margin-top: -10px;
    margin-bottom: -10px;
  }

  pre > code {
    margin: 10px 20px;
    box-sizing: border-box;
    display: inline-block;
    width: max-content;
    min-width: calc(100% - 40px);
  }

  html {
    overflow-x: hidden;
  }

  body {
    -webkit-text-size-adjust: none;
  }
}

-webkit-text-size-adjust: none is needed to make the code examples not appear huge on iOS Safari, -webkit-overflow-scrolling: touch is needed to have momentum scrolling

Getting column size below 45 seems very difficult, but getting column size below 80 looks achievable for all the examples and that would help on desktop too.

from www.ziglang.org.

Sobeston avatar Sobeston commented on May 27, 2024

For what it's worth, I've tried to keep code under 60 columns for the ziglearn site and it has worked out alright so far. Feel free to copy whatever's on the repo.

from www.ziglang.org.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.