IRC channel logs

2014-01-11.log

back to list of logs

<ArneBab_>no problem there: I actually use them in the wisp-parser and that bootstraps itself to scheme
<ArneBab_>does it need to support square brackets?
<ArneBab_>(foo [bar 5])?
<mark_weaver>well, R6RS mandates that [] are equivalent to ().
<mark_weaver>but of course, you are inventing a new syntax, so it's up to you.
<ArneBab_>then I’ll have to add support for that, I think.
<mark_weaver>IMO, it would be good to support SRFI-105 curly-infix notation.
<ArneBab_>wisp is just a preprocessor to regular scheme-code, so pasting any valid scheme in beween should work.
<mark_weaver>well, specifically, I think you should pass anything between curly braces unchanged.
<mark_weaver>just as you do with parens, I guess.
<ArneBab_>yes
<mark_weaver>curly infix can be combined with datum labels too, so you can have #0={...}
<ArneBab_>that should still work as soon as I have curly braces.
<mark_weaver>and of course, expressions delimited by curly braces can span multiple lines.
<ArneBab_>so actually it boils down to treating parens, square brackets and curly braces in the same way (but they can be nested).
<ArneBab_>almos the same…
<ArneBab_>almost
<ArneBab_>(foo [bar {5 + 6 ] }) ← nasty syntax error?
<mark_weaver>yes
<ArneBab_>can you see any cases where this would not be a syntax error?
<mark_weaver>no
<ArneBab_>then I could just treat parens, brackets and braces as abstract delimiters and not worry about the difference…
<ArneBab_>But I worry that such a simplification could break badly
<mark_weaver>well, if curly-infix mode is not enabled in the reader (and it's off by default), then '{' and '}' are not delimiters and can be part of unescaped symbols.
<ArneBab_>ouch…
<mark_weaver>but curly-infix mode is turned on automatically if "#!curly-infix" is present in the file.
<mark_weaver>but I wouldn't worry too much about edge cases like this. I think it's likely that your reader has a number of other problems with edge cases like this.
<ArneBab_>I guess that’s true…
<mark_weaver>it's not practical to get it exactly right without somehow integrating it into guile's native reader.
<ArneBab_>(though the version written in wisp is a good deal more versatile than the bootstrap version in python ☺)
<mark_weaver>you'd have to exactly match the detailed syntax understood by guile's reader, which is a moving target and has some complex nooks and crannies.
<mark_weaver>for that matter, guile's reader is also extensible.
<ArneBab_>can I quote you in my bug-notes?
<mark_weaver>heh, sure.
<ArneBab_>thanks ☺
<ArneBab_>Today I started working on something which hopefully becomes an SRFI at some point.
<mark_weaver>cool!
<ArneBab_>and guile -L . → ,L wisp already works quite nicely.
<ArneBab_>I can actually copy-paste wisp-code into that.
<mark_weaver>I have to admit, though, that although I prefer wisp notation to SRFI-110, I still find it hard to read, at least the way you tend to write it.
<ArneBab_>I’m learning to make it better - the last few months I actually learned new styles for writing it.
<mark_weaver>but that's just my personal opinion :) I'd still like to support the use of notations like wisp and SRFI-110 in guile.
*taylanub wasn't aware of SRFI-110
<ArneBab_>can you trace why it is hard to read for you?
<ArneBab_>taylanub: I helped with that until they added $ \\\\ and <* *> as syntax-elements to make some special cases more readable
<mark_weaver>well, I think if I were making use of such a notation, I wouldn't try so hard to avoid almost ever using parens.
<mark_weaver>I think both you and David take it too far in purging all parens.
<ArneBab_>I’m actually using parens quite a bit in more complex if-statements ☺
<ArneBab_>example: if : and (< x 2) (> x 7)
<mark_weaver>and then you end up with less intuitive notations, e.g. in things like 'let' forms, and I end up trying to figure out how all the colons map back to parens.
<mark_weaver>but maybe it's just that I've gotten so used to parens, I dunno.
<mark_weaver>also, I'm surprised that you don't use curly infix for things like (< x 2)
<ArneBab_>I found that I have far less need of that with wisp - actually a calc-macro would do the job for the stuff I need.
<mark_weaver>I'd rather see: if {{x > 2} and {x < 7}}
<mark_weaver>I find "if : and (< x 2) (> x 7)" very hard on the eyes, personally.
<ArneBab_>I’m still getting used to prefix-notation, so I tend to attribute such feelings to that - which obviously does not apply for you ☺
<mark_weaver>but again, this is just my personal opinion. if lots of other people prefer "if : and (< x 2) (> x 7)", that's more important than the one data point from me.
<ArneBab_>even better would be to have both
<ArneBab_>so people can experiment and a standard can emerge
<ArneBab_>(and implementing braces in wisp should give both)
<mark_weaver>yes, I'd like to support such experimentation.
<ArneBab_>for example to me the stacked curly braces look like overhead
<mark_weaver>beauty is in the eye of the beholder :)
<ArneBab_>but I try hard not to get used too much to seeing parens/brackets/braces - all that pulls me further away from new users.
<mark_weaver>of course, I agree that {x>2 and x<7} is yet easier to read, but then you lose the generality and homoiconity of scheme syntax.
<ArneBab_>I already find myself not caring that much about parens anymore…
<ArneBab_>yes
<ArneBab_>… if : and {x > 2} {x < 7}
<mark_weaver>btw, it can also be written {2 < x < 7}
<mark_weaver>which maps to (< 2 x 7)
<ArneBab_>ah, yes, I swapped the definitions…
<taylanub>I dislike it how the rationale section of SRFI-110 reinforces the idea that s-expressions are a bad syntax and people "tolerate" it at most. After just a bit of Paredit usage I find them simply superior to anything else. Might not be as nice without Paredit, but editing *any* text is unpleasent without a good editor after one gets used to the features of an editor.
<ArneBab_>taylanub: I prepared something for that today… let me get it…
<mark_weaver>yeah, there was an interesting mini-thread on the SRFI-110 mailing list about how something like paredit might not be doable without parens, or at least not in the same way.
<ArneBab_>taylanub: http://draketo.de/proj/wisp/why-wisp.html
<mark_weaver>because with s-exp syntax, you can unambiguously specify a subexpression from its starting position, whereas you can't do that in SRFI-110 (or wisp for that matter).
<ArneBab_>mark_weaver: I disagreed on that, by the way: SRFI-110 actually has sweeten and *unsweeten* code, so paredit could simply operate on a preprocessed version and move the changes back to the whitespace-code
<mark_weaver>david wheeler argued that something like paredit might still be doable, although with a different UI, but I'm not so sure. it's an open question.
<ArneBab_>(wisp does not has a wispify at the moment)
<ArneBab_>have
<ArneBab_>taylanub: here’s a mini-presentation: http://draketo.de/proj/wisp/why-wisp.html
<mark_weaver>ArneBab_: that assumes that you want the output of 'sweeten', which I strongly believe is a mistake.
<mark_weaver>with any of these syntaxes, for each subexpression, there are many choices of how to represent them. curly-infix or not? parens or not?
<ArneBab_>I would want a complete-roundtrip (unsweeten→sweeten) to produce exactly the same code as I had before.
<ArneBab_>with wisp that should actually mostly be possible.
<mark_weaver>anyway, if you want to look at the sweetened version of the code while editing, then sweeten/unsweeten doesn't solve the problem anyway.
<mark_weaver>paredit has several commands that operate on the sexp that's in front of the cursor.
<ArneBab_>at least in wisp, line numbers match up
<ArneBab_>and positions of parens are clear, too
<ArneBab_>(at the beginning, at a paren or at a " : ")
<mark_weaver>there's an implicit assumption in its UI that the sexp referred to by the cursor position is unique.
<mark_weaver>there's no way that an auto-sweetener would consistently produce code that I think looks good.
<ArneBab_>since this is about the round-trip, that should work for wisp: It’s still just a simple preprocessor: It only adds parens at the beginning, at the end and for inline " : "
<ArneBab_>the hardest problem is correctly parsing strings and escape-codes…
<ArneBab_>taylanub: shall I explain the presentation (just 5 pages)?
<ArneBab_>mark_weaver: the presentation also contains a test for how much you are already filtering parens ☺
<ArneBab_>mark_weaver: (on sweeten: I do not yet want to write a wispify, though. There’s lots of polish to do on wisp→lisp first.)
<taylanub>ArneBab_: The argument is that sexpr code isn't readable well because words get preceding and trailing symbols ?
<ArneBab_>yepp
<ArneBab_>and that the first and last letter of a word are the most important letters for recognizing it.
<ArneBab_>you can undo that with training (then you mostly stop seeing parens), but that’s not how people *start*.
<taylanub>I don't think we should judge languages by how well they can be read without a proper text editor. ... Wait, I just realized that I don't even have parens greyed out in my color scheme, funny.
<ArneBab_>in s-expressions, most lines start with a paren, which makes it harder to track lines.
<ArneBab_>taylanub: that’s your filter - similarly I don’t use rainbow-parens mode anymore.
<ArneBab_>(that’s *likely* your filter)
<ArneBab_>taylanub: and what actually disturbs me about readable is that it breaks the elegance of using the most common non-letter, non-math symbols.
<ArneBab_>(and that treating a single datum on a line as variable is not general)
<mark_weaver>going offline for a bit, ttyl!
<ArneBab_>I’m going offline too - for sleep ☺
<ArneBab_>cu
<mark_weaver>okay, good night!
<jenia>hello everyone
<jenia>im running geiser and guile
<jenia>i would like to trace a function
<jenia>how do i achieve that?
<ArneBab>jenia is already gone…
<zacts>is '(()()()) automatically reduced to '() in guile?
<zacts>guile-2.0
<zacts>I'm having a problem with a procedure that counts parenthesis
<zacts>and if so, how can I make it see each nested paren?
<zacts>I guess I must quote each null paren '()? :-)
<zacts>I've kind of answered my own question, it works now.. thanks. =)
<ArneBab>:)
<ArneBab>I don’t think it’s automatically reduced (at least it isn’t in the REPL)
<ArneBab>'(()()())
<ArneBab>$1 = (() () ())
<zacts>weird
<zacts>may I paste my procedure?
<zacts> http://paste.lisp.org/display/140864
<zacts>(count-parens-all '(())) => 2
<zacts>I can't figure out why. Even if you can at least tell me if there is a bug in my code, or a bug in guile, that would be sweet.
<zacts>(count-parens-all '(())) should evaluate to => 4
<mark_weaver>zacts: the problem is that '(()) is not null, (car '(())) => () is not a pair, so you get the final case: (count-parens-all (car '(()))) => (count-parens-all '()) => 2
<mark_weaver>there's no bug in guile, but the logic of your procedure is flawed.
<mark_weaver>sory, the last '
<mark_weaver>sorry, the last 'car' should have been 'cdr' in what I wrote.
<mark_weaver>maybe your confusion is that you think () is a pair?
<civodul>Hello Guilers!
<mark_weaver>good morning, civodul!
<civodul>mornin' mark_weaver!
<civodul>are you getting up early or did you give up sleeping? ;-)
<mark_weaver>zacts: the bug in your code is that you assume that if the CAR is not a pair, then it has no parens. but that's false. '() has parens, but it's not a pair.
<mark_weaver>civodul: up early :)
<civodul>heheh
<mark_weaver>civodul: are you sure we can't change the hash function in stable-2.0? right now, the hashing function takes unbounded amounts of time for certain structures involving vectors. e.g. for #0=#(#0#) (a singleton vector containing itself), it goes into an infinite loops.
<mark_weaver>more generally, any structure containing only vectors of size <= 5 will be completely scanned, no matter how large.
<mark_weaver>s/scanned/traversed/
<mark_weaver>I have a patch that fixes this, but of course there's no way to fix this bug without changing the hash function.
<mark_weaver>so there's no way to support cyclic vector literals in the compiler without fixing the hash function (or making an alternative hash function that's not broken, just for the compiler)
<civodul>mark_weaver: weren't you the one arguing that the hash function could not be changed? :-)
<mark_weaver>no, never
<civodul>oh, so that was me?
<civodul>:-)
<mark_weaver>well, you were always unsure.
<civodul>right
<civodul>structures containing only vectors of size <= 5
<civodul>what a weird use case
<civodul>hmm
<mark_weaver>well, even if a lot of the vectors are larger than 5, it will still often scan unbounded amounts of stuff.
<mark_weaver>that was just one simple theorem I could prove easily.
<civodul>yeah that's an issue
<mark_weaver>this is my fix, on the r7rs-wip branch: http://git.savannah.gnu.org/gitweb/?p=guile.git;a=commitdiff;h=8834a0b6e7bc0d8367e8e6fe54b94f661a1675bd;hp=748b2024c0aa3e224c0378205016fae1b0fcd76a
<civodul>it needs comments and perhaps factorization
<civodul>why does it start at 1 in one case an n-1 in another case?
<civodul>oh that's historical, OK
<mark_weaver>well, in this patch, I made minimal changes to what was already there.
<mark_weaver>I suppose it would be better to just rethink the strategy for vectors from scratch.
<civodul>i don't get it
<civodul>is there any change other than if(d) ?
<civodul>yeah sorry, i was just looking at the + part
<mark_weaver>there are three changes: (1) if(d) (2) in the len>5 case I pass (d>2)?2:1 instead of 2 to the nested call to scm_hasher, and (3) in the (len <= 5) case, I pass (d-1)/len instead of d/len to the nested call.
<mark_weaver>basically, I want to make sure that 'd' is always reduce in any nested call.
<mark_weaver>*reduced
<mark_weaver>d/len doesn't get reduced at all if 'len == 1', which I wanted to fix.
<mark_weaver>and passing '2' in the len>5 is a problem because it will traverse infinitely deep into the first elements of a nested tree of vectors.
<mark_weaver>another general theorem is that the vector hasher will always traverse into the vector's first element, no matter what.
<mark_weaver>well, as long as (d >= 2).
<mark_weaver>sorry, I guess that last theorem is wrong.
*civodul is back
<civodul>ok, i see
<civodul>so definitely "if (d > 0)" was missing
<civodul>then, how about (d / (len + 1)) ?
<civodul>that makes sure it reduces
<mark_weaver>sure, that would also work.
<mark_weaver>passing '2' to the nested call in the len>5 case also needs to be fixed, though.
<mark_weaver>because it will traverse infinitely deep into the first elements of vectors with len>5
<civodul>how come we've lived with this code for so long?
<mark_weaver>good question! I don't know :)
<civodul>:-)
<civodul>anyway the commit above looks OK
<civodul>could you add spaces though, and SCM_MAX instead of the ternary "?"?
<civodul>and eventually, we should redo that thing
<mark_weaver>sure. okay for 2.0, you mean?
<civodul>i think so
<mark_weaver>okay, sounds good, thanks!
<civodul>could you post a heads-up to guile-devel?
<mark_weaver>will do
<civodul>cool, thanks for fixing this
<mark_weaver>np!
<mark_weaver>civodul: that ternary can't be expressed with a single SCM_MAX
<mark_weaver>the closest would be SCM_MAX (2, d-1), but that's not quite the same, although maybe it's not a big deal.
<mark_weaver>the difference is the d == 1 case.
<mark_weaver>well, it's not important. sorry to bother you with this.
<mark_weaver>I'll do SCM_MAX (2, d-1)
<civodul>ok
<mark_weaver>oh, I see a better way. in the (len > 5) case, change i = d/2 to i = (d - 1)/2;
<mark_weaver>then we can leave the 2 as is.
<mark_weaver>that also makes 'd' a better approximation to the amount of work done.
<mark_weaver>I'll post an updated patch to guile-devel.
<mark_weaver>we can continue this on the ML.
<civodul>ok, thanks
<civodul>i'll look into it
<mark_weaver>um, SCM_MAX is only in private-gc.h
<mark_weaver>civodul: I just posted a patch: http://lists.gnu.org/archive/html/guile-devel/2014-01/msg00010.html
<mark_weaver>it's effectively the same code as what you already said "ok" to, but with the loop moved out of the 'if'.
<civodul>mark_weaver: just replied, OK for me!
<civodul>and sorry for the delay
<mark_weaver>no worries, thanks!
<mark_weaver>I'm embarrassed to admit that I posted the patch without even trying to compile it. Turns out it's correct except for SCM_MAX being missing.
<civodul>i'm embarrassed to admit i didn't notice :-)
<mark_weaver>I wonder if we should move SCM_MAX and SCM_MIN somewhere more sensible.
<mark_weaver>or I could include gc-private.h, or copy the definition of SCM_MAX into hash.c. WDYT?
<mark_weaver>or switch back to the ternary operator.
<mark_weaver>s/gc-private.h/private-gc.h/
<mark_weaver>hmm, looks like SCM_MAX has been removed from master.
<mark_weaver>ah, in master it's called 'max' and is in _scm.h
<mark_weaver>well, this is all trivia. I'll take care of it.
<mark_weaver>bah, I want SCM_MIN (2, d - 1), not SCM_MAX (2, d - 1).
<mark_weaver>too much to do, and it's making me tempted to rush things :-(
<civodul>heh, that happens
<civodul>maybe it's time for a break? :-)
<mark_weaver>yeah, maybe :)
<mark_weaver>well, you suggested I use SCM_MAX :-P
<mark_weaver>:)
<civodul>i'll take a break too :-)
<civodul>sorry about that
<mark_weaver>there must be a gnulib module for this
<mark_weaver>hmm, there doesn't seem to be. too trivial, I suppose.
<zacts>oh thanks mark_weaver
<zacts>works with list?
<mark_weaver>if you change pair? to list?, it will then work properly as long as there are no improper lists.
<mark_weaver>if there are no improper lists, then the following will suffice:
<mark_weaver>(define (count-parens obj)
<mark_weaver> (if (list? obj)
<mark_weaver> (fold + 2 (map count-parens obj))
<mark_weaver> 0))
<zacts>neat
<zacts>yeah, this is only for proper lists
<mark_weaver>and all the sublists have to be proper as well.
<zacts>every sublist is proper also
<ArneBab>wingo said on twitter, that he’ll be back soon
<mark_weaver>that's good!
<jenia>hello. im using guile and geiser in emacs
<jenia>how do i debug scheme code in guiser?
<mark_weaver>see section 4.4.6 of the guile manual (Interactive Debugging)
<jenia>okay thanks
<ArneBab>The embedding-docs undersell how easy it is to embed guile: It actually looked hard until I took apart the code: http://www.gnu.org/software/guile/manual/html_node/A-Sample-Guile-Main-Program.html#A-Sample-Guile-Main-Program
<ArneBab>Ideas to improve it: Subsections for the make-file (at least titles) to separate the autotools from the simple makefile.
<ArneBab>and syntax highlighting!
<ArneBab>having a linebreak after the return type also feels quite unusual (but maybe that’s just me).
<ArneBab>I compared it to lua - their instructions are actually much more complex, but they *look* simpler (and looks matter when you try to get users)
<mark_weaver>having the function name in the first column is a GNU coding convention, and one that we follow in Guile.
<dje42>anything else is unusual to me :-)
<mark_weaver>and personally, I think it's important, because often the return type and other things like 'static' get rather long, and the function name gets buried.
<dje42>agreed
<mark_weaver>ArneBab: but otherwise I'm certainly open to trying to improve that section. Would you like to post about it to guile-devel, preferably with a suggested patch?
<mark_weaver>more generally, our manual could certainly use improvement in several areas.
<ArneBab>mark_weaver: ok
<ArneBab>I’m currently dabbling with it to see how the code would look easier.
<mark_weaver>great, thanks!
<ArneBab>wouldn’t the GNU coding standards also have the { after indented slightly?
<mark_weaver>in most places, but not at the toplevel.
<ArneBab>ah, ok
<ArneBab>can I make the lines slighly longer (64 chars)?
<ArneBab>is the return 0; in the main() really never reached, or only after the interpreter stops?
<mark_weaver>I'm not sure off-hand. Ludovic might know, but ultimately I think it comes down to how it looks in PDF (either Letter or A4) and how it looks in emacs info mode on a 80-column text display.
<mark_weaver>I'm not sure off hand.
<mark_weaver>on either question.
<ArneBab>I’ll just test the second
<dje42>scm_boot_guile does not return
<dje42>[a (suitably conditionally defined) ATTRIBUTE_NORETURN or some such in the header could be useful]
<dje42>No disagreement that it's a bit antisocial for a library, but there are other entry points.
<mark_weaver>we have SCM_NORETURN
<dje42>Ah.
<mark_weaver>if you want something that returns, you can use scm_with_guile
<dje42>Yep.
<dje42>Still, if users want to start a full repl (and have it return when the user types ,q or some such), it currently requires a bit of a hack whereas scm_boot_guile feels right.
<ArneBab>ok, return 0; just suppresses a compiler warning.
<dje42>Yeah. Add SCM_RETURN to scm_boot_guile's decl and then that won't be necessary.
<dje42>[I looked in 2.0.9, maybe it's already fixed]
<dje42>Oops, SCM_NORETURN.
<mark_weaver>hmm, good point. I wonder if there's a reason that wasn't already done. We certainly have lots of SCM_NORETURN declarations in the tree already.
<ArneBab>and then the return 0; would actually be reached?
<ArneBab>that would certainly make the code-example easier to read ☺
<dje42>No, but the compiler wouldn't issue the warning.
<ArneBab>ah, ok
<dje42>Convention is to still add something like /*NOTREACHED*/ there.
<ArneBab>why isn’t it reached? To me that sounds quite strange…
<dje42>How so? [see the definition of scm_boot_guile, e.g.,]
<ArneBab>(I can imagine lots of situations where I’d just want to drop users into a debug shell and continue the program flow whetn that is finished).
<ArneBab>whetn→when
<mark_weaver>okay, but that's not what 'scm_boot_guile' does.
<dje42>Ah, why is it strange for scm_boot_guile to have been defined that way. [that's what you meant] Agreed, a bit strange, but oh well.
<ArneBab>it’s a code-example. I do not expect to have to look up a definition to understand it.
<mark_weaver>just use scm_with_guile instead
<ArneBab>(and it is the first code-example any embedder would see)
<dje42>ArneBab: It's not uncommon for some functions to be defined "no return". You shouldn't have to look up the definition, no. I misunderstood your question was, that's why I said that.
<ArneBab>no problem (I hope my answer did not sound as if I was offended)
<mark_weaver>I guess I'm not clear on why an embedder would expect to run code after 'scm_boot_guile'. Whatever cleanup code they want can be put at the end of whatever function is passed to 'scm_boot_guile'.
<ArneBab>the docs say « void * scm_with_guile (void *(*func)(void *), void *data) »
<ArneBab>what exactly do I pass it?
<dje42>Here's an example that uses scm_with_guile to start a repl. https://github.com/xdje42/gdb/blob/gg-pass1/gdb/guile/scm-safe-call.c#L460
<mark_weaver>are the scm_with_guile docs unclear?
<mark_weaver>"Call FUNC, passing it DATA and return what FUNC returns."
<mark_weaver>one advantage to calling 'exit' within guile mode is that atexit-registered functions can use the guile API.
<mark_weaver>btw, feel free to disagree with me. I'm giving my perspective, but admittedly my perspective is a lot different than that of a newcomer to Guile, and I appreciate your input on this.
<ArneBab>mark_weaver: I think they are just incomplete when seen in isolation: where do I get func, how do I pass it (syntax) and what data do I give?
<ArneBab>an example would do wonders here ☺
<mark_weaver>hmm. well, this is pretty basic C stuff, and there are a lot of functions with APIs like this. Do we provide an example for each one? Section 5.2.2 already has a basic example of how to boot guile using scm_boot_guile.
<mark_weaver>I guess it comes back to this: I don't know why it's considered suboptimal that whatever you would have put after 'scm_boot_guile' (if it returned) should be put at the end of your 'inner_main' instead.
<mark_weaver>I think it's more likely that users will get tripped up if they leave guile mode before exitting.
<ArneBab>void *(*func) (void *) ← a pointer of a ....
<mark_weaver>that's a relatively advanced thing to want to do, and I'd expect such users to be able to figure out how to use scm_with_guile without much trouble.
<ArneBab>I think it’s the first time I every saw such an argument definition…
<mark_weaver>frankly, I'm not sure why non-advanced users would want to use C at all, except perhaps to extend guile (as opposed to embedding libguile within a C program)
<ArneBab>I do not have ages of experience with C, but it’s definitely not covered in crashcourses…
<ArneBab>Even beginning users need to ship their programs.
<mark_weaver>yes, but why use C at all?
<ArneBab>to be able to sidestep package managers
<mark_weaver>I don't understand what you mean by "sidestep package managers"
<ArneBab>if you want to be able to ship a binary, then you likely need C
<ArneBab>(or is there a simple way to ship guile code as complete program?)
<dje42>Does shebang work with Guile? I'd presume so.
<mark_weaver>yes
<ArneBab>if the right guile is installed
<ArneBab>(lilypond is currently non-functional for me since the installed version does not support guile 2.0)
<ArneBab>also many non-advanced users write programs in C and then realize that they want to make them extendable
<mark_weaver>linking C to libguile does not alleviate the potential problem of "wrong guile version", in fact it makes it much worse.
<jenia>why isnt gimp using guile?
<mark_weaver>because it makes you sensitive to the libguile ABI, and not merely the set of Scheme macros/procedures/modules you use in your program.
<ArneBab>that’s then where people would link statically
<mark_weaver>well, even so, you need to include the .go files and so on.
<ArneBab>yes
<mark_weaver>I agree that we should have a better story to building monolithic self-contained installers for macos and windows.
<mark_weaver>but that problem is not solved, or even helped, by using C. in fact using C makes portability problems much worse.
<ArneBab>that’s what I expect when I want to just build a program which uses guile: Have a simple way to put everything together.
<jenia>ahha okay thanks. so how do they achieve in scripting their c program using scheme without the c/scheme guile library (ABI)?
<ArneBab>portability is not the same as distributing
<mark_weaver>if we want to accomplish this task, we need to attract developers who with with macos and windows to get the job done.
<mark_weaver>s/who with with/who work with/
<ArneBab>jenia: I never found an answer why gimp isn’t using guile
<jenia>how do they use c data types in scheme without guile?
<mark_weaver>ArneBab: again, how does using C help?
<mark_weaver>ArneBab: as I see it, to accomplish what you're looking for, we need Guile bundles for MacOS and Windows, where you can easily plop in your own top-level Scheme program.
<mark_weaver>I don't see how using C helps at all. We can provide the main program that invokes the user's top-level Scheme program.
<ArneBab>mark_weaver: that would fullfill my personal needs, but I’m actually still looking at the code-example.
<mark_weaver>and then it can use C libraries if needed, ideally via the dynamic FFI.
<mark_weaver>and what's the problem with the code example again?
<ArneBab>The extend-with-guile section of the manual is quite big, and the code-example is about running guile-code from a C-program.
<mark_weaver>(I apologize if I seem defensive; I'm just honestly confused what the problem is, and would like to understand)
<ArneBab>I’ll try to get my thoughts on that organized: The intention of the guile-interpreter-in-c-program is to show how easy it is to embed guile
<ArneBab>this makes it serve as a minimal example for how you can take a C-program and add guile to it.
<ArneBab>which implies that this is a viable way to use guile.
<mark_weaver>yes
<mark_weaver>so I'm looking at the sample code in section 5.2.2 (A Sample Guile Main Program), and it looks impressively short and sweet to me. How can it be improved?
<ArneBab>(I’ll get to that in a minute)
<ArneBab>now imagine that some game-developer has a game he or she wants to make extendable with guile. The game won’t land in the distros fast enough (and it might be a game which is sold for money, like Aquaria), so the dev needs to ship a binary.
<ArneBab>Anything which is more complex than a zip-file with an executable and some folders will cost users, so the game needs to be a single binary with some additional files in folders.
<ArneBab>Which works on all distros.
<mark_weaver>wait, why does it help anything for the game to be a single executable, as opposed to a shebang script?
<mark_weaver>sorry, nvm.
<ArneBab>a shebang script requires installing guile on the target system
<mark_weaver>so yes, it's a binary, and it's linked with libguile.
<ArneBab>statically
<mark_weaver>why does that matter? what's wrong with using a shared library?
<ArneBab>and it includes all *.scm files (or *.go files)
<dje42>One question that arises is whether Guile is self-relocating.
<mark_weaver>oh, you want all the .go files linked into a single file?
<dje42>If it's dynamically linked, as long as the rpath uses ${ORIGIN}, the user could run the binary without extra effort.
<ArneBab>in my (limited) understanding, the shared library needs to be installed. The user might not be able to install anything on his or her system.
<dje42>[e.g., without having to set LD_LIBRARY_PATH]
<mark_weaver>well, you can use rpaths
<ArneBab>all .go files (and everything) in a single file would be ideal, but I’d not go that far. All .go files in a subfolder of the game would be required, though.
<mark_weaver>sure, that's not a problem.
<ArneBab>in the end, it has to be possible to start a stripped-down gentoo system (but with X), unzip the folder and run the program.
<mark_weaver>you can set the GUILE_LOAD_PATH and GUILE_LOAD_COMPILED_PATH variables before booting guile.
<ArneBab>that’s the minimal GNU/Linux distribution story.
<ArneBab>(as I see it)
<mark_weaver>hmm, I agree that many developers want this, although I think most users in their right mind should want to use the shared libraries that are properly integrated with their distro.
<ArneBab>naturally it is not the developer-story, though: For developers all that is useless.
<ArneBab>A developer would just ask “what do I need to install to compile this?”
<mark_weaver>for GNU/Linux systems, Guix probably provides what's needed.
<ArneBab>does it work without installing guix?
<ArneBab>(otherwise it just moves the problem to another layer)
<mark_weaver>well, basically you're looking for a bundle that includes all shared libraries, etc.
<ArneBab>yepp
<ArneBab>imagine that you want to ship a game-prototype to your secretary.
<mark_weaver>and that's exactly what Guix does. everything goes in /nix/store/*, but that directory can be configured when Guix is built.
<mark_weaver>and once you have those /nix/store/* directories, including all dependencies, then you don't need anything else from Guix.
<ArneBab>he or she does not have root, nor any programming skills. But decompressing a zip-file and clicking a binary are supported by the GUI.
<ArneBab>did someone already test using guix for that?
<mark_weaver>well, the missing piece is that the system Guix builds is not relocatable at run-time.
<mark_weaver>you can put it wherever you want, but you have to choose at compile time where that is.
<ArneBab>that then won’t work for users…
<ArneBab>Do you think the problem got clear?
<mark_weaver>sure, although this is a much different issue than the one we started on.
<ArneBab>it grows hairs when it meets the needs of game developers ☺
<ArneBab>then to the code-example
<ArneBab>it starts with the header: that’s more than one line, which makes it bigger than parts of the significant code.
<ArneBab>then the comment above #include <libguile.h> is redundant: It should be clear that this gets guile.
<ArneBab>and the comment above scm_shell doesn’t really help - it would be more useful in an expanded example with explanation.
<ArneBab>(it mixes explanation with example, but that explanation is not expanded in the text)
<ArneBab>and conceptually an inner_main function shouts “non-standard” (that’s why I asked for something else).
<ArneBab>but if the inner_main is required, comments could be /* preparations */ scm_shell /* execut after exit */
<ArneBab>that would show that inner_main is the actual workhorse.
<ArneBab>with an scm_boot_guile which does not trigger the return-warning, a /* never reached */ comment (without return) would not feel strange anymore.
<ArneBab>mark_weaver: here’s an example: https://piratenpad.de/Fxq4QzmAqd
<mark_weaver>looks reasonable, but I guess part of the issue is that I don't see why you'd want to write a program that called 'scm_shell' and then did other stuff after. if you're extending an existing C program, then you probably don't want to call 'scm_shell' at all. instead, your whole program goes in 'inner_main', which I guess seems obvious to me, but maybe it should be spelled out, dunno.
<mark_weaver>I agree that scm_boot_guile should be declared SCM_NORETURN so that the 'return 0' is not needed.
<ArneBab>you could use scm_shell as debug-shell
<mark_weaver>I guess these little tweaks seem relatively trivial to me, and this section is really aimed to relatively advanced C programmers, I think.
<dje42>It feels reasonable to export a simple way to start a Guile repl and have it return to the caller when the user types, e.g., ",q".
<ArneBab>why is this section aimed at advanced C programmers? If you’re an advanced C programmer: Why would you want to use Guile?
<dje42>There's lots of reasons why C programs (simple or complex) would want to include a scripting language.
<dje42>It's not really an advanced vs beginners kind of question.
<ArneBab>(I know: Some would want to - but the number of mediocre C programmers who can understand Guile Scheme is much larger than the number of advanced C programmers who can do it
<dje42>I don't understand.
<ArneBab>actually it’s ones who first lookmple are likely not the advanced ones ☺
*ArneBab just has a system overload due to texinfo…
<mark_weaver>well, forget what I said about "aimed at relatively advanced C programmers".
<mark_weaver>well, for starting a REPL and waiting until they quit, there's 'start-repl' in the (system repl repl) module.
<mark_weaver>so to call that from C, you'd write scm_call_0 (scm_c_public_ref ("system repl repl", "start-repl"));
<mark_weaver>'start-repl' is not currently documented, I see.
<ArneBab>why does guile compile the whole guile when I run make in docs/ref/…
<mark_weaver>does it? I find that surprising. I don't know much about our build system.
<mark_weaver>I think that part of our docs might be autogenerated by a guile script, or something.
<ArneBab>I found it surprising, too - luckily the OOM-killer just reclaimed the memory from Firefox and not from Emacs ☺
<ArneBab>mark_weaver: here’s what I’d change: http://paste.lisp.org/display/140868
<ArneBab>(untested due to the build memory-issue…)
<mark_weaver>ArneBab: looks reasonable to me (although this assumes as a prerequisite that we'd added the SCM_NORETURN declaration to scm_boot_guile)
<ArneBab>yes
<mark_weaver>ArneBab: would you like to post patches to guile-devel? one to add SCM_NORETURN, and this one? (preferably using 'git format-patch')
<mark_weaver>oh, you don't have enough memory to build guile?
<mark_weaver>wow, I've built it on some machines that are quite small by today's standards.
<ArneBab>FF just got killed due to a OOM - but I can build guile
<ArneBab>(otherwise I’d not have it - I run Gentoo (source-distro))
<ArneBab>SCM_NORETURN would be harder (I don’t know where to search)
<mark_weaver>well, the idea is to add it to the 'scm_boot_guile' declaration, right?
<mark_weaver>hmm, I wonder if there are ABI implications to this declaration. If so, we might not be able to do it in stable-2.0.
<mark_weaver>anyway, so search guile source tree for 'scm_boot_guile'
<mark_weaver>tip: the C code is in libguile and the Scheme code is in modules.
<mark_weaver>you probably need to change it in both the .c file and the .h file.
<mark_weaver>or, don't remove the 'return 0'
<ArneBab>Do I declare SCM_NORETURN in .c after the arguments or after the block (after the final })?
<mark_weaver>I don't think we can do this in stable-2.0
<ArneBab>(I think not removing the return 0 is safer for guile-2.0 - otherwise these changes are blocked by the discussion about SCM_NORETURN
<mark_weaver>currently, we put SCM_NORETURN after the argument list, but I think it will end up being moved before the argument list.
<ArneBab>ok
<mark_weaver>but for now, any patch should put SCM_NORETURN after, for consistency with all the existing code.
<mark_weaver>in guile
<ArneBab>ok
<mark_weaver>so if you make a patch for this, it should be for master.
<ArneBab>so, first things: the doc patch.
<mark_weaver>the improvements to the manual should be for stable-2.0 though.
<ArneBab>I can’t use git format-patch (because I don’t use git), but you should be able to just apply the diff output with git.
<mark_weaver>do you wish to be a contributor to software projects? "no" is a fine answer, just curious :)
<mark_weaver>sorry, that was uncalled for.
<ArneBab>I wish to avoid shooting myself in the foot again ☺
<ArneBab>so I access git-repos with hg-git.
<ArneBab>git cost me so many hours, that this additional step actually saves time.