<cky>mark_weaver: Congrats on your "new" project maintainership! (Sorry, you weren't on IRC around the time of the announcement, so I'll just congratulate you now. :-D) <cky>I haven't been hacking on Guile for a while. I wonder how the "rewrite all the define-macro macros to use syntax-{rules,case}" project is going. <mark_weaver>I've been totally swamped with a housing move for the last couple of months, so haven't been able to do much. <cky>*nods* Hopefully that's all done and dusted now. :-) <cky>and you have a new shiny place to live in. <mark_weaver>yes, that's done now, thankfully, and there's a huge backlog of stuff I need to deal with, starting with upgrading a relocating my server, and then take a look at my guile todo list. <cky>Relocating your server? You run your server at home, or did you move out of the Boston area or something? <cky>(Many years ago, I used to run a server out of my home Internet connection, but I've gotten lazy in my old age, and I just run a VPS on Linode. :-)) <mark_weaver>no, I had my server located somewhere else, but the people who ran that rack decided to virtualize all of their servers and go back to residental internet service :-( <mark_weaver>whereas I seem to be rare in feeling strongly about running on my own physical hardware. <mark_weaver>I don't like the idea of a few companies having root access to almost all the servers in the world. <cky>I wish I have exciting software projects to work on, but I've been busy with real life much of these days. <mark_weaver>well, that's a common problem. it has been my situation for the last few months as well... <cky>The last exciting bit of Scheme code I've been working on was a pure-Scheme SHA-2 implementation, thanks to some dude requesting for such a thing on Stack Overflow. <mark_weaver>hmm, I wonder if weinholt's industria library has that yet. <cky>I dunno, but one of my design criteria was avoiding embedding giant tables of constants, and instead working them out from first principles. <mark_weaver>it's few enough primes that you could replace it with an elegant (slow) prime number generator. <cky>Yes, that would be nice. <cky>I once wrote a Sieve of Eratosthenes implementation in Racket using its for, and it should be easy to port to SRFI 42 comprehensions. <cky>But I guess you had something even simpler in mind. <mark_weaver>hmm, I don't understand what you're doing with your 'sqrt' and 'cbrt' procedures <cky>The SHA-2 constants are 64-bit quantities, so we require more precision than double-precision. <cky>So we generate an approximate first guess, then use Newton-Raphson to buff up the precision. <mark_weaver>it would be better to avoid inexact arithmetic altogether <mark_weaver>but that's a small nit, and doesn't change the fact that this looks like a nice piece of code :) <cky>I wish I know how to avoid inexact when generating the constants. Advice welcome. :-) <cky>Like, is there a way to do the equivalent of (expt x 1/3) while staying exact? <mark_weaver>you can use newton raphson to do the entire computation <cky>True, I could do that. I remember reading that it would take 4 iterations in that case, but sure. <mark_weaver>well, it's only used to initialize the tables, right? so a few more iterations shouldn't really matter. <cky>Thanks for the suggestion! I'll let you know when I push the change. :-) <mark_weaver>also: can the sha1-init be computed from first principles? <cky>Is there a nice way to describe it? That's what I wonder. The first number is #x01234567 byte-swapped, for example. <cky>the second number is #x89abcdef byte-swapped, etc. <cky>The third one is #x89abcdef with the nybbles in each byte swapped. <cky>the fourth is #x01234567 with nybbles in each byte swapped <cky>And thanks for your tips. :-D <cky>Sure, it was fun. :-D *nalaginrut thought the brand new source-info stores src in .go <taylanub>nalaginrut: IIRC there were *plans* to store source in ELF but I don't remember hearing it's been implemented yet <nalaginrut>taylanub: I saw there's a new branch wip-source-info just now ***wleslie_ is now known as wleslie
<moben>Do guile's .go files contain some kind of timestamp? <taylanub>moben: maybe you could use the file creation time? <moben>maybe I should clarify: I'm doing some distribution work towards reproducible builds and noticed that if I do two guile builds, the .go files differ <TheBrayn>how exactly is a SCM defined? I can find this line in tags.h: typedef union SCM { struct { scm_t_bits n; } n; } SCM; but what is scm_t_bits? <moben>my first thought was that there might be timestamps in there, like with pythons .pyc files, but the differences are to big <monumental_deuce>you wouldn't happen to know a way to tell guile to autocompile a shell script without running it would you <taylanub>I assume with "shell script" you mean "unix shebang script" (or whatever to call it, certainly not shell though) <lloda>There's 'guild compile', but I haven't used it. <taylanub>'guild compile' seems to do the right thing <monumental_deuce>What makes guild different from guile and why does it need a seperate executable? <taylanub>guile runs guile, guild is a set of tools around guile <monumental_deuce>It stands to reason that if guild can tell guile to compile, there must be a way to tell guile directly. <taylanub>yeah, probably some code snippet you don't want to type in every time <monumental_deuce>Also, what stops languages like python from being compiled languages if Scheme has always been. Surely the python runtime doesn't add extra things which make that difficult, hell, common lisp is typically compiled with its bizarre things like (set (intern "symbol") 4) <taylanub>they don't aim to be very fast, they're "scripting" languages <monumental_deuce>And why they choose to not expose it via guile --help, it seems like a useful thing. <taylanub>though things get a bit different once the language grows popular so people go and make things like PyPy <monumental_deuce>Yeah, but it stands to reason that if you don't aim to be compiled you should add stuff to your runtime to justify that. <taylanub>monumental_deuce: file a bug report that guile --help should point at guild :) <taylanub>that's what I was saying, if you want you can file a bug report for guile --help to point at guild <taylanub>I don't know much about PyPy, Wikipedia says it's an interpreter and a JIT <monumental_deuce>A JIT compiler often still relies on an extensive runtime that needs to interpret some fairly high level structure though. <monumental_deuce>Then again, this whole distincition is fairly vague, youc an argue that a language runtime is an interpreter which interprets some lower level variant of that language. <taylanub>monumental_deuce: BTW the compilation related things are in the module (system base compile), but I don't know if that's also the module that auto-compiles and writes things to the cache directory. you can also read the source code of guild if you're interested <monumental_deuce>I suppose, reading the source requires a lot of interest though to find out how it works. <taylanub>the VM and many procedures are, dunno what the ratio of C/Scheme code is on the meanwhile <monumental_deuce>Reading a lot of the documentation seems to imply that many basic functions are basically calls to C functions. <monumental_deuce>I like how GHC goes so far to even make the most fundamnetal constrol structures library and receive no special treatement from the compiler and still be fairly fast. <ijp>I wouldn't say guile is mostly C <ijp>what are you trying to read? <ijp>which is in (system base compile) I think <ijp>the script is in module/scripts/compile.scm <monumental_deuce>reading that article the info I read about the internals of the guile runtime is quite outdated. <monumental_deuce>Does it still do the thing where it needs to copy the entire stack for continuations? <ijp>for a full continuation, I believe so <monumental_deuce>I never really got what the justification was for not using CPS. Everyone seems to be pretty vague about the disadvantages. <ijp>if you do that, you can't capture any of the C parts <monumental_deuce>Over at #racket I've gotten the weirdest and most confusing explanation of not using CPS that I still don't get. <ijp>and being able to use guile from C is a very important use case <taylanub>stack frames of C functions, monumental_deuce <ijp>no, it's an integrating with C code problem <taylanub>BTW what's meant with CPS here? master branch does use a CPS IL <ijp>monumental_deuce: that is also not true anymore <monumental_deuce>What's the latest guile version anyway, this thing says I'm on 2.0.9 which seems fairly outdated <ijp>2.0.11 is the last official release I think <taylanub>.9 is fairly recent, latest is .11, and .10 was a fail-release that was immediately followed by .11 <taylanub>I think it actually uses 2.1 currently, to indicate it's unstable and will lead to the stable 2.2 release <taylanub>i.e. odd minor numbers are unstable, even minor numbers are stable. (the numbers are <major>.<minor>.<micro>, at least in the terminology I'm familiar with) <monumental_deuce>Meaningful version numbers don't sell. You should always update major numbers rapidly. <ijp>yeah, that works great for firefox <monumental_deuce>I think I left firefox for chromium at 5, I came back 1 year later and saw them at 35 or something <ijp>I'm on aurora (33), so I think that means the current release is 31 <ijp>they change it every 6 or 8 weeks *taylanub is guilty of abusing numbers the other way around; overhauling APIs between minor releases .. but it was just a silly pet project whose versions 1.0 through 1.2 should just have been 0.x <ijp>monumental_deuce: I don't see how <monumental_deuce>Well, guile itself has the problem that two versions of the same library can't co-exist in the load path, r6rs gives you this fancy versioning syntax and then you can't use it. Never got that. <ijp>taylanub: it's basically firefox 12 weeks ahead <taylanub>oh never mind I confused it with some other browser that isn't FF at all <ijp>I do it mostly so that mozilla can collect usage information <monumental_deuce>I will say though, we kicked your butt for third place, and the WC before we also beat you. So suck iiiiiit. <lloda>(sxml->xml '(hello 1 2 3 4)) gives <hello>1234</hello>, how do I separate the 1 2 3 4 in the output? <davexunit>otherwise you'll need additional html nodes around the numbers. <ijp>there is no option for it, but you can do some other processing to add in spaces <ijp>lloda: can you give a bit more info? Is the hello tag always going to use a list of numbers, or is this a one off? <ijp>davexunit: the problem isn't the type, it's that sxml->xml adds no extra unnecessary spacing <davexunit>yes, I realize that, but didn't make it clear. <ijp>if you are always wanting a spaced list for a given tag, it's easy enough to write a rewrite rule for pre-post-order <lloda>Thank you both. I thought at first that a string would come out as "string". I'll just use (format ...) for the number list. <ijp>"string" does come out as "string" <ijp>but "string" "string2" comes out as "stringstring2" <lloda>scheme@(guile-user)> (sxml->xml `(hello "s")) <lloda><hello>s</hello>scheme@(guile-user)> <ijp>oh, you mean with quotation marks? <ijp>that would be inconvenient in the common case <dsmith-work>monumental_deuce: Guile was just a C library at first. Now that guile has/is a compler (and a better compiler in 2.2), more and more stuff is implemented in Scheme instead of C. <monumental_deuce>dsmith-work, what I want to know though, I cloned 2.2 from git but there/ s no ./configure <dsmith-work>monumental_deuce: Note that current master is failing a test. <dsmith-work>I dont't remmeber at the moemnt. coverage.test iirc. <dsmith-work>Both 2.0 and 2.1 compile to a virtual machine. But 2.0 is a stack machine (I think) while 2.1 is a register machine. <dsmith-work>monumental_deuce: And I am way over my head here. wingo is the master. <ArneBab>dsmith-work: just as confirmation: sneek is written in guile scheme, right? <ArneBab>monumental_deuce: and there is work going on towarks native compilation <ijp`>monumental_deuce: you can, but only if you also disable all the other warnings... <ijp`>which is less than ideal <mark_weaver>moben: I don't know about timestamps, but the hard problem is that the macro expander introduces gensyms. <ijp`>and fixing the warnings is a very unsexy task <ArneBab>monumental_deuce: that’s something common to many free software projects - just ask the folks at #freenet about rough edges ☺ <moben>mark_weaver: and I take it those aren't deterministic. <mark_weaver>moben: that's correct. they include a per-session random number. <mark_weaver>I'm aware of the importance of deterministic builds, and have given some thought of how to solve this problem, but it's a thorny one. <ArneBab>mark_weaver: would it be possible to give it a seed? <ijp`>is that random number settable? surely guix must do that <mark_weaver>guix doesn't do it yet, but we'll have to solve that problem at some point. <dsmith-work>ArneBab: sneek is bobot++ with guile extension. Mostly a poor quality port of the old sarahbot that was on #scheme. <mark_weaver>but the thorny problem is that somehow, we must ensure that the marks included in every macro-generated identifier are unique, even if they were compiled in different sessions. <dje>re: generated identifiers and deterministic builds: how about provide an option to let one specify the seed ? <dje>Heh. Missed ArneBab's comment. :) <moben>or use e.g. a hash of the source file as seed. iirc that's how gcc generates the build-id <moben>(disclaimer: I don't even know guile, but it came up when I checked for non-reproducing builds ;) ) <moben>so no idea if that is feasible <mark_weaver>moben: right, I think something like that is probably the right way to go, at least when building things using 'eguild compile' <mark_weaver>the trickier thing is how to cope with when things are compiled in an interactive session <moben>just checking if I got this right: interactive sessions with the same input should have the same seed and those with different input should have a different seed <moben>also, I guess the seed has to be initialized before anything can be compiled <mark_weaver>moben: technically, even interactive sessions with exactly the same input should have a different seed, I think. <mark_weaver>here's the thing: every time a macro is expanded, it needs a unique mark attached to all of its generated identifiers, and that mark must be different from every other macro expansion. <mark_weaver>things get more complex when you have macros that generate macro definitions <mark_weaver>if you compile the same macro twice, somehow they must end up with different marks in them. <mark_weaver>at least if there's any possibility that they might be loaded together into the same session. <mark_weaver>I thought deeply on this several months ago. if I recall correctly, the approach I favored at the time was to make 'guild compile' seed the per-session random number to a hash of the module name being compiled, on the assumption that two modules with the same module name cannot be loaded into the same session, at least not normally. <mark_weaver>(when reloading modules, maybe it's possible somehow) <mark_weaver>and then interactive sessions would still use the random number. <mark_weaver>I don't remember if the other maintainers were hoping for a better solution, or if I still needed to convince myself that this would do the right thing in all cases. <mark_weaver>anyway, for now, if you want to experiment with setting the seed, the relevant variable is 'syntax-session-id' in the (system syntax) module <moben>That sounds like it would solve the problems that distributions are having wrt reproducibility (and I don't even see how determinism should work for interactive sessions) <moben>mark_weaver: already found that one ;) <mark_weaver>and module/ice-9/compile-psyntax.scm is an example of setting it to a fixed value. we actually do that when creating psyntax-pp.scm from psyntax.scm <monumental_deuce>what is your opinion on that you can't have two versions of the same module co-existing in the load path? <monumental_deuce>And that I think J.K. Rowling's injunction which prohibits people from reading a book they find on the streets is ridiculous. <ArneBab>monumental_deuce: it’s common to many free software projects that there are issues which are simple but boring to solve. <ArneBab>mark_weaver: about that mark for macros: Is it actually possible to game that when I am able to guess that mark? <ArneBab>mark_weaver: for interactive use: Could you use the total input of the interactive session as seed? <ArneBab>dsmith-work: the guild hall goes deeper than wizards: It’s where craftsfolk of a common profession meet. Though wizards sound cooler ☺ <monumental_deuce>ArneBab, yeah truth be told, I can see why no one would want to spend time on something that trivial, it's just not very exciting. <ArneBab>monumental_deuce: which also means, by the way, that there are many low hanging fruits: Things with which you can make a big difference to many people without having to know the code very deeply. <ArneBab>monumental_deuce: just ask here - it’s likely that people can give you a pointer where to start <dsmith-work>ArneBab: Yes. Didn't know how to say all that simply. <ijp>ice-9 is a kurt vonnegut reference (this is also explained in the manual) <mark_weaver>monumental_deuce: you wouldn't be able to load both versions anyway. <ijp>I've only met two people that actually used the r6rs versioning stuff <ijp>weiholt, and the larceny author <monumental_deuce>Some of my older code would still use the old interface in that case and I might not want to update that. <ijp>I know what it's purpose is, that doesn't mean it is the best way to do it <ijp>well, every other language uses a package manager, and includes the version info there <monumental_deuce>With that system most languages are plagued by the idea that they can never really break the interface of libraries though. <monumental_deuce>Once the libraries are out their interface never gets altered even if they have what some people would consider a design flaw. <mark_weaver>if you want to change the interface of a module in a way that is not backward compatible, then it seems best to change its name. <monumental_deuce>Yeah, so that's what I do now, I just put 2 behind it in the name, which is basically the same thing, but much less elegant. <mark_weaver>if one were to modify guile to support multiple versions of the same module loaded simultaneously, probably the most straightforward way to do that would be to include the major version number as part of the name. <mark_weaver>but it's a very old assumption that the name of a module is sufficient to uniquely identify it. <mark_weaver>it would be a lot of work to change that assumption with any degree of confidence that you'd found all the places that assumed that. <monumental_deuce>Well, it's an assumption that has led to basically having to tie yourself to old bad choices. <monumental_deuce>I found having versions in imported modules to be a very nice thing of r6rs. <monumental_deuce>Especially when these concern small re-usable code for personal use where you hack and prototype it together quickly, and later realize you probably should have changed the interface, but at that point some scripts already depend on it <mark_weaver>with R6RS, it is possible to load two versions of the same module within the same session? do implementations actually support this? <ijp>mark_weaver: larceny maybe <mark_weaver>well, I agree that it seems like a nice feature. the problem is, it would be a huge amount of work for marginal benefit. there's a huge amount of more important work to be done, and not enough people to do it. <mark_weaver>it would effectively be part of the name anyway. everywhere that the module would be referenced would have to include the version number, to make sure it was uniquely identified in case two or more versions were loaded. <mark_weaver>so I don't even really understand how it would improve things, to be honest. <ijp>the metadata is already in there somewhere, since it is how r6rs versioning is implemented <mark_weaver>since we're talking about anticipating future incompatible changes, it would never be enough to ask for the newest version of a module. you would have to ask for a particular version that is known to work. <mark_weaver>so you'd have to include a version number in every import <mark_weaver>so how is it different than just including the version number in the module name? <ijp>mark_weaver: you can specify an inequality <ijp>but it can get pretty brittle. you sometimes get haskell packages failing to install for no other reason than a version number was bumped <ijp>that's kinda why web programmers prefer to do feature detection <mark_weaver>I guess the inequalities would have to be included in the compiled .go files as well. <ijp>hm, someone bumped my old bytevector bug report <mark_weaver>at some point I intend to look into revamping the way Guile handles modules, to make module auto-loading thread-safe, to support immutable modules per R6RS and R7RS, etc. when I do that, I'll see what can be done about versioning. <ijp>mark_weaver: if you do, ping me about adding parameterised modules <ijp>I did it a hack for it before, but at the time I had no idea about how to integrate it into use-modules <mark_weaver>there's a can of worms... but an enormously useful one :) <monumental_deuce>mark_weaver, well, it comes down to being part of the name, except that the name isn't used in an ad hoc way for what is a major version I guess. I use the name right now which just looks weird having numbers at the end of stuff. <ijp>davexunit: by imports <mark_weaver>hmm, it might not be quite as hard as I've been thinking. <mark_weaver>internally, the module names would have to include the major version numbers. <mark_weaver>but the number of places where code would have to be changed to translate what the user specified into this internal module name is probably relatively few. <davexunit>ijp: so, in your example, you have 2 modules that implement stream procedures, and a third module that takes as input a module that provides those stream procedures. correct? <ijp>davexunit: well, in that particular example, the module takes the procedures directly rather than the module <ijp>*than the stream module <ijp>"higher order modules" are just functions that return modules <ijp>in a robust implementation, punning like that isn't really the best idea <mark_weaver>it seems to me that this is really the way it needs to work internally anyway: as functions that accept a list of parameters (other modules probably) and return modules, with some kind of memoization. <mark_weaver>but I've not researched the issue. what do you think, ijp? <mark_weaver>what are your thoughts on how best to implement parameterized modules? <ijp>well, it's been two years since I last really looked so I'm rather rusty, but I think they are kind of problematic for compilation <mark_weaver>I guess the resulting .go file would have to include the list of parameters in its "name" somehow. <mark_weaver>if the parameters are limited to other module names, things get a bit easier I think. <mark_weaver>is parameters could include arbitrary procedures, it seems hard. <ijp>well, the thing is, you could write a module that is parameterized by another module that exports a macro <mark_weaver>but of course, those parameters could include other parameterized modules. <ijp>ML does not have that particular thorn <ijp>I think racket has units, which work similarly, so I'd probably crib from there <ijp>I think the url explains it all <mark_weaver>ijp: maybe better to (cons elt (delete elt %load-path)) ? <ijp>I thought of that, but I wasn't sure <ijp>I suppose in $WILDY_IMPLAUSIBLE_SCENARIO it can make a difference <ijp>right, I'll do that then push <ijp>bottles of beer on the wall?