<ijp>okay, so, it's easy to add a list of ignores as a bot field <ijp>but I've been trying to figure out how I can do it as an extension <ijp>first I thought about adding it as a privmsg hook <ijp>but that's order dependent, so no good <ijp>so I though about adding another hook: a "pre-privmsg hook", but I'm not liking that either <ijp>the bot field may end up being the least hacky solution <ijp>so it isn't laziness, but more a question of which way I hate the least <ijp>as an aside, I want to add a 'channel' argument to bot commands <ijp>but if the arguments pile up, it may be best to make them all keywords <aidalgol>ISTR you and wingo didn't like it when I was asking for feedback ages ago. <ijp>the latest plugin adds a privmsg hook for snarfing <ijp>I also want to keep it around for logging <ijp>and you'll hate me for it <ijp>I've been pondering on committing a 'commands' function; fbs says I shouldn't <ijp>no, different people <aidalgol>Why not, and why should we listen to him? <ijp>he wrote a guile irc library <ijp>he thinks it's spammy <ijp>but since we can privmsg it to them in private, I don't see the problem <ijp>a fancy name for a vector of strings <aidalgol>At a glance, this plugin looks more compex than I thought it would, but the snarfing seems acceptable. <ijp>aidalgol: except for the setup! function, it was all written "wishful thinking" style, so it's quite readable <aidalgol>Actually, why isn't lets implemented as a command? <ijp>let's $something_stupid <ijp>it saw a let's, and copied it to the corpus <aidalgol>Oh! OK, now I get it. I was confusing the snarfing with command parsing. >_< <aidalgol>My brain's still a bit fuzzy from my cold. <aidalgol>Which was prolonged by the stress from the storm <aidalgol>Did you see in #emacs about the hurricane? <ijp>btw, I updated erc-shoot with the current firearms list <aidalgol>That's why I don't have a cbot instance up already. :P <aidalgol>ijp: sans the really obscure, context-dependant ones? <ijp>they're all obscure context-dependent ones <aidalgol>I mean the ones derived from #emacs memes. <ijp>I haven't went through them *ijp loads his lightning bolt and sends aidalgol to tartarus. <ijp>except for the slashdotfic, they don't seem too bad <ijp>and maybe the tattooist one, since it refers to vim <ijp>I really need a new pure data structure to fawn over <ijp>not unless you've got some plan to continuously feed new firearms while continuously shooting <ijp>same reason I used that truly awful vector-cons method in lets.scm <ijp>aidalgol: have you seen pfds? it's kind of a hobby of mine <ijp>I need something that will get me as excited as fingertrees did *aidalgol looks up again... <ijp>of course you have, it's in my fsbot entry <aidalgol>I think I remember you gushing over fingertrees in here aaaages ago. <ijp>yes, and you know how jaded I am <aidalgol>Back when my bot was just a non-interactive loop, and I was still getting it to reply to keepalive pings. <aidalgol>How do you have purely functional data scructures in a non-pure functional language? <ijp>by not using any of the impure bits <aidalgol>In your opinion, what is the best way to get a good understanding of FP? <ijp>actually, I do have a branch in which I rewrite the fingertrees code to use a reader monad <ijp>they have a great macro stepper <ijp>that alone is reason to keep drracket installed <ijp>especially now that install doesn't spend forever compiling docs...-_- <aidalgol>I've been pondering how to make cbot default to rudybot-like regurgitation when there is no match. <aidalgol>I'm not sure how to guarntee that it's run only after every other plugin is done. <ijp>I learned fp from SICP, if you're not used to it by the 3rd chapter, you weren't paying attention <ijp>it's not difficult conceptually, it just takes a lot of practice <aidalgol>I think I get FP; I may just have self-doubts. <aidalgol>I have time now that I'm not studying fulltime. <ijp>adding a regurgitation to handle-commands is easy, the tricky part is other things in privmsg-hook <ijp>you could snoop on send-privmsg, but that's really gross <shanecelis>I want to make a defvar (or define-variable) that defines the variable if it hasn't been defined, or leaves it alone if it has already been defined. <shanecelis>Given (define-variable x 1 "Some var x."). I have a macro that does this, but Guile reports a warning that x is an Unbound variable. <shanecelis>How do I make it such that Guile doesn't report an unbound warning since x will definitely be bound. <mark_weaver>shanecelis: I'd recommend expanding to (define <name> ...) where the ... looks for an existing binding and reuses the existing value (if any), or else uses the value that the user gave. <nalaginrut>shanecelis: I've heard that your tried green-thread alike thing in Emacsy? ;-) <mark_weaver>nalaginrut: I vaguely recall that he copied that from davexunit's guile-2d <nalaginrut>I discussed with davexunit yesterday, the agenda scheduler may not suit for green-thread, duuno, I feel like this <nalaginrut>Artanis needs a customized server, to handle uploaded-file and web-socket <mark_weaver>the hardest part of implementing green threads is to modify all our primitives that would block, and arrange for them to not block. <nalaginrut>our current http server will read whole request body, so I can't let user constrain the uploaded-file size <nalaginrut>mark_weaver: so you mean it's impossible to implement a green-thread external? <mark_weaver>well, if you want things like 'read' to not block the entire POSIX thread, then yes, core changes are needed. <mark_weaver>there are ways around that, but they would be very painful. <nalaginrut>OK, if I have to touch guile-core, I think it's better to support thread-break for green-thread, wingo gave me a hint to think about VM hook *nalaginrut feel the things getting more and more complicated。。。 <nalaginrut>but the embarrass thing is maybe it's not cool to based on current VM implementation <nalaginrut>maybe a better way is watchdog, break the thread and schedule it, then call next <nalaginrut>I can break a thread in certain seconds with SIGALARM, but I can't catch the delimited-continuation in alarm signal action function <mark_weaver>nalaginrut: I'm sorry, but I don't think it's sane for you to try to do green threads externally. <nalaginrut>alas, but I do think it's nice to have it in core <nalaginrut>mark_weaver: I think there's an easy way to handle 'read' <nalaginrut>suggest users try epoll, and we don't promise the non-block in green-thread <nalaginrut>and another nice way is we provide NIO in guile core <mark_weaver>well, that's the "very painful" method I was alluding to before. <mark_weaver>you can use select/poll/epoll, and then use 'get-bytevector-some', and build all other I/O on top of that. <mark_weaver>the problem is that you can't use anything in guile that might call anything that blocks. <mark_weaver>which means you effectively have to rebuild a lot of guile on top of your primitives. <nalaginrut>when read nothing, edge-triger won't block, it'll throw EWOUDBREAK, then user may yield <nalaginrut>but the problem is the dependency of epoll, or kqueue <mark_weaver>the problem is that Guile's core I/O routines are not designed to handle non-blocking I/O. <mark_weaver>that's the hard problem. well, not so much hard as tedious. <mark_weaver>the wip-ethreads branch basically has a new I/O system in it. the problem (or so I've heard) is that it's a duplication of the existing ports, which is not a good long-term solution. <mark_weaver>what we need to do is to enhance the existing ports to support non-blocking I/O. <mark_weaver>not just I/O though... anything in Guile that could block needs to be changed. it's a big job. <nalaginrut>I have a question, is it possible to provide non-blocking when users try poll/select? <mark_weaver>yes: after poll/select indicates that at least one byte is ready on a port, then use 'get-bytevector-some'. <mark_weaver>but then you have to build the entire I/O infrastructure on top of that. and you need to avoid calling anything that would use the normal I/O procedures. <mark_weaver>you can't. 'get-bytevector-some' just gives you some number of bytes (at least one). it will not block if there's at least one byte ready. <mark_weaver>on top of this, you could build something that reads a specified number of bytes. <mark_weaver>right, but 'select' will tell you when there's at least one byte ready. <mark_weaver>Since 2.0.9, 'get-bytevector-some' is very efficient. It's by far the most efficient way to read many bytes without blocking. <nalaginrut>I wonder if we should do so much thing for poll/select, the high performance concurrency needs non-block stuff <nalaginrut>and the performance of select will decrease when fd more than 1024 <mark_weaver>note: before 2.0.9, get-bytevector-some was slow as molasses. <mark_weaver>nalaginrut: maybe you can use the Dynamic FFI to call epoll. <nalaginrut>the problem is I have to tell user use epoll all the way <nalaginrut>since I left all the non-block work for them, which sound suck for users ;-( <mark_weaver>the problem, again, is that although you can build your own non-blocking I/O on top of 'get-bytevector-some', it's very inconvenient because so many other things in the system are expecting to use the normal I/O primitives. <mark_weaver>that's why I think it's probably best to just wait until Guile has green threads in core. <nalaginrut>yes, if we let users do non-block work, they don't know how to avoid problem, and hard to choose functions <nalaginrut>mark_weaver: you know the word I'm afraid of is "wait", since I know how long your TODO is <mark_weaver>nalaginrut: indeed, I have no idea when I might get around to doing that work. <nalaginrut>I wonder if other languages handle non-block in core well <mark_weaver>sure, plenty of them support it. several Scheme implementations support green threads too. <nalaginrut>all of them have method to avoid to block whole thread? <nalaginrut>If one thread in a process blocks on I/O, they all block. However, if the underlying OS supports AsynchronousIo? or select, it is possible to get around this limitation. <mark_weaver>you don't need asynchronous I/O. You can do it with select/poll/epoll. <nalaginrut>hmm..and I wonder if wingo or you have time for ethread/nio branch <mark_weaver>wingo seems very focused on the RTL compiler right now. I've not seen him do much else. <mark_weaver>if you really can't wait, you could just build your own I/O system in Scheme on top of epoll/get-bytevector-some. <mark_weaver>nalaginrut: in current git, I fixed all the problems I know of in both client and server. <mark_weaver>it now sends Content-Length even if the body is empty. <mark_weaver>nalaginrut: if you could build the latest stable-2.0 git, and make sure it works properly, I'd be grateful. I've done only very basic testing. <nalaginrut>mark_weaver: there're few tests for http-* client functions, only one for each, hmm... <nalaginrut>so the problem you fixed is happens to be the hole we ignored <nalaginrut>mark_weaver: this time you need a patch or you'll cover it? ;-P <mark_weaver>nalaginrut: if you'd like to contribute more tests for web/, that would be great! :) <mark_weaver>nalaginrut: note that the tests shouldn't talk to the actual network. the tests will have to be implemented where both the client and server are part of the test suite. <shanecelis>mark_weaver: Thanks, define-once worked like a charm! <mark_weaver>cky: thanks for looking into converting define-macros into modern hygienic macros :) <dje42>I have a question about Guile modules implemented in C + Scheme. <dje42>Python apparently has a convention where the C part is module _foo, <dje42>and the Python part is named foo and imports _foo. <dje42>Does Guile have a similar convention? <dje42>E.g. in gdb, the C part of the Python gdb module is named _gdb. <foeniks>signing up for guile-devel and guile-user on Wednesday -- no email since oO <mark_weaver>dje42: in Guile there's no such convention. If there's a module implemented in a mixture of C and Scheme, they both share the same module name. <dje42>thx. I wonder if there's some technical benefit to such a convention. <nalaginrut>mark_weaver: I think current web-client.test tests url from internet, do you suggest tests between inner serer & client <mark_weaver>Thanks for pointing out that the current web-client.test does network tests. I think we should fix that. <mark_weaver>first of all, I guess those tests will fail if any of those web pages change. that's not good. <nalaginrut>should I remove them all? and write new test just between inner server & client? <nalaginrut>oops, I realized there's no real HTTP server for inner server, which means there's no proper handler for that <mark_weaver>nalaginrut: wait, we don't need anything that fancy. <mark_weaver>for testing purposes that handler can be very simple. <mark_weaver>because it doesn't actually have to route, nor should it. <mark_weaver>it should verify that the request is what it should be, and send back a predetermined response. <mark_weaver>so each test would specify what request is expected, and what the response should be. <nalaginrut>alright, I see, I can rewrite the old tests based on predetermined handler <mark_weaver>first of all, are you sure that the existing test file actually uses the network? <nalaginrut>but for the bug you just fixed, how to test body is "" <nalaginrut>I think the current test is fetch from the url, then compare the HTML string <mark_weaver>don't assume it's going to talk over the network just because you see those URLs in there. <mark_weaver>it's passing the #:port keyword argument to 'http-get' etc. <mark_weaver>the port it's passing is a soft port, created by 'run-with-http-transcript'. <mark_weaver>so all the needed infrastructure already exists.. what's there is good. <mark_weaver>well, it's not not all good though.. the tests for 'http-post' and 'http-put' are not sending any body. <mark_weaver>so that's what needed.. maybe the other methods need to be tested better as well. <mark_weaver>but a good start would be to simply add a test for 'http-post' or 'http-put <mark_weaver>so I guess that requires some enhancement to 'check-transaction'. <mark_weaver>note that specifying a body of #f means "no body", which is not the same as "", which means "an empty body". <ArneBab_>you can test it with $ guile -L . → (use-modules (wisp))(display (wisp2lisp (call-with-input-file "wisp-guile.w" wisp-chunkreader))) <mark_weaver>yes, there's no inner server. just a simple soft port that expects an exact request stream, and then sends back a predetermined response stream. <nalaginrut>mark_weaver: maybe it's intended to avoid inner server? If we used inner server for that, the stuff won't be so complex <ArneBab_>(sidenote: the wisp translator still has some shortcomings in regards to the spec (linebreaks…), but it can translate itself and the example code) <mark_weaver>ArneBab_: don't compile to tree-il. Compile to scheme. <mark_weaver>and I guess the compiler will be the identity function, essentially, although it has to accept multiple arguments and return multiple values iirc <ArneBab_>so I would set #:compilers `((scheme . ,compile-scheme))? <mark_weaver>at some point, the #:printer could be something that prints wisp. <ArneBab_>nalaginrut: it’s not your mistake. I just copied the code you wrote for readable, and for that it’s correct, I think <nalaginrut>and I even told him no need to compile to tree-il <ArneBab_>I first had to understand that reader is a function which reads one expression from the inport and then returns. <mark_weaver>ArneBab_: so, I guess you want something like this: (define (compile-scheme x e opts) (values x e e)) <mark_weaver>and (define (decompile-scheme x e opts) (values x e)) <nalaginrut>though no one need guile-sweet now, it's an example for other guys... <nalaginrut>we lack some docs&examples for front-end on Guile <ArneBab_>mark_weaver: could we connect over that to look into the file together? <mark_weaver>ArneBab_: I've never successfully used it, so you'll have to walk me through the process. <ArneBab_>mark_weaver: do you have the port open (I’ll lookup the port in an instance) <ArneBab_>(I cannot open ports here, but if you cannot open it, I could use my homeserver… ) <ArneBab_>even if it only allows both of us to use rudel for cooperating with other people in future, then it’s worth the effort, I think. <ArneBab_>But I need to get firefox on my homeserver first, to be able to configure my router… <ArneBab_>(damn interfaces which do not support text-browsers…) <mark_weaver>ArneBab_: actually, I don't really want to work on this right now. <ArneBab_>then I’ll just get the basics for that in place and keep working on the wisp-parser here <mark_weaver>ArneBab_: I'd rather concentrate on getting wisp to work. <mark_weaver>I'm happy to help you with that, but for now I'd rather just use the existing tools that we're comfortable with, like paste sites. <mark_weaver>ArneBab_: another problem I see is that the module name is not right. it has to actually be (language wisp spec) <nalaginrut>hmm..the guile-sweet has bugs, but it no worthy to fix now <ArneBab_>mark_weaver: to do that, I’ll have to put it into the filepath language/wisp/spec.scm, right? <ArneBab_>mark_weaver: can I do that later, so I can keep working in the local setup here until it works? <mark_weaver>but it doesn't have to be in the same system directory that the core guile stuff is in. <mark_weaver>just set up a directory structure $DIR/language/wisp/spec.scm, and then put $DIR into %load-path <ArneBab_>and that’s for the file which holds the define-language? <mark_weaver>that's the only file you need, but of course you can also split things up if you want. <mark_weaver>ArneBab_: also, change the #:export (scheme) to #:export (wisp) <ArneBab_>The reader translates wisp to scheme! *first step done* <mark_weaver>ArneBab_: and trim down the #:use-module lines to what you're actually using. <ArneBab_>now I only need to change that to compile the scheme <ArneBab_>yepp: instead of defined functions it returns strings with the scheme-code <ArneBab_>Happy hacking with Wisp Scheme Syntax! To switch back, type `,L scheme'. <ArneBab_>$1 = "(define (hello)\\n \\"Hello World!\\")\\n\\n\\n" <ArneBab_>ah, so I have to add a scheme-parser to the reader <ArneBab_>is there a reader which will always read the full string or port it gets and return the sexps? <ArneBab_>wisp could have multiple sexps in a chunk… <mark_weaver>will 'wisp-chunkreader' ever read more than one top-level form? <ArneBab_>it could read the whole file if there aren’t multiple linebreaks (>2) in there. <mark_weaver>can you change the reader to read only one top-level form? <ArneBab_>(means: yes, I can, but it would be nasty…) <mark_weaver>well, there will be complications whenever one top-level form changes the current module. <mark_weaver>I don't understand why it would get nasty, based on what I know of wisp. can you help me understand? <ArneBab_>I have to do string-parsing and paren-parsing to avoid breaking the reading just because there were multiple linebreaks in a string and such. <ArneBab_>though I could check for new top-level datums (no indentation) <mark_weaver>the thing is, when you do a 'define-module', for instance, that changes the current module, which also changes the module in which future forms are macro-expanded. <ArneBab_>maybe it won’t hurt too much and I’m just burned from the python-shell taking inpot the wrong way… <mark_weaver>but if the 'define-module' and several forms that follow are wrapped within a single 'begin', then it breaks that behavior. <ArneBab_>mark_weaver: Actually I think it would be ideal to take what wisp outputs and parse that with a regular reader which could extract several sexps <ArneBab_>just like when someone enters several sexps in one line <ArneBab_>not yet: it just reads the file and preprocesses it to scheme <mark_weaver>it's hard for me to see how the wisp reader can be correct without using Guile's 'read', or having a full Scheme reader built in. <mark_weaver>the problem is, how do you know whether you are in a comment? in a string literal? <ArneBab_>mark_weaver: I only need to detect brackets, strings and those pesky #\\… forms (chars) <ArneBab_>I parse it by hand, because I cannot just defer to scheme <ArneBab_>to know where to place the parens, I have to detect comments <mark_weaver>it's not obvious to me why you can't just use 'read'. <mark_weaver>and I guess you need to be able to read reader directives as well. <ArneBab_>because the whitespace is only relevant when I’m not in a string nor in parens <mark_weaver>and in fact, whenever you detect that something is not a wisp form or a comment, just call 'read'. <ArneBab_>I think with that I could not use the preprocessor as standalone: ./wisp.scm wisp-code.w > lisp-code.scm <mark_weaver>here's what I think is missing: a way to read (and process) a reader directive (starting with "#!"), without proceeding to read the following datum. <ArneBab_>that’s definitely still missing and it is not the only thing <mark_weaver>ArneBab_: that's true, but I see no way to do the job properly without using Guile's read. part of the problem is that you'd have to duplicate things like Guile array syntax, which is complex and hairy.. but even worse, what about reader extensions that other people add? <mark_weaver>ArneBab_: What else do you need from core Guile to implement this nicely? <mark_weaver>I'd like to make sure you (and SRFI-110) have what you need to do this. <ArneBab_>Ideally I’d like to use wisp to preprocess the input, then defer the parsing of sexps to the guile reader <mark_weaver>my point is that you can't properly preprocess the input without the help of the full Guile reader. <mark_weaver>you need to be able to parse every datum supported by Guile's reader, including any extensions that others have added. <ArneBab_>I can ignore most of the special forms in scheme <ArneBab_>essentially all I have to worry about are things which affect paren-structure <ArneBab_>if they are not function calls, you just prefix them in wisp with . <mark_weaver>and regarding paren structure: any reader extension could add syntax that includes unmatches parentheses. <mark_weaver>for example, I know of someone who's using a reader extension to implement Python-style here documents. <mark_weaver>so that right there means arbitrary text as a string literal that you somehow have to understand how to find the end of. <ArneBab_>triple-quote would still work, double-quote would be a problem. <mark_weaver>anyway, the point is, you simply can't do this job properly without integrating with the Guile reader to some extent. <ArneBab_>is there a way to just get the string for a special form (string-literal or otherwise) from the reader? <ArneBab_>what I’m doing at the moment is first escaping all linebreaks inside parens and strings, then splitting the lines into indentation, content and comment, and then adding parens to the content. <ArneBab_>If there were a way to ask guile “please give me a string of the datum following this character”, the I could simply escape all linebreaks inside this. <ArneBab_>linebreaks and comments inside lisp-forms (parens, string-literals) are the only really hairy problem. <ArneBab_>escape: \\n → \\\\LINE_BREAK_N, unesape: \\\\LINE_BREAK_N → \\n <ArneBab_>(actually \\LINE_BREAK_N, \\\\ is in the strings…) <mark_weaver>well, that's not reliable, but I suppose in practice it will rarely fail (except maybe on the wisp code itself :) <ArneBab_>the wisp-code uses string-append "\\\\LINE_" "BREAK_N" to avoid that ;) <mark_weaver>what happens in \\LINE_BREAK_N is already in the original code? <mark_weaver>I'd do something like: (1) read whitespace and comments until you reach something real. <mark_weaver>(2) if it's a ':' followed by whitespace, handle it apprpriately. <mark_weaver>(3) otherwise take note of the current column (which is kept track of by guile on the port), and then call guile's 'read' to read the top-level datum. <mark_weaver>and where appropriate, take the datums returned by 'read' and build them up into lists. <mark_weaver>I suppose there'd also be some logic in the 'read whitespace' when it encounters two or more newlines in a row. <mark_weaver>I only vaguely remember the rules for wisp, so maybe I'm missing a few details. <ArneBab_>for (2) you have to know where the line ends. For (3) you need to add a paren at the end of the top-level datum. And all kinds of other hairy stuff like inline " : " to add an additional level of parens which only extends to the end of the line… <ArneBab_>but I do not claim that my parser is perfect <ArneBab_>and it doesn’t yet handle all of wisp correctly. <ArneBab_>(is there a way to add an EXPERIMENTAL USE AT YOUR OWN RISK flag to a language?) <ArneBab_><mark_weaver> ArneBab_: What else do you need from core Guile to implement this nicely? — ^ this ☺ <nalaginrut>mark_weaver: I realized it didn't test #:body "", the request body never pass in with the keyword, and simply pass #:body request-body causes other test failed <nalaginrut>seems no need to stick to check-transaction for the test <ArneBab_>mark_weaver: could I just create a port in the wisp-module and use the wisp-preprocessor to fill that, letting the guile parser read the resulting scheme-code? <ArneBab_>mark_weaver: should I create a small testsuite for wisp-parsers? <mark_weaver>ArneBab_: is 's' is the string returned by your preprocessor, you can just do (call-with-input-string s read) <ArneBab_>does that work when there are mutliple toplevel sexps inside s? <mark_weaver>for that, I guess you'll have to do (call-with-input-string s (lambda (port) ...)) <ArneBab_>mark_weaver: then I’ll try to turn my examples into a testsuite. <mark_weaver>where ... has a loop that reads until it reaches EOF, and wraps it all within a 'begin'... <mark_weaver>but again, that's going to cause problems with 'define-module'.. and it will also fail if the user redefined 'begin' to be something different. <ArneBab_>mark_weaver: then I have all the problems with the begin again <nalaginrut>mark_weaver: I have to write another checker for the client, since check-transaction only check the response, but we have to check if the request is valid <ArneBab_>I thought about only invoking the wisp-parser if an internal port is empty <mark_weaver>but I guess it would be good to get something basically working for now. <mark_weaver>(even though I think this is the wrong approach for a proper wisp reader) <mark_weaver>nalaginrut: in that case, 'check-transaction' should be improved to check the request too. <ArneBab_>(if (and (not (equal? #\\eof (char-peek port)) (equal? #\\eof (char-peek internal-port))) (wisp-parser port) (read internal-port)) *ArneBab_ just wrote that from memory, hopefully it’s not too broken… <ArneBab_>I thought that that would be equivalent to a user calling (display 1)(newline) <mark_weaver>ArneBab_: I don't even understand what that's trying to do. <ArneBab_>mark_weaver: I’ll try to make it clearer <mark_weaver>ArneBab_: the way to test for eof is to use 'eof-object?' <ArneBab_>mark_weaver: that’s what I do in the code, I just wasn’t sure about the name… <ArneBab_>mark_weaver: it tries to read one wisp-chunk from the port, then push the resulting scheme into internal-port. Then tell the reader to read all sexps from the internal port until it’s empty. <mark_weaver>ah, so 'internal-port' is essentially a pipe with 'wisp-parser' pushing on the other end of the pipe? <mark_weaver>well, if 'wisp-parse' produces more than one sexp at a time, then the pipe will fill up and you have a deadlock. <ArneBab_>does that also happen, if wisp-parse only pushes at the other end if the pipe is empty? <mark_weaver>if wisp-parser can ever output less than one sexp, then you're also in trouble. <ArneBab_>if it outputs less than one sexp, then that’s a bug :) <mark_weaver>you'd really need these pipeline stages to be in different threads. <ArneBab_>hm, wisp-parse could output several lines with only comments in them… those would have no sexp… <ArneBab_>mark_weaver: so it would not suffice to evoke wisp-parse if the pipe is empty - followed by evoking the reader on the pipe? <mark_weaver>hmm, maybe you could use the environments passed around to compile-scheme to keep track of the pending expressions. <mark_weaver>well, the deeper problem you have is that you don't have a way to keep state in your reader. <mark_weaver>so you don't even have a place to store the 'internal-port'. <mark_weaver>well, I suppose there are ways to hack it, but not nicely. <mark_weaver>the compilers are where there is state that you can pass around.. namely the environments. <mark_weaver>one of those returned environments will be passed to the next compiler down, scheme in this case. (and the scheme compiler expects that to be a module) <mark_weaver>and the other returned environment will be passed to the next call to 'compile-scheme' when compiling a file. <mark_weaver>I don't know how well all of this has been tested though... I'm not sure the latter environment is handled properly by the repl. <mark_weaver>I suppose one way to hack it for now would be to create an object property and associate it with the port you're reading from. <mark_weaver>that object property could contain "pending top-level forms"... so the reader would pop off of that list if it's not null, otherwise it would call the wisp reader again. <mark_weaver>or the object property could contain a string port... yes, that might be easier. <ArneBab_>can’t I just define a variable which holds a soft-port? <nalaginrut>mark_weaver: I found run-with-http-transaction tested request, but the problem is the test-case didn't cover #:body "", and I realized open a soft-port with null body is different from #:body "", according to the test result <mark_weaver>there's actually no reason to make a soft port here. it would be a needless complication. <nalaginrut>with #:body "", I found HEAD -> GET, POST->GET in old code <nalaginrut>yes, I agreed soft-port is not a good design here <mark_weaver>in your spec file, define a global variable (define wisp-pending-port (make-object-property)) <mark_weaver>so that'll let you do (set! (wisp-pending-port port) ...) <mark_weaver>and then later look it up with (wisp-pending-port port) <mark_weaver>basically, it's like being able to add a new custom field of your own to any object. <mark_weaver>the way it actually works is using a weak-key hash table.. <mark_weaver>but anyway, this lets you associate a wisp-pending-port to the real port. <mark_weaver>(wisp-pending-port port) will return #f by default, if it's never been set for that port. <mark_weaver>so, in your reader, you do this: first call (wisp-pending-port port) to see if there's any pending data (this is analogous to your 'internal-port' pipe) <mark_weaver>if there's pending data, then use 'read' to read from the pending port. <mark_weaver>if there's no pending data, or if 'read' on the pending port found EOF, then call the wisp reader. <mark_weaver>and then (set! (wisp-pending-port port) (open-input-string s)) <mark_weaver>where 's' is the string that was returned by the wisp preprocessor. <ArneBab_>ah, so that is what I thought about doing with a soft-port <mark_weaver>and then loop I guess.. so it reads from the pending port and returns a datum. <mark_weaver>obviously, you have to be prepared for (wisp-pending-port port) to return #f, which it will the first time. <ArneBab_>(though I don’t yet really understand it…) <mark_weaver>and then you can just do #:reader read-one-wisp-sexp <mark_weaver>ArneBab_: is there a way to read a top-level datum that's not a list, in wisp? <mark_weaver>also: what do you do if the first non-whitespace on a line is a comment? <ArneBab_>then the whole line is a comment and gets ignored for the sake of indentation processing <ArneBab_>the only way to define a line as only indentation is use ":" as the only non-whitespace character on the line. <mark_weaver>well, when if the whole line isn't a comment? what if the comment is followed by non-comment? <mark_weaver>do you have a plan for how to handle that? or is it as yet undecided? <ArneBab_>it is as yet undecided, because I don’t know enough about scheme to see all implications of a decision. <mark_weaver>well, I need to sleep now. anyway, I'm glad it's working :) <ArneBab_>thank you very much for helping me to get this to work! *ArneBab_ can now test on the REPL with wisp! *happy* <sneek>Chaos`Eternal, you have 1 message. <sneek>Chaos`Eternal, cky says: As I understand it, you can actually import non-exported bindings from a module. Whether that will continue to work, that's a different question. <ArneBab_>nalaginrut: do you have a website I can link to in the article about the REPL - and does Mark have one? *ArneBab_ thought he read quite a few posts from him *ArneBab_ curses his horrible person-memory… <ArneBab_>For guile I just linked to gnu.org/s/guile <nalaginrut>I misunderstand, do you need an article on REPL? or you need a site to put article? <ArneBab_>I need a link I can use to reference you :) („here’s his personal site“) <ArneBab_>nalaginrut: essentially it’s a kind of thank you and a kind of citation (referencing contributors). <nalaginrut>ArneBab_: alright, I haven't done such an article <ArneBab_>riting front-ends would also be nice, yes <ArneBab_>nalaginrut: but actually I just wanted to link to something describing you two as people :) <ijp>shanecelis: the amusing thing (to me) about your http client bug, is that if you do it in a browser, it'll increase by more than one, because of requests for things like the thumbnail <ijp>strace indicates the client is still reading even though it should have all the info it needs <ijp>read(13, "HTTP/1.1 200 OK\\r\\nContent-Length: 15\\r\\nContent-Type: text/plain;charset=utf-8\\r\\n\\r\\nHello World! 22", 4096) = 94 <ijp>read(13, 0xa1ec000, 4096) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <ijp>the guile code gets the response just fine, but blocks when reading the body <ijp>read-response-body does a get-bytevector-all <ijp>when it should only be reading a certain amount of bytes when the content length header is available <ijp>I can be sloppy and just use get-bytevector-n because we have a different procedure that does the validating <ijp>hmm, but we don't expose that <ijp>actually, that doesn't seem to be enough, hmm <ijp>maybe it's caused under the hood by the get-bytevector-* procedures <ijp>well, right now I'm tracking down the bug shanecelis brought up on the tracker <ft>civodul: Hai! wrt. your mail to the geiser list: isn't the author asking for "-C DIRECTORY like -L, but for compiled files"? <ijp>which seems to be blocking unnecessarily <civodul>ft: oh you're right, i had forgotten about that one <ijp>is that the gimp one <ArneBab_>is there a chance to get my string-replace-substring into guile? <ArneBab_>essentially that post says “we need better libraries, and we can have them because scheme has enough flexibility for that” <ijp>doubtlessly, the author has not came up with such a library <ijp>hmm, what I don't get is why this bug is only showing up when it's a local guile server <ijp>it has to be something in the get-bytevector-* procecures though <ArneBab_>ijp: rather he did not *write* that library. *ArneBab_ thinks that library design is pretty hard: find the balance between doing things the standard way and doing them the simple way… <ijp>it is hard, but blogging about it isn't going to make it easier <ArneBab_>I did not say so, but he has an actual point. Therefore my question: would (string-replace-substring s substring replacement) be a fit for guile? <ijp>I'm sure it's been reinvented often enough, I have no obvious objection to such a procedure <ArneBab_>then I’ll try to make it a bit more efficient and send it to the list <ijp>strictly, it's subsumed by regex replacement, but (ice-9 regex) can die in a fire <ijp>hmm scm_c_read_unlocked <ArneBab_>,time did not work with wisp. But I could just use ,L scheme and run the command in scheme! <ArneBab_>ijp: could you look at the substring code to see whether its quality suffices to send to devel? <davexunit>the article made me so happy, and then the comments made me so sad <ArneBab_>davexunit: actually I agree with the readability argument. That’s why I joined with project readable and created wisp… <ArneBab_>the technology behind guile is wonderful. <ijp>first things first, indentation is non-standard <ijp>(not (equal? addindex #f)) = addindex <ijp>I take it this only works when length of substring = length of replacement <davexunit>ArneBab_: the comments boil down to: just use javascript <davexunit>which is unfortunate when the article addresses that point. <ijp>you seem to be under some misapprehension that people read the post they comment on <ijp>the likelihood is inversely proportional to the number of comments <ijp>ArneBab_: perhaps call it string-replace-all or similar <ijp>I'm not sure how costly string-replace is (or that it matters much), but one other way to do it is to build up a list of indices to replace at, and then do a bunch of string-copy!'s at the end <ijp>.oO(did you hear that right? ijp telling someone to mutate a string?) <ijp>it's conventional to SHOUTY CAPS the arguments in the docstring *davexunit just learned that a week or so ago. <ijp>other than that, maybe use two internal defines instead of two nested lets, and I'd tweak some of the names <ArneBab_>davexunit: just ignore them. As soon as an article gets popular, people chime in to shout it down. <ArneBab_>davexunit: the points in the article were really good. <ArneBab_>ijp: at least string-contains was much more costly than string-replace. <ijp>I suppose the argument against internal defines, is that the current fixing letrec treats them a little dumb <ijp>doesn't string-contains take an index to start at, argument? <ijp>that would make more sense than taking a substring <ijp>should remove an addition too ***micro` is now known as Guest89641
<nalaginrut>ArneBab_: have you tried string-substitute/global ? <ijp>there is a regexp-substitute/global but no string-substitute/global <ijp>and I'm pretty sure he was aware of it <ijp>since I mentioned there was a regex variant 2 hours ago <nalaginrut>the problem of our current string maybe non-ascii code <nalaginrut>I wonder if I have energy for thinking and hacking <ijp>do we have a procedure that does the opposite of module-use! ? <ijp>okay, that wasn't so hard to write <ijp>remove the module from the uses list, nuke the obarray, rebuild <ijp>nalaginrut: I explicitly do not want to reload <ijp>I want to unuse[sic] a module <ijp>it calls the module observers, which repopulate the obarray AFAICT <ijp>the documentation of module procedures is weird <ijp>it's not like they aren't documented, you can read boot-9 and see that, but for some reason they haven't made it to the manual or docstrings <ijp>and at least some of them are public knowledge anyway, because of tricks like reexporting a module <add^_>ah so that's what your using it for? *ijpbot loads its hose and drenches add^_ <add^_>Thanks ijpbot, I needed that :-) <ijp>not only that, but it has its uses <add^_>I was thinking about that a while ago, can't remember for what though.. <ijp>I think I added at least 70% of them <ijp>actually, that list is no where near complete <ijp>pretty sure there's like twice as much <add^_>Sneek just spammed me privmsg XD <mark_weaver>ijp: I'm not sure what you want unexport for, but it might not work quite as you intend. for one thing, procedures that use imported variables will cache those variables internally, I think. <mark_weaver>there may be other problems as well. overall, there's a general assumption that variables within a module never go away, or even change. <mark_weaver>(by change I mean that the variable object itself is the same, even if its value may change) <ijp>cunning-bot, here ijpbot, uses an empty module for commands <ijp>this is a way to bulk-unload commands <mark_weaver>that was confusing, but hopefully you get the gist :) <ijp>I have no intention of using it on "real" guile modules <mark_weaver>also, using such internal module procedures might well break on future versions of guile, but I guess you know that already. <ijp>mark_weaver: I do expect to have to rewrite this eventually, but it is partially an experiment to see how far I can push modules <ijp>is there a way to loop over all the symbols defined in a module _AND_ in the symbols it imports <ijp>module-map only does the first one <ijp>I suppose I can loop over the uses-list myself <mark_weaver>I wonder how things like #:replace exports are dealt with. <ijp>hmm, I could creativly abuse module-search <ijp>which inexplicably has an extra value <mark_weaver>e.g. your module uses both (guile) and (ice-9 curried-definitions). How to make sure you get the 'define' from the latter and not the former. <mark_weaver>but maybe I'm overthinking this, since this is just a hack for the irc bot :) <ijp>it looks like replacements are added to the module, where as regular imports aren't (they get looked up in the uses list) <ijpbot>ijp: help, join, lets, botsnack, shoot, privmsg, flay, eval, ping, define, source, say-hello, commands, auth, quit, revoke, debug, log <ijpbot>You need to be my master to do this "mark_weaver" <ijp>special privilege :) <ijpbot>New authentication string created. Check stdout. <ijp>depends, can you see my stdout? <add^_>I have to check on your comput.. <ijp>because that would be bad in any case <ijp>it probably shouldn't list the admin commands unless you are admin though <mark_weaver>ijp: so if I stole your nick temporarily while you were offline, I could get it to eval for me? <ijp>if I went offline while still his master, then yes <ijp>but I know how to fix that <mark_weaver>if I were you, I'd disable that functionality altogether, until you have a proper sandbox for the eval. <ijp>right now, I make sure to only run him when I'm here <ijp>but removing it is just a one liner <mark_weaver>it means that anyone in control of the irc server, or able to forge a TCP packet from the IRC server, can run arbitrary code on your machine. <ijp>well, at this moment in time, no <mark_weaver>well, I guess you could largely mitigate the problem by running the bot as an unprivileged user on your machine. <ijp>I've been spending a lot of time thinking about it, but I still have no good answer for ((lambda (x) (x x)) (lambda (x) (x x))) <ijp>I considered spawning a separate guile, with a timer to kill it, but it's not very satisfactory <mark_weaver>guile doesn't have internal resource controls. so yeah, you need to run a subprocess with rlimits. <mark_weaver>which personally I find quite reasonable. processes are specifically made for isolating and limiting resources. <ijp>the evil irc server is a concern, but it's not one you can avoid if you want to be able to control the bot over irc <ijp>but if you remove eval, at worst, it's a puppet <mark_weaver>ijp: you can't avoid an evil irc server being able to act as administrator of your bot, no. However, you *can* prevent it from doing anything that ijp can do on your machine. <mark_weaver>actually, even the admin stuff could be handled by using OTR when talking to your bot as admin, I guess. <shanecelis>Anyone know of a scheme module that has a list with cursor (basically, it remembers where I'm at, and I can add and insert at that point)? <ijp>a gap buffer, or a zipper? <mark_weaver>shanecelis: I've never looked at it, but maybe (ice-9 gap-buffer) <mark_weaver>one possibility is simply to keep two lists: the elements before the cursor (in reverse order), and the elements after the cursor. <shanecelis>mark_weaver: linear, very simple. I just want to have a minibuffer history object for Emacsy. Right now I have a list and an index, and I just want to group them. <shanecelis>ijp: Where can I find a zipper implementation for scheme? <ijp>rotty has one in spells <ijp>but a zipper is more a pattern than a specific data structure <ijp>what mark described is essentially a list zipper <shanecelis>Yeah, I think I'll go with that. Thanks. I always feel better informed by asking #guile. You guys are great! <ijp>I might just purloin the zipper in spells for pfds, and the srfi 101 ralists while I'm at it <mark_weaver>shanecelis: btw, at some point (but not right now), I'd like to talk with you about maybe making a new language for your literate programming language, which will be more robust in many ways, and allow you to avoid making so many reader extensions that have global consequences on the entire guile process. <mark_weaver>by "new language", I mean implement it as a language in guile, which would allow you to create your own custom reader, and essentially preprocess your input code to standard scheme. <ijp>the only concern I have with new languages is module imports <shanecelis>mark_weaver: Hmm... new syntax or just new implementation? <mark_weaver>well, basically it would be a compiler from noweb to scheme. <mark_weaver>but "compiler" is a strong word for this, of course. <mark_weaver>really, the compiler would be an identity function, and all you really care about is the reader. <shanecelis>mark_weaver: So new implementation. Hmm... that'd be cool. I wouldn't have to rely on the build system to generate all the .scm files. <mark_weaver>in practice, it's pretty simple, and the wisp code shows the way. <shanecelis>Awesome. I had thought about it, but I wasn't sure if adding new languages to guile was available for users. <mark_weaver>it is. tree-il is still evolving a bit, but in your case you'd just need to compile to scheme. <mark_weaver>all the reader extensions make me nervous. remember they affect every user of read in the system. <mark_weaver>and if they conflict with an extension someone else has written, someone loses :-/ <shanecelis>Sounds good. I think that would definitely be preferable. <ijp>the list of replacement indices approach? <mark_weaver>well, I accumulate a list of strings to concatenate at the end. <mark_weaver>the list consists of substrings of the original string and the replacement string. ***ijp` is now known as supremeleaderijp
<supremeleaderijp><oakaz> some open source communities make me feel like I live in North korea <add^_>I haven't been there for ages ***supremeleaderijp is now known as ijp
***ijp` is now known as ijp
<add^_>I need another project to work on :-/ *add^_ has been working with inpure/common lisp for a while, now he needs his scheme-dose.. <stis>yep! Or more corect stefan israelsson tampe <ijp>hmm, I have quite a few suggestions for emacs projects, but I'm low on scheme suggestsions <add^_>So your Swedish? Or at least live in Sweden? <ijp>things like flymisspell-mode, sponsored recommendations for ido, erc hunter2 protection <add^_>Or was that a suggestion for me to work on? xD <ijp>those were examples of emacs project ideas I have noted down <add^_>What is the "erc hunter2 protection" supposed to be? <ijp>you're familiar with the famous hunter2 log from bash.org? <stis>add_ I live in Västerås! <add^_>I'd say something in Swedish, but I don't think that would be approriate for this channel :-P *add^_ doesn't mean talking inappropriate, he means that talking in something else than scheme or english would be inappropriate. <stis>It's good to stick to the subject! But a few sentences of any language would not hurt. <add^_>I'm trying to come up with a project in Scheme, I've been trying to maintain a CL game project for a while and to say the least, it's not very gratifying anymore. <add^_>Is that even a proper sentence? <add^_>I just got really confused, it apparently is Friday here too. (Thought it was more like Wednesday or something) <stis>add^_: the sentence is fine enough, my recomendation is to try to explore scheme, and have fun! <add^_>I've done my fair share of exploring in Scheme, it's not new to me. <add^_>But I can't really come up with any ideas. <ijp>the other day I was suggesting people try writing a guile virus <add^_>I can't say *nothing* is new to me, but still. <ijp>add^_: just to explore quines <add^_>ijp: LOL at the bash.org thingy also (forgot to read after clicking) <stis>add: there are many useful things that are missing, what are your good at math physics CS games? <add^_>It's not that I'm not good at it, I'm just uneducated in it. <stis>Are you taking a degree? <add^_>I thought that was how everyone (should) work.. <stis>I cannot say what suits you, but I find a lot of inspiration ion my work for what I want to do with guile. <add^_>I don't really have a use for anything, I mostly do stuff because it's fun. :-/ <add^_>So the "need" that creates ideas isn't really there.. <stis>Yea, but take xml schemas for example. I know that an appropriate tool in scheme is unbeatable for authooring these documents <stis>So I spend time designing a schem interface for this exersice, I learn and perhaps others can use it as well <stis>In all an inspiration starting from my work. <stis>Another example is that we work quite a lot with control theory e.g. designing PID loops or even more advanced stuff. <stis>So I sat down and wrote a Moon rocket controller e.g. the thrust beeing on and off using logic programming and optimization <stis>quite some fun, also here I can test my logic programming stuff, learn and have fun! <stis>Actually after writing a prolog language for guile, I will takle on to introduce that as a nice example for guile-log <stis>trying to introduce some graphics and so on. <stis>So my advice is to try to spin the fun scheme life together with work and both will benefit! <stis>Happy Friday dsmith-work: <ArneBab_>mark_weaver: it’s cool to see new ideas spring off wisp! (re noweb). I use noweb via org-mode… <mark_weaver>ArneBab_: did you see my improved string-replace-substring? it's about 80 times faster on my machine (for the test you gave). 20 milliseconds vs 1.69 seconds. <ArneBab_>mark_weaver: yes, I saw it. I just wasn’t finished with the backlog yet- and did not get to test it. <ArneBab_>mark_weaver: interestingly the split-join approach is exactly what I would have used in python :) <ArneBab_>mark_weaver: I did not yet get to create the full wisp test-suite by the way, but I have some tests at hand. <mark_weaver>ArneBab_: how's the REPL working for you so far? have you noticed any problems? <add^_>Is there any problems on 32bit gnu/linux with guile 2.2 ? <ArneBab_>what’s the difference between define and define*? <mark_weaver>add^_: guile 2.2 doesn't exist yet :) if you mean git master, then it should work fine. <ArneBab_>mark_weaver: the repl mostly works well. <ijp>define* allows #:key and #:optional (is that right?) and #:rest <add^_>mark_weaver: yeah, I thought that was what you called it :-P <ArneBab_>mark_weaver: one problem I had is that ,time <something> did not work. <mark_weaver>ArneBab_: 'define*' supports #:optional #:key and #:rest <add^_>mark_weaver: thanks for the quick answer :-) <mark_weaver>add^_: it's possible that slipped through my lips at some point :) <add^_>Do you recommend trying it out? <mark_weaver>add^_: personally, I would stick to stable-2.0 for "make install", but guile-master is fine to try also. <add^_>Maybe I should wait for that instead. :-) <mark_weaver>the snapshots are made automatically every time we change anything. <mark_weaver>so the snapshots should basically always be up to date. <mark_weaver>the stable releases are based on the stable-2.0 git. now *that* I can recommend installing basically anytime. git stable-2.0 will generally be better than the most recent release. <dsmith-work>sneek: later tell mark_weaver, add^_ says "happy hacking*" <ArneBab_>wow, the speed of marks replace-substring is awesome! <add^_>ArneBab_: I think it'll give you help in a private message <add^_>I guess that's to not accidentally get kicked for flooding <ArneBab_>sneek: later tell mark_weaver The performance is awesome! Thanks! <ArneBab_>sneek: later tell mark_weaver: another problem I noticed with the repl is that readline does not preserve the newlines. <add^_>dsmith-work: does sneek understand that ":" after the nick? <add^_>I meant the one after mark_weaver in ArneBab_ 's message <ijp>sneek: later tell ijp: foo <sneek>Welcome back ijp, you have 1 message. *ijp whacks add^_ with an empiricism stick <ijp>it's for your own good <add^_>Really? Can you hit people for their own good? <ijp>have I ever lied to you? <ijp>actually I have, probably dozens of times *add^_ had to look up how to spell that, and is still not sure if it's correct <taylanub>add^_: You can spell-check in Emacs with M-$. <taylanub>M-x load-library RET flyspell RET might do it. <ijp>aidalgol: I have a COOL NEW FEATURE(tm) <ijp>hold on, I'll demonstrate <ijpbot>test definition: '''chiefly British''' cupel. <taylanub>add^_: I don't know then .. maybe one needs to have ispell installed in the OS, and/or compile Emacs with it, or something .. it "just works" for me. <ijpbot>test definition: '''chiefly British''' cupel. <ijp>you can now unload plugins! <add^_>What's the difference between the second ijpbot: define test and the third? <ijp>I reloaded the plugin <ijp>aidalgol: you could, by doing it one function at a time *ijpbot blows a raspberry <ijp`>aidalgol: if you're up for it, can you add a way to check for nick changes and quits ***ijp` is now known as ijp
<ijp>and that one needs fixed too <ijp>ijpbot: define perspicacity <ijpbot>perspicacity definition: of acute mental vision or discernment. <ijpbot>Unbound variable: remove-plugin! <ijp>ijpbot: define vivacious <ijp>ijpbot: define vivacious <ijpbot>vivacious definition: lively in temper, conduct, or spirit. <mark_weaver>civodul: nice bug you found in scm_c_read. you should use 'c_strcasecmp' though. <sneek>Welcome back mark_weaver, you have 3 messages. <sneek>mark_weaver, dsmith-work says: add^_ says "happy hacking*" <sneek>mark_weaver, ArneBab_ says: The performance is awesome! Thanks! <sneek>mark_weaver, ArneBab_ says: another problem I noticed with the repl is that readline does not preserve the newlines. <mark_weaver>the redundant representation of ->encoding is suboptimal. <civodul>mark_weaver: regarding the bug, i wasn't event sure it's the right fix