IRC channel logs


back to list of logs

<mark_weaver>ijp: I just pushed a fix for that.
<mark_weaver>(to stable-2.0)
<aidalgol>ijpbot: Yo, what up?
<ijpbot>No such command: Yo,
*aidalgol prods ijp.
<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>Also, should we ditch the hook thing?
<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
<aidalgol>snarfing as in...?
<ijp>you'll see
<ijp>and you'll hate me for it
<ijp>I've been pondering on committing a 'commands' function; fbs says I shouldn't
<aidalgol>Oh, fds
<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
<aidalgol>Oh, you mean a commands *command*.
<aidalgol>Right, where's this snarfing snarfery?
<aidalgol>What's a corpus?
<ijp>a fancy name for a vector of strings
<ijp>ijpbot: lets
<ijpbot>let's not
<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>it is
<ijp>ijpbot: lets
<ijpbot>let's not
<aidalgol>So why is snarfing necessary?
<ijp>let's $something_stupid
<ijp>ijpbot: lets
<ijpbot>let's $something_stupid
<ijp>that's why
<aidalgol>What just happened?
<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
<aidalgol>Try one now.
<aidalgol>See what it gives us.
<aidalgol>SHOOT ME!
*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
<aidalgol>For erc-shoot?
<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>I've heard of fingertrees...
*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
<ijp>(modulo eqv?)
<aidalgol>Does that mean you have to use monads?
<aidalgol>didn't think so
<aidalgol>In your opinion, what is the best way to get a good understanding of FP?
<aidalgol>Learn Haskell?
*aidalgol ducks.
<ijp>actually, I do have a branch in which I rewrite the fingertrees code to use a reader monad
<aidalgol>OOC, do you do racket?
<ijp>they have a great macro stepper
<aidalgol>Emacs needs that.
<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 need to actually go through SICP.
*aidalgol kicks himself.
<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
<aidalgol>pre-hook and post-hook, then?
<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>Here's the macro
<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.
<mark_weaver>shanecelis: forget that... use 'define-once'
<nalaginrut>morning guilers~
<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
<mark_weaver>or at least based it on that.
<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>and I think why not just add actors too
<nalaginrut>that's why I'm thinking actor-model at present
<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?
<nalaginrut>it has to be intergrated with guile-core?
<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>since it could be changed
<nalaginrut>mark_weaver: so how to avoid read block?
<nalaginrut>I think modify core for that is hard
<nalaginrut>maybe a better way is watchdog, break the thread and schedule it, then call next
<nalaginrut>but I didn't find a proper way for watchdog
<nalaginrut>I can break a thread in certain seconds with SIGALARM, but I can't catch the delimited-continuation in alarm signal action function
<nalaginrut>the continuation is in the handler context
<nalaginrut>not the thread I broke
<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
<mark_weaver>I agree
<nalaginrut>mark_weaver: I think there's an easy way to handle 'read'
<mark_weaver>what's your idea?
<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.
<nalaginrut>I mean use epoll under edge-triger mode
<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.
<nalaginrut>what's your idea?
<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.
<mark_weaver>We should do this job. It's on my TODO list :-)
<nalaginrut>I have a question, is it possible to provide non-blocking when users try poll/select?
<nalaginrut>IMO, only epoll/kqueue provide proper non-block
<mark_weaver>yes: after poll/select indicates that at least one byte is ready on a port, then use 'get-bytevector-some'.
<nalaginrut>then how can you choose the size?
<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.
<nalaginrut>so if there's no byte, it's blocked?
<nalaginrut>oh, I asked a stupid question
<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
<nalaginrut>epoll is the best thing for that
<nalaginrut>I mean epoll on edge-triger
<nalaginrut>ah~nice to know get-bytevector-some
<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>fortunately Artanis based on 2.0.9
<nalaginrut>epoll is not a problem to provide I think
<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
<nalaginrut>however, mine is so long too
<nalaginrut>I can imagine what's going on...
<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
<nalaginrut>oh, I don't mean "they suck so we suck too"
<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>I saw this page
<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.
<nalaginrut>it's referenced
<mark_weaver>there are several ways around it.
<mark_weaver>you don't need asynchronous I/O. You can do it with select/poll/epoll.
<nalaginrut>yes, aio is another way
<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.
<nalaginrut>I have to try it I think
<nalaginrut>wait, but my original question is not block
<nalaginrut>the original question is the scheduler..
<nalaginrut>mark_weaver: BTW, client is OK now?
<mark_weaver>nalaginrut: in current git, I fixed all the problems I know of in both client and server.
<nalaginrut>thanks for the work
<mark_weaver>it now sends Content-Length even if the body is empty.
<mark_weaver>you're welcome :)
<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>alright, I'm building it
<nalaginrut>np ;-P
<nalaginrut>mark_weaver: there're few tests for http-* client functions, only one for each, hmm...
<mark_weaver>yes, it would be great to have more tests.
<nalaginrut>and no test for request body
<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
*nalaginrut go for lunch
<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.
<mark_weaver>i.e. two threads talking to each other.
<mark_weaver>I just merged stable-2.0 into master.
<shanecelis>mark_weaver: Thanks, define-once worked like a charm!
<mark_weaver>shanecelis: :)
<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.
<nalaginrut>I don't remember there's such convention
<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>nalaginrut: yes
<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?
<mark_weaver>that's really terrible.
<mark_weaver>nalaginrut: that would be much appreciated!
<nalaginrut>oops, I realized there's no real HTTP server for inner server, which means there's no proper handler for that
<nalaginrut>although I can borrow something from artanis...
<mark_weaver>nalaginrut: wait, we don't need anything that fancy.
<mark_weaver>nalaginrut: what about just using (web server) ?
<nalaginrut>but we have to specify handler in 'run-server'
<nalaginrut>there's no proper given handler
<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.
<mark_weaver>or something like that.
<nalaginrut>alright, I see, I can rewrite the old tests based on predetermined handler
<nalaginrut>rather than depends on url on internet
<mark_weaver>first of all, are you sure that the existing test file actually uses the network?
<mark_weaver>and not using some inner simulator or something?
<mark_weaver>(I haven't looked)
<nalaginrut>but for the bug you just fixed, how to test body is ""
<nalaginrut> "GET" "" ...
<nalaginrut>I think the current test is fetch from the url, then compare the HTML string
<mark_weaver>and what does 'run-with-http-transcript' do?
<mark_weaver>don't assume it's going to talk over the network just because you see those URLs in there.
<nalaginrut>I think it calls http-get to fetch the page
<nalaginrut>or http-*
<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 the soft port acts like the server.
<mark_weaver>so all the needed infrastructure already exists.. what's there is good.
<nalaginrut>IMO, it seems tested an echo like server
<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> with a non-empty body.
<mark_weaver>so I guess that requires some enhancement to 'check-transaction'.
<mark_weaver>to accept a body to send with the request.
<nalaginrut>I think it accept request-body
<mark_weaver>ah, indeed it does!
<mark_weaver>note that specifying a body of #f means "no body", which is not the same as "", which means "an empty body".
<nalaginrut>but seems no inner server started
<ArneBab_>nalaginrut, mark_weaver: I now have a function to read a single wisp-expression from a port and to translate that to scheme. The schemed version of the code is here:
<nalaginrut>Arne`: congrats
<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.
<ArneBab_>nalaginrut: but I’m unsure how to go on. My experiments look rather chaotic…
<mark_weaver>ArneBab_: nice!
<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>that's the first problem I see.
<ArneBab_>I just pushed the latest changes:
<ArneBab_>but it’s still mostly copy-pasted…
<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>ArneBab_: right
<mark_weaver>same for decompilers
<nalaginrut>oops, the tree-il is my mistake ;-O
<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 just did not understand you
<ArneBab_>I first had to understand that reader is a function which reads one expression from the inport and then returns.
<ArneBab_>(basics… ☺ )
<mark_weaver>ArneBab_: so, I guess you want something like this: (define (compile-scheme x e opts) (values x e e))
<nalaginrut>IIRC compile-tree-il has same pattern
<nalaginrut>so it works ;-P
<ArneBab_>do you by chance have emacs rudel-mode?
<mark_weaver>and (define (decompile-scheme x e opts) (values x e))
<ArneBab_>I’ll try that
<mark_weaver>ArneBab_: yes, I do.
<nalaginrut>I have to modify guile-sweet too
<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)
<mark_weaver>I'm behind nat.. that's a pain.
<ArneBab_>(I cannot open ports here, but if you cannot open it, I could use my homeserver… )
<ArneBab_>ok, I’ll try the homeserver
<mark_weaver>I'm not sure this is worth the effort, though.
<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.
<mark_weaver>okay :)
<ArneBab_>Rudel is like etherpad, but in emacs.
<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.
<mark_weaver>ArneBab_: maybe later.
<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.
<ArneBab_>no probs
<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
<nalaginrut>let it be ;-P
<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.
<ArneBab_>I’m currently calling guile with -L .
<mark_weaver>just set up a directory structure $DIR/language/wisp/spec.scm, and then put $DIR into %load-path
<mark_weaver>-L $DIR also works.
<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
<mark_weaver>get rid of the (language scheme *) imports.
<mark_weaver>compile the scheme?
<ArneBab_>yepp: instead of defined functions it returns strings with the scheme-code
<mark_weaver>the reader should return sexps
<ArneBab_>> ,L wisp
<ArneBab_>Happy hacking with Wisp Scheme Syntax! To switch back, type `,L scheme'.
<ArneBab_>wisp@(guile-user)> define : hello
<ArneBab_>... . "Hello World!"
<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_>that would get not-so-nice…
<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)
<ArneBab_>I’ll look into it
<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
<mark_weaver>ArneBab_: does the wisp parser use Guile's 'read'?
<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.
<ArneBab_>can I somehow defer it to read?
<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
<nalaginrut>mixed lexer and parser huh?
<mark_weaver>it's not obvious to me why you can't just use 'read'.
<ArneBab_>nalaginrut: a preprocessor…
<mark_weaver>but you read the whitespace first..
<mark_weaver>and comments
<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>so whenever you see an '(', just call 'read'.
<mark_weaver>and in fact, whenever you detect that something is not a wisp form or a comment, just call 'read'.
<mark_weaver>right? am I missing something?
<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.
<nalaginrut>or write a same 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
<mark_weaver>what about top-level datums?
<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>well, triple-quote.
<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.
<ArneBab_>ah, no, there’s the " in the strnig…
<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?
<mark_weaver>I'm not sure I understand the question.
<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.
<mark_weaver>do you unescape the line breaks later?
<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?
<ArneBab_>it has to be able to parse itself…
<mark_weaver>well, I'd go about this in a much different way.
<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>something to that effect.
<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_>it’s far from that
<ArneBab_>and it doesn’t yet handle all of wisp correctly.
<ArneBab_>but it works for most code
<ArneBab_>(is there a way to add an EXPERIMENTAL USE AT YOUR OWN RISK flag to a language?)
<mark_weaver>hehe :)
<mark_weaver>where's the wisp spec again?
<mark_weaver>maybe I'll try my hand at writing a wisp parser.
<ArneBab_><mark_weaver> ArneBab_: What else do you need from core Guile to implement this nicely? — ^ this ☺
<ArneBab_>mark_weaver: the wisp-spec is 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?
<ArneBab_>(would that help you?)
<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>ArneBab_: sure, that would definitely help
<mark_weaver>ArneBab_: no
<ArneBab_>I feared that (re: no)
<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…
<nalaginrut>mark_weaver: I'm looking
<ArneBab_>mark_weaver: where would that break?
<ArneBab_>mark_weaver: a port is a fifo, right?
<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…
<mark_weaver>what are 'internal-port' and 'port' hooked up to?
<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.
<ArneBab_>port is the input
<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.
<ArneBab_>could I use a soft-port?
<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>the 'e' argument to 'compile-scheme'.
<mark_weaver>and the two 'e's that are returned.
<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?
<mark_weaver>so the logic in the wisp reader would be:
<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.
<mark_weaver>here's one way to hack it for now:
<nalaginrut>with #:body "", I found HEAD -> GET, POST->GET in old code
<nalaginrut>yes, I agreed soft-port is not a good design here
<nalaginrut>it doesn't cover the function test
<mark_weaver>in your spec file, define a global variable (define wisp-pending-port (make-object-property))
<mark_weaver>do you know about object properties?
<ArneBab_>not yet
<nalaginrut>ah, I don't understand object properties too
<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.
<ArneBab_>I’ll try that…
<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>ArneBab_: this is more of less what I had in mind (untested):
<mark_weaver>and then you can just do #:reader read-one-wisp-sexp
<ArneBab_>YAY! works!
<ArneBab_>I’ll set it up to you can test it, too.
<mark_weaver>ArneBab_: is there a way to read a top-level datum that's not a list, in wisp?
<ArneBab_>yes: just prefix it with a .
<ArneBab_>. "123"
<mark_weaver>also: what do you do if the first non-whitespace on a line is a comment?
<mark_weaver>is there any significance to that?
<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>s/when if/what if/
<ArneBab_>wisp does not yet handle #! !#…
<mark_weaver>it's just not #! !#.. it's also #;datum
<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.
<ArneBab_>(and about other lisps)
<mark_weaver>okay, sounds wise :)
<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!
<mark_weaver>happy hacking!
<mark_weaver>you're welcome
*mark_weaver --> zzz
*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_>(but my Google foo fails me right now)
<ArneBab_>… the posts could have been from Andy
*ArneBab_ curses his horrible person-memory…
<ArneBab_>this is where I’d like to link it:
<nalaginrut>Arne`: maybe guile wiki?
<nalaginrut>on libreplanet
<ArneBab_>nalaginrut: is that his/your site?
<nalaginrut>it's official guile wiki IIRC
<nalaginrut>I'm planing put some articles on it
<ArneBab_>For guile I just linked to
<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
<nalaginrut>but I'm writing an article for front-end
<nalaginrut>maybe different from your idea?
<nalaginrut>you just need REPL?
<ArneBab_>an article for w
<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
<dsmith>Looking for EOF?
<ijp>I think so
<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>so there's the bug
<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
<civodul>Hello Guilers!
<civodul>we have a problem!
<civodul>our web client is *damn* slow
<civodul>and i can't find why
<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"?
<ArneBab_>Hi civodul
<ijp>which seems to be blocking unnecessarily
<civodul>ft: oh you're right, i had forgotten about that one
<civodul>when was it added?
<civodul>2.0.9 apparently
<ArneBab_>regarding this post: How Guile (and Scheme) Could Really Win the Language Selection War →
<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>makes no sense!
<ijp>it has to be something in the get-bytevector-* procecures though
<ijp>which means C :(
<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_>,L is cool!
<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>reading this for the first time:
<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
<ijp>no no, my mistake
<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>(the reddit lemma)
<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
<davexunit>ijp: fair point
<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
<ArneBab_>oh, yes!
<ArneBab_>ijp: mail sent.
*ArneBab_ out :)
***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
<nalaginrut>well that's it
<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>seems it's too late for me to talk about tech
<nalaginrut>it's sleep time...
<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
<nalaginrut>what's the principle?
<ijp>excuse me?
<nalaginrut>I mean how
<ijp>remove the module from the uses list, nuke the obarray, rebuild
<nalaginrut>how to rebuild? which procedure?
<nalaginrut>maybe you mean reload?
<ijp>nalaginrut: I explicitly do not want to reload
<ijp>I want to unuse[sic] a module
<nalaginrut>I don't know module-modified, it does rebuild?
<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?
<add^_>ijpbot: shoot add^_
*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> is an (almost) complete list of the ones fsbot on #emacs supports
<ijp>I think I added at least 70% of them
<ijp>actually, that list is no where near complete
<add^_>ijpbot: help
<ijpbot>no such command: #{}#
<ijp>pretty sure there's like twice as much
<add^_>Sneek just spammed me privmsg XD
<add^_>But that was useful :-)
<add^_>sneek: botsnack
<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)
<ijp>ijpbot: commands
<ijpbot>ijp: help, join, lets, botsnack, shoot, privmsg, flay, eval, ping, define, source, say-hello, commands, auth, quit, revoke, debug, log
<ijp>okay, works right
<mark_weaver>ijpbot: eval (+ 1 1)
<ijpbot>You need to be my master to do this "mark_weaver"
<mark_weaver>ah :)
<ijp>special privilege :)
<add^_>ijpbot: auth
<ijpbot>New authentication string created. Check stdout.
<add^_>Isn't that bad?
<ijp>depends, can you see my stdout?
<add^_>I have to check on your comput..
<ijp>because that would be bad in any case
*add^_ spoke to soon
<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
<ijp>but in general, yes
<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)
<shanecelis>zipper is non-mutating, right?
<shanecelis>gap-buffer is for strings only.
<mark_weaver>ah, right
<shanecelis>But yeah, same idea.
<mark_weaver>what kind of traversal pattern do you expect?
<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>mark_weaver: that's a good idea.
<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!
<mark_weaver>glad to help :)
<mark_weaver>and thanks for the kind words :)
<shanecelis>You're very welcome. :)
<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
<mark_weaver>ArneBab_ just used this method to support his "wisp" syntax in Guile.
<mark_weaver>ijp: well, we'll have to solve that problem anyway.
<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.
<shanecelis>Cool. Adding this idea to my TODO.
<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 :-/
<mark_weaver>anyway, we can talk about it later...
<shanecelis>Sounds good. I think that would definitely be preferable.
<mark_weaver>ArneBab_: Here's a more efficient 'string-replace-substring':
<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
<add^_>hello "supremeleaderijp"
<supremeleaderijp>add^_: it makes more sense if you are on #emacs
*add^_ joins #emacs
<supremeleaderijp><oakaz> some open source communities make me feel like I live in North korea
<add^_>I haven't been there for ages
<add^_>Still funny I see
***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..
<add^_>stis: are you tampe?
<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^_>wrong window?
<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
<add^_>No :-/
*add^_ clicks
<stis>add_ I live in Västerås!
<stis>add^_: ^^
<add^_>stis: :-)
<add^_>I live near Gothenburg :-)
<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^_>Maybe not
<add^_>Oh well
<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?
<dsmith-work>Happy Friday, Guilers!!
<add^_>Is it Friday?
<dsmith-work>It is for me!
<add^_>Happy Friday everyone!
<add^_>I just got really confused, it apparently is Friday here too. (Thought it was more like Wednesday or something)
<dsmith-work>Yeah, that happens..
<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.
<add^_>ijp: lol, why?
<add^_>to get rid of them?
<ijp>add^_: just to explore quines
<ijp> is my "fib quine"
<add^_>ijp: LOL at the 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?
<stis>add^_: ^^
<add^_>It's not that I'm not good at it, I'm just uneducated in it.
<stis>Are you taking a degree?
<add^_>No School for me anymore..
<add^_>Not right now anyway.
<stis>Hard Work then ;-)
<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>no rush :)
<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 ?
<dsmith-work>Yes. There is no 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
<ArneBab_>ah, ok
<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?
<dsmith-work>mark_weaver: Are there 2.1 snapshots being made?
<mark_weaver>add^_: personally, I would stick to stable-2.0 for "make install", but guile-master is fine to try also.
<dsmith-work>sneek: snapshots?
<sneek>snapshots is at
<add^_>hm ok
<dsmith-work>AH yes.
<add^_>Maybe I should wait for that instead. :-)
<mark_weaver>wait for what?
<add^_>2.1 snapshot
<mark_weaver>the snapshots are made automatically every time we change anything.
<mark_weaver>so the snapshots should basically always be up to date.
<add^_>Well, "stable release"?
<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.
<mark_weaver>anyway, gotta go offline for a bit. happy hacking!
<add^_>missed him
<add^_>happy hacking*
<dsmith-work>sneek: later tell mark_weaver, add^_ says "happy hacking*"
<sneek>Got it.
<dsmith-work>sneek: botsnack
<add^_>thanks dsmith-work
<ArneBab_>wow, the speed of marks replace-substring is awesome!
<ArneBab_>sneek: help
<ArneBab_>how can I tell a bot to msg mark?
<add^_>ArneBab_: I think it'll give you help in a private message
<ArneBab_>ah, yes, it did. thanks!
<add^_>I guess that's to not accidentally get kicked for flooding
<ArneBab_>sneek: later tell mark_weaver The performance is awesome! Thanks!
<sneek>Will do.
<ArneBab_>sneek: botsnack
<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?
<ijp>sneek botsnack
<ijp>sneek: botsnack
<add^_>not that :
<ijp>ah in the message
<add^_>I meant the one after mark_weaver in ArneBab_ 's message
<add^_>actually, can test that now
<ijp>sneek: later tell ijp: foo
<sneek>Welcome back ijp, you have 1 message.
<sneek>ijp, ijp says: foo
<ijp>it's fine
*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?
*add^_ was enlightened
<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
<ijp>aidalgol: ping
<taylanub>add^_: You can spell-check in Emacs with M-$.
<taylanub>Oh .. maybe need to load ispell.
<aidalgol>ijp: pong
<taylanub>M-x load-library RET flyspell RET might do it.
<add^_>still undefined
<taylanub>What Emacs version ?
<ijp>aidalgol: I have a COOL NEW FEATURE(tm)
<taylanub>Maybe it was added in 24.
<aidalgol>ijp: rudybot ripoff?
<ijp>hold on, I'll demonstrate
<ijp>ijpbot: define test
<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.
<ijp>ijpbot: define test
<ijpbot>No such command: define
<ijp>ijpbot: define test
<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?
<aidalgol>ijp: Oh!
<ijp>I reloaded the plugin
<aidalgol>I thought we could already do that. :P
<dsmith-work>add^_: :or ,
<ijp>aidalgol: you could, by doing it one function at a time
<dsmith-work>emacs erc adds the : when I hit tab
<dsmith-work>sneek, botsnack
<dsmith-work>sneek botsnack
<dsmith-work>It sdoesn't matter
<ijp>ijpbot: dont-help
*ijpbot blows a raspberry
<aidalgol>ijp: Do we want a factoid module?
<aidalgol>Yeah, I guess we do for #guile.
<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>ijpbot: ping
<ijp>and that one needs fixed too
<ijp>ijpbot: define perspicacity
<ijpbot>perspicacity definition: of acute mental vision or discernment.
<ijp>ijpbot: disable ddg
<ijpbot>Unbound variable: remove-plugin!
<ijp>ijpbot: disable ddg
<ijp>ijpbot: define vivacious
<ijpbot>No such command: define
<ijp>ijpbot: enable ddg
<ijp>ijpbot: define vivacious
<ijpbot>vivacious definition: lively in temper, conduct, or spirit.
<ijp>ijpbot: revoke
<add^_>ah well, good night all
<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