[00:00.000 --> 00:10.000] People here are organizing the deaf room, particularly Manolis who has done a lot of [00:10.000 --> 00:20.000] the work before we organized this room. [00:20.000 --> 00:23.000] Anyway, I'm going to talk a little bit about Guy and Zig. [00:23.000 --> 00:26.000] So I prepared two talks. [00:26.000 --> 00:29.000] One talk you can download online. [00:29.000 --> 00:36.000] There was kind of an overview of why I made these choices and why we're doing this. [00:36.000 --> 00:45.000] But I think it's better just to hit the command line or a shell. [00:45.000 --> 00:48.000] Right, so many people will recognize this Emacs. [00:48.000 --> 00:53.000] The letters fall off on the side, it shouldn't matter too much. [00:53.000 --> 01:05.000] And then I'm going to run in a shell. [01:05.000 --> 01:09.000] So I don't know if everyone is aware, but the gig shell is a proper container. [01:09.000 --> 01:15.000] So only the tools are pulled in that we define. [01:15.000 --> 01:30.000] And this is done in the gig.scheme file. [01:30.000 --> 01:34.000] In the gig.scheme file we define the dependency we want. [01:34.000 --> 01:37.000] Right, so Guy is there and Zig is there. [01:37.000 --> 01:44.000] So in the file we find Zig version. [01:44.000 --> 01:49.000] In the container, right, and then Guy minus V is also there. [01:49.000 --> 01:51.000] But Vi, for example, is not. [01:51.000 --> 02:04.000] And if this was properly running on Debian, it would be visible. [02:04.000 --> 02:09.000] So what I'm going to do is I'm going to run Zig to build my library. [02:09.000 --> 02:13.000] It's a dynamic library. [02:13.000 --> 02:23.000] And then I use package config to pick up the Guile compile switches. [02:23.000 --> 02:31.000] And I'm going to compile it against a little C file. [02:31.000 --> 02:35.000] Uh-oh. [02:35.000 --> 02:45.000] Yeah. [02:45.000 --> 02:52.000] Right, yeah, I missed the second line, I see, yeah. [02:52.000 --> 02:57.000] Right. [02:57.000 --> 03:03.000] So Guile is almost designed for linking against C. [03:03.000 --> 03:09.000] Right, so I wrote a little C program to show you that. [03:09.000 --> 03:13.000] And it can, it calls Guile functions. [03:13.000 --> 03:15.000] So scheme from int is a Guile function. [03:15.000 --> 03:21.000] So it switches, it turns test into a Guile integer, essentially. [03:21.000 --> 03:25.000] And then a boolean, and then I call this function here in C. [03:25.000 --> 03:27.000] Right, my increment in function. [03:27.000 --> 03:31.000] And you can see that it uses Guile objects to pass into the function. [03:31.000 --> 03:33.000] And there's also a Guile object returned. [03:33.000 --> 03:35.000] Right. [03:35.000 --> 03:37.000] So it's very minimalistic code. [03:37.000 --> 03:49.000] And I just need to get a compile it. [03:49.000 --> 03:54.000] Now it did compile, but now it doesn't find the library. [03:54.000 --> 03:56.000] So I need to add the library path. [03:56.000 --> 03:59.000] So I'm just doing this raw so you can see what is happening. [03:59.000 --> 04:04.000] You know, I mean, if you had a proper build script, you can account for all this. [04:04.000 --> 04:07.000] But you can see it says hello world from 3 to 4. [04:07.000 --> 04:13.000] Right, so that's what the C function does. [04:13.000 --> 04:15.000] Now I want to do the same thing in Zig. [04:15.000 --> 04:21.000] Right, so I created, actually what I want to do is I want to call Zig from, [04:21.000 --> 04:24.000] you know, the same library that I'm using. [04:24.000 --> 04:32.000] I want to call this from Guile. Right. [04:32.000 --> 04:38.000] So let's try that. [04:38.000 --> 04:51.000] So I'm in Guile now and I added the local search path for the library. Right. [04:51.000 --> 04:56.000] Yeah, so here we load the shared library libmy.so. [04:56.000 --> 04:59.000] Right, it loads into Guile. [04:59.000 --> 05:07.000] And I want to try something like, [05:07.000 --> 05:10.000] and it says it doesn't find the procedure because I haven't defined it. [05:10.000 --> 05:18.000] Yeah, so that doesn't work very well. [05:18.000 --> 05:47.000] Let me see where we are. [05:47.000 --> 05:52.000] Yeah, so call it ping Zig with an underscore. [05:52.000 --> 05:56.000] All right, that's not very Guile-like, is it? [05:56.000 --> 06:02.000] Yeah, so that's some conventions and I already ignored it. [06:02.000 --> 06:08.000] Yeah, so Guile has a wide range of C functions in the library. [06:08.000 --> 06:10.000] And these can be called. [06:10.000 --> 06:21.000] You know, so if you look for the C function, which one did we use before? [06:21.000 --> 06:27.000] Yeah, or a scheme from int you can see here, right? [06:27.000 --> 06:42.000] Scheme from int. And so in the Guile reference manual, [06:42.000 --> 06:50.000] you see in the reference manual almost on every page you see the sort of the C functions that you could also call as list functions. [06:50.000 --> 06:53.000] You know, and the scheme from int should be there. [06:53.000 --> 06:57.000] It's a long list, but that's the idea. So when you actually use the Guile manual, [06:57.000 --> 07:04.000] you will see the C interface to the CABI. [07:04.000 --> 07:10.000] Now the interesting thing about Zig is that it faithfully, you know, uses the CABI. [07:10.000 --> 07:19.000] So, you know, anything you can, you define in Zig, you can essentially access from Guile. [07:19.000 --> 07:26.000] So let's look at my Zig file and I say ping. [07:26.000 --> 07:33.000] Yeah, so this is the equivalent C function, sorry, ZigVinc function that we had defined in C earlier. [07:33.000 --> 07:39.000] Yeah, you have a ping Zig. It takes a scheme object as an input and it returns a scheme object, right? [07:39.000 --> 07:43.000] And it just pings it back. [07:43.000 --> 07:47.000] So how can I see the scheme object as it is defined now? [07:47.000 --> 07:59.000] And as a matter of fact, Zig can export, sorry, can import C include files. [07:59.000 --> 08:11.000] Yeah, it's actually one command. [08:11.000 --> 08:18.000] Yeah, so you say Zig translate C, right, then the path to the include file, then include file itself, [08:18.000 --> 08:22.000] and it turns into a proper Zig file. [08:22.000 --> 08:25.000] And this Zig file you can just import and it will work. [08:25.000 --> 08:33.000] Yeah, so all the functions that are defined by Guile that are exported that you could use from C in principle [08:33.000 --> 08:38.000] are now available in Zig, including the objects. [08:38.000 --> 08:44.000] Yes, if you look at this Zig file, it doesn't look very nice, right? [08:44.000 --> 08:47.000] But it's all there and it actually just worked in one go. [08:47.000 --> 08:54.000] I had to delete one line in it. [08:54.000 --> 09:00.000] All right, so yeah, the other thing of course is that I'm using ping Zig1 right now. [09:00.000 --> 09:07.000] Okay, so let's try hello. [09:07.000 --> 09:09.000] And it pings back hello, right? [09:09.000 --> 09:12.000] I mean that's what we see in the Zig function here. [09:12.000 --> 09:17.000] And Guile is not a strictly typed language. [09:17.000 --> 09:24.000] Yeah, I mean it's typed, but it's not in the sense that here we have a variable that you can, you know, [09:24.000 --> 09:28.000] in the one case I'm using an integer, in the next case I'm using a string. [09:28.000 --> 09:35.000] Yeah, and this makes for, apart from the fact that I'm using a rappel where I'm actually talking to the, you know, to the Zig backend, [09:35.000 --> 09:45.000] it also gives me a lot of flexibility in what, you know, how I define these functions and these variables that get passed. [09:45.000 --> 09:57.000] Okay, so let's do something a little bit more complex. [09:57.000 --> 10:05.000] And, you know, this exploration that I had with Zig and C and Guile, it's also all online, you can just read it. [10:05.000 --> 10:13.000] It's in a GitLab repository. [10:13.000 --> 10:24.000] Yeah, so if you define a function in Zig, you know, just naively like ping Zig here, it won't be immediately visible to Guile. [10:24.000 --> 10:27.000] So you need to create a mapping for that. [10:27.000 --> 10:31.000] Yeah, and this is in the Guile documentation, it's exactly the same thing in C. [10:31.000 --> 10:33.000] See if I can find it, yeah, here it is. [10:33.000 --> 10:40.000] So when you initialize the module, which means when you load the shared library, right, it will call this function, [10:40.000 --> 10:47.000] and you will define a sub, sorry, it will, yeah, define the function call here. [10:47.000 --> 10:52.000] So in Zig here is ping Zig, right, ping Zig and it has one argument. [10:52.000 --> 10:58.000] You need to do that to make the symbol visible to the Guile interpreter. [10:58.000 --> 11:00.000] That's basically what you have to do. [11:00.000 --> 11:10.000] There's nothing more to it, which is kind of boring, you know. [11:10.000 --> 11:16.000] So yeah, I'm also opinion that, you know, that we need multiple programming languages. [11:16.000 --> 11:22.000] Yeah, there's the, when you talk about Zig, there's often, or even C++, you know, there's often the elephant in the room. [11:22.000 --> 11:24.000] I'm not going to name it. [11:24.000 --> 11:31.000] But this is a language that tries to be everything, you know, and you end up with a very complex language. [11:31.000 --> 11:34.000] Also, the compiler is dog slow. [11:34.000 --> 11:40.000] I don't know if anyone is using the unnamed language. [11:40.000 --> 11:48.000] And then it has, you know, it has a borough checker, which acts like, you know, a nagging wife, you know, it keeps talking to you. [11:48.000 --> 11:53.000] And I tried it, you know, and I tried to love it because it's a functional language, you know, it's a functional programming language. [11:53.000 --> 11:59.000] But it kept talking to me and it kept going me out of my flow, you know, I just couldn't keep moving. [11:59.000 --> 12:09.000] So I think, you know, it's probably wiser to have a language like C, which is, you know, you have to realize that most of the code in the world today is written in C++, C++ still. [12:09.000 --> 12:21.000] If you want a type of performance, you will end up with a strictly typed language, which is, you know, imperative to some degree because CPUs are imperative, right? [12:21.000 --> 12:25.000] We don't have, at this point, we don't really have functional programming CPUs. [12:25.000 --> 12:30.000] So to optimize that stuff, you end up, you know, with a type of language that has to cater for that. [12:30.000 --> 12:38.000] But nobody loves programming in C++, you know, and in C programming is also hard, you know, to shoot yourself in the food language. [12:38.000 --> 12:40.000] I call it. [12:40.000 --> 12:49.000] So it's nice if you can have a language that has some somewhat stronger guarantees, but it's still blazingly fast and still, you know, kind of imperative. [12:49.000 --> 12:55.000] And then have something like Gile, which actually allows you to be, you know, productive, right? [12:55.000 --> 12:57.000] And do functional programming when you want to. [12:57.000 --> 12:59.000] So you end up with this type of mixture. [12:59.000 --> 13:03.000] Have we got five minutes? [13:03.000 --> 13:04.000] Five minutes. [13:04.000 --> 13:06.000] Five minutes to two questions. [13:06.000 --> 13:16.000] Okay, so one thing, one additional thing I would like to show you. [13:16.000 --> 13:22.000] Sorry, that's mine. [13:22.000 --> 13:35.000] Yeah, so you can, I mean, using the Gile libraries, you can essentially build up lists, you know, which is the fundamental for many list-like programming efforts. [13:35.000 --> 13:41.000] But, you know, when you talk about performance, you'd like to deal with arrays of data. [13:41.000 --> 13:52.000] So it continues blocks of memory where you have integers in a row or doubles in a row, and you're able to address these integers and doubles. [13:52.000 --> 14:02.000] Of course, you can do that from Gile, but, you know, if you want to do, if you write high-performance code like we do, you want to be able to, you know, use it as a vector in ZIG. [14:02.000 --> 14:11.000] Yeah, so you have an index, the base pointer to the vector, and then you have an index, and you should be able to fetch out the data object that you want. [14:11.000 --> 14:16.000] So just write a little example here. [14:16.000 --> 14:17.000] So this is the list example. [14:17.000 --> 14:25.000] Let me see if I can, the vector array. [14:25.000 --> 14:31.000] Yeah, so you have, I wrote a little, let me move that down. [14:31.000 --> 14:41.000] A little ZIG function, which has my increment in floating point 64 bits vector ZIG, you know, I'm very good at naming, apparently. [14:41.000 --> 14:46.000] You pass in a Gile vector, which is, again, a scheme object. [14:46.000 --> 14:50.000] It returns a scheme object, which is, again, a vector, right? [14:50.000 --> 14:57.000] And then it calls this Gile function, scheme f64, oh, that's where the naming came from. [14:57.000 --> 15:09.000] It came from Gile, yes, so I set X, you know, so I set, I'm set in the vector, I set at position one, right? [15:09.000 --> 15:13.000] So index one, I set the value 3.7. [15:13.000 --> 15:22.000] So this is kind of happening in Gile-ish C code, so it's calling essentially Gile C functions. [15:22.000 --> 15:31.000] Yeah, and I prove that it works, you can look it up. [15:31.000 --> 15:37.000] But here, here I'm using a proper index, I think, let me see, yeah. [15:37.000 --> 15:42.000] So you increment the f64 vector, right? [15:42.000 --> 15:44.000] This is the old version. [15:44.000 --> 15:49.000] Here I get a handle on the array. [15:49.000 --> 15:54.000] And then I get the data, so I get a vector here. [15:54.000 --> 15:59.000] If our data is a vector, yeah, of the elements of the vector array, right? [15:59.000 --> 16:10.000] And then I index the data points based on the vector, you know, of the floating points, and show 0, 1, and number 2. [16:10.000 --> 16:18.000] Yeah, and that's what it shows, so I'm not going to do that live, but that's the idea. [16:18.000 --> 16:22.000] Yeah, I'm done. [16:22.000 --> 16:30.000] Yeah, so it's in a nutshell, the code and the slides are online, so you can have a look, have a go. [16:30.000 --> 16:32.000] Any questions? [16:32.000 --> 16:53.000] Yes. [16:53.000 --> 16:57.000] I tried quite long actually, so I read five books. [16:57.000 --> 17:05.000] I probably took two months and wrote a thousand lines of code or so to decide it wasn't for me. [17:05.000 --> 17:10.000] But yeah, I hear quite a few stories like this, which are very similar. [17:10.000 --> 17:15.000] I think, you know, it's a language for masochists. [17:15.000 --> 17:17.000] A language for masochists. [17:17.000 --> 17:19.000] You have to be a brilliant person, right? [17:19.000 --> 17:21.000] Well, a brilliant masochist, let's put it that way. [17:21.000 --> 17:25.000] You have to be brilliant to keep that all in your head. [17:25.000 --> 17:30.000] Yeah, so see. [17:30.000 --> 17:41.000] Yeah, you know, I'm not complaining about it because people who program in Rust, they do better than in C++. [17:41.000 --> 17:45.000] So the compiler does help a lot, and I think it does lead to better code. [17:45.000 --> 17:54.000] I've given students, you know, work in Rust, and they do write better code because the compiler actually helps you. [17:54.000 --> 18:00.000] All right, but it also takes them a long time to get something done. [18:00.000 --> 18:02.000] So it depends on what your goals are, right? [18:02.000 --> 18:09.000] I mean, if you have to write, you know, perfect software to launch your rocket, you might, you know, want to do it that way. [18:09.000 --> 18:14.000] But if it's just like me, you know, in my job, we write mostly throw away code. [18:14.000 --> 18:19.000] It doesn't pay. [18:19.000 --> 18:23.000] Bioinformatics, so I'm in science. [18:23.000 --> 18:26.000] We have long-lived code, but it's usually by accident, right? [18:26.000 --> 18:34.000] So you write something, and people start using it, and then 10 years later, it becomes mainstream. [18:34.000 --> 18:37.000] It's actually happened to one of our projects, yeah. [18:37.000 --> 18:39.000] It's kind of, yeah. [18:39.000 --> 18:43.000] And then, you know, then it's too late to do better. [18:43.000 --> 18:53.000] So at one point, you showed us how to convert the ZIG file to C, right? [18:53.000 --> 19:02.000] But it wasn't really necessary in order to, or it wasn't necessary in order to call the style stuff from within ZIG? [19:02.000 --> 19:06.000] No, I mean, it's, the guy that adheres to the C ABI, right? [19:06.000 --> 19:09.000] So it has a C calling interface. [19:09.000 --> 19:13.000] You can use the scheme object, yeah, so that came from there. [19:13.000 --> 19:16.000] But actually, the scheme object is really simple when you look at it. [19:16.000 --> 19:21.000] So it could be that, you know, just, you can just roll your own. [19:21.000 --> 19:23.000] Yeah? [19:23.000 --> 19:27.000] So you create the language for scratch. [19:27.000 --> 19:32.000] So why did you decide to use the semicolons and curly braces in it? [19:32.000 --> 19:33.000] Well, I didn't design ZIG. [19:33.000 --> 19:35.000] I should have been clearer. [19:35.000 --> 19:41.000] Nor have I any input on guile, unlike other people here. [19:41.000 --> 19:47.000] But, yeah, you know, I dabble in languages. [19:47.000 --> 19:52.000] You know, I use, people often ask me, what is the language of the year? [19:52.000 --> 19:55.000] I think at that point it was Scala. [19:55.000 --> 19:57.000] I'm embarrassed to say. [19:57.000 --> 20:03.000] But, no, I think, you know, ZIG does appeal to me. [20:03.000 --> 20:05.000] Yeah? [20:05.000 --> 20:10.000] The second question is, so if I'm running, if I want to make a formal program, [20:10.000 --> 20:19.000] and I do them in Fortran or Julia, why would they use it? [20:19.000 --> 20:22.000] So Fortran is, you know, it's a bit difficult, [20:22.000 --> 20:26.000] because the very different language is Fortran and Julia. [20:26.000 --> 20:30.000] But I think, you know, ZIG tries to be in the space of C. [20:30.000 --> 20:32.000] Yeah. [20:32.000 --> 20:38.000] It's a general purpose systems programming and uncompromising speed. [20:38.000 --> 20:40.000] And it is fast. [20:40.000 --> 20:47.000] Yes, the compiler itself compiles itself in 10 minutes about on a standard machine. [20:47.000 --> 20:52.000] But I think, for example, it doesn't have exception handling. [20:52.000 --> 20:57.000] Yeah, it uses a different approach, which is more like a maybe monad. [20:57.000 --> 21:02.000] You know, and even C++, typically you'll have exception handling, [21:02.000 --> 21:05.000] which, you know, every time you call a function, it has to carry state with it [21:05.000 --> 21:07.000] to be able to unroll the stack. [21:07.000 --> 21:09.000] And this causes overheads. [21:09.000 --> 21:11.000] That's one thing. [21:11.000 --> 21:14.000] Now, with C++, the other thing is that in the background, [21:14.000 --> 21:17.000] there's often a lot of memory allocation going on. [21:17.000 --> 21:21.000] Yeah, especially when, I mean, it's kind of unavoidable to use the SEL these days. [21:21.000 --> 21:23.000] That's best practice. [21:23.000 --> 21:27.000] And I find that in ZIG, because it's closer to the C philosophy, [21:27.000 --> 21:29.000] it's actually much faster. [21:29.000 --> 21:31.000] Yeah, so. [21:31.000 --> 21:33.000] Oh, hey. [21:33.000 --> 21:39.000] Are you planning to write like a tutorial in the guide manual for how to do this? [21:39.000 --> 21:40.000] Yeah, we should. [21:40.000 --> 21:41.000] Yeah, we should. [21:41.000 --> 21:43.000] I think the next speaker needs to go on. [21:43.000 --> 21:44.000] No? [21:44.000 --> 21:46.000] How much time do we have? [21:46.000 --> 21:48.000] Two minutes, one and a half. [21:48.000 --> 21:49.000] Yeah, you can. [21:49.000 --> 21:51.000] It's good to switch. [21:51.000 --> 21:53.000] Thank you. [21:53.000 --> 21:55.000] Thank you. [21:55.000 --> 21:57.000] Thank you. [21:57.000 --> 22:22.000] I'll switch on.