IRC channel logs

2016-09-05.log

back to list of logs

<paroneayea>o/
<amz3`>wingo: In the fibers documentation, I think you talk about fibers scheduler without introducing that fibers has a user space scheduler
***wleslie is now known as verte-nv
<amz3`>here is a mini-framework that mimick tinkerpop's gremlin similar in principle to srfi-41
<amz3`> http://hastebin.com/foqelamoru.lisp
<djcb>is it possible to add a docstring to non-closure defines? I.e. somewhat like emacs' defvar?
<amz3`>amz3: one particular that it does, results of map are chained to be able to get the parent result cf. traversi-parent
<amz3`>compared to yesterday paste, this implementation has a filter proc
<amz3`>see you later
<wingo>moin
***verte-nv is now known as wleslie
<lloda>morning wingo, thx for the link ^
<lloda>fortran had it right with A(i) ~ f(x) :-/
<civodul>hello!
<jmd>how do I square a number in Guile?
<lloda>(* x x) ??
<lloda>or (expt x 2) I guess
<jmd>Thanks.
***wleslie_ is now known as wleslie
<jmd>How can I persuade guile to display a number as a decimal rather than a vulgar fraction?
<wleslie>(exact->inexact), while not really for display, is one way
<jmd>I'll use that. Thanks.
<profan>7Iwn 10
<profan>wops
<lloda>I use (* a 1.) on the repl
<jmd>oh. How does that work?
<wleslie>inexactness is catchy
<wingo>jmd: this and many of your other questions can be answered by reading the manual
<jmd>It is such a shame that #guile is slowly becoming like #perl.
<jmd>But even in #perl often when someone says RTFM, they will also point you to which bit of the FM to R.
<wleslie>wingo: I guess you'll have to grow a moustache.
<wleslie>jmd: it wasn't a refusal to answer your question, just a suggestion that you may have an easier time if you've taken a look at it.
<jmd>I have perused the manual many times. If I had remembered a section which I recalled to be relevant, then I would not have asked here.
<wingo>jmd: my comment is in reaction to your many questions which have simple answers in the manual. we put them there so that we don't have to answer them many times.
<wingo>i feel like my time is not being respected when someone asks a question whose answer can be found in the manual.
<jmd>ACTION ignores wingo
<wingo>it's fine if it's just a few times. but a pattern of such questions indicates a problem
<wingo>lol
<wingo>why on earth would you enter the guile channel and ignore its maintainer
<davexunit>reminds me of the time ams joined #guix and proceeded to ignore every core developer and ludo
<davexunit>good times.
<wleslie>that sounds like ams
<jmd>davexunit: I am not a guile developer. I respect those people who have work on Guile (and all free software projects). I do not expect them to answer my questions (but am grateful when they do). Should they choose not to answer, I also expect them to refrain from patriotic rhetoric.
<jmd>Also, if this channel is supposed to be a developers only channel, I suggest that this is made clear in the /topic and let somebody start a #guile-users channel.
<jmd>s/patriotic/patronising
<wingo>the guile manual is for all guile users.
<wingo>except for jmd apparently :P
***ruste is now known as Guest85974
<TMA>wingo: as the guile maintainer, do you care of cygwin? or is cygwin support out of scope, because guile is a GNU project? I might be able to run a build now and then.
<wingo>TMA: cygwin builds sound great :) we have been doing a fair amount of mingw work recently too
<wingo>i don't use or ship to windows so i can't do that development; depends on what users want really
<wingo>recently it seems that people mostly want mingw tho
<wingo>i don't see a near or mid-term future supporting visual studio tho
<TMA>wingo: as of "8f2f8db Fix typo about open-pipe" the C part compiles fine but then eval.go fails to load
<wingo>also i am a co-maintainer, civodul and mark_weaver are also maintainers
<wingo>so s/the maintainer/a maintainer/ :)
<wingo>TMA: was it working before?
<TMA>wingo: oh, I meant no insult by my article choice
<wingo>yeah i just meant to not take the credit/ultimate decision power/etc
<TMA>wingo: it's the version I tried last. I might try bisecting the history. 1.8.8 ships with cygwin as a binary, so it was definitely working in the not-so-recent past
<wingo>TMA: i would try first mailing guile-user
<wingo>i think some people build with cygwin
<wingo>that way you have a chance at finding those people
<jmd>Is there any builttin or standard numerical constants in Guile (eg, pi)? [Yes - I did look to see if I could find any reference in the manual.]
<nalaginrut>A preview of Guile-Lua (rebirth), and some oguansihttps://nalaginrut.com/archives/2016/09/05/a-preview-of-guile-lua-%28rebirth%29%2C-and-some-opinions-
<amz3>nalaginrut: neat!
<amz3>nalaginrut: what do you plan to in AI?
<amz3>nalaginrut: what do you plan to do in AI?
<rekado>I'm writing a web interface in Guile that should allow users to start a long running application and eventually get a link to the results.
<rekado>do you have any hints as to how to design this?
<rekado>I probably shouldn't tie up Guile web server handler threads, so this needs to be forked to start the application in the background, I think.
<rekado>A related question is: how many requests does the web server handle simultaneously? Does it fork and/or have a thread-pool?
<rekado>or is it better to start a lot of them and use a load balancer?
<rekado>(or a reverse proxy with multiple backends)
<rekado>I think I may need to separate this into the web server and a worker pool. Not sure what to use for managing the job queue. "guile-redis" maybe or just sexps..?
<wingo>rekado: i think the long-term answer for this on the server side is something like fibers
<wingo>but as far as the user goes you probably need some javascript to give users a nice in-the-meantime result
<wingo>fibers are pretty close to working enough for your use case, but what you will want to do is make your fiber spawn a thread that will send a message back over a channel when it is done
<wingo>and we don't have channels implemented yet
<wingo>not sure if that really helps you right now tho :)
<rekado>hmm
<rekado>can't really wait :)
<wingo>by default right now the web server can have a number of clients waiting on it but only serves one request at a time
<wingo>once the request is served the client goes back into the poll set
<wingo>with fibers, you can have multiple requests being served at a time; when each request would block, the fiber suspends and a different active request is scheduled
<wingo>it's really nice from the user POV because you don't really have to change anything about the way you code your program
<wingo>you just (run-server 'fibers) instead of the normal run-server invocation
<rekado>I see. Is a fiber-ized web server part of 2.1.x?
<wleslie>you just have to completely give up any hope of comprehending the state space, or use pure code everywhere
<wingo>i think it needs 2.1.x but the fiber-ized web server implementation is part of fibers (https://github.com/wingo/fibers)
<wingo>i had a web server implementation on top of thread pools at some point but it was not so great
<wingo>i am much more enthused about lightweight concurrency these days
<wingo>rekado: to run the web server with fibers, the silly hello example is pretty much the same https://github.com/wingo/fibers/blob/master/examples/web-hello.scm
<rekado>nice
<wingo>i get better latency and throughput on that compared to master, but it's a work in progress
<wingo> https://github.com/wingo/fibers/blob/master/fibers.texi is a bit of design, still have some channels things to implement tho
<wingo>wleslie: i think "how to understand state space" is a problem in all systems with concurrency and state tho :/
<wingo>the situation with thread pools and with callbacks is essentially the same as with goroutines or erlang processes
<wleslie>in some systems, some local reasoning is possible
<wingo>like what? :)
<wingo>(honest q)
<wleslie>I guess I've linked you https://glyph.twistedmatrix.com/2014/02/unyielding.html before - in the list of four green threaded solutions under the "don't use threads" heading, three permit local reasoning, and the rest explains why
<wingo>i think i just disagree with his central assertion that options 1-3 permit local reasoning. you still have to imagine all of the ways in which shared state is mutated by concurrent (though not necessarily in-parallel) executions of multiple callbacks
<wingo>you still need a system-wide understanding of mutable state.
<wingo>and as we all know mutable state doesn't live only in one address space; understanding system-wide state in a network is hard
<wingo>a chain of callbacks is a thread of execution, and it communicates with other threads by sending messages; any thread system that communicates by message-passing is essentially the same i think
<rekado>wingo: I'm reading fibers.texi right now. Very instructive!
<rekado>(there's a word missing here: "A process that tries [to] receive a message", line 175)
<wingo>tx
<wleslie>wingo: it doesn't remove the need to ever consider the global state of the system, it reduces the number of positions in the code at which you need to consider that state
<wingo>you're probably right for a system with lots of shared state.
<wingo>i wonder how much weight glyph's arguments have if you have a system where mutable state is localized to single threads
<wingo>like the concurrent ml implementation of an async queue
<wleslie>it's especially relevant if you have mutable state localised to single threads
<wingo>ACTION listens :)
<wleslie>in that case, what matters is the order of messages sent
<wingo>but you can reason entirely locally when you have one thread handling one bit of mutable state.
<wingo>that's the thing that impressed me about concurrent ml
<wingo>approximately none of ousterhout's arguments apply to go or erlang, i don't think
<wleslie>certainly not to erlang
<wingo>the concern is just about mutable state visible to other processes then?
<wingo>erlang is even more gnarly in some ways because it is pre-emptive
<wingo>so you can get all kinds of message orders
<wingo>dunno
<wingo>maybe that is trash reasoning :)
<wingo>but the deadlock concerns can apply equally to erlang
<wleslie>message order guarantees are another interesting thing. I happen to think erlang has very strange message ordering.
<wleslie>hmm? can you deadlock erlang? you can livelock it...
<wingo>two processes waiting to recv from each other are in a deadlock situation, aren't they?
<wleslie>that's datalock, when you've got a descriptor that select() will never return
<wleslie>or a future that will never resolve etc
<wingo>yeah
<wingo>but in a system where channels/ports are the means of synchronization, not mutexes and conds, afaiu it's equivalent
<wleslie>the interesting thing about sane event systems is that you can't block a task waiting for one
<wingo>because channels/messages/etc are used to signal control flow as well as data flow
<wingo>how do you mean?
<wingo>a callback that is waiting on a request is just like a task blocked on a message, seems to me
<wleslie>in systems where you can have back edges - say, wait for that task to complete before continuing this task - you can arrive at that situation
<wingo>maybe i am just saying the same thing all the time and not listening :)
<wleslie>in E or Twisted or Promises/A+, you can't tell it to wait right here, you can only add more callbacks
<wleslie>what you get from that is that each event runs to completion, so events running in a single thread aren't really concurrent, they run to completion and get out of the way
<wingo>what's the difference between erlang saying "recv right here" (presumably a good thing?) and your negative example of "wait right here"
<wingo>i do think events are concurrent with respect to each other. they might not run in parallel but given N runnable events they could be handled in any order
<wleslie>in a pure world, creating a new task/promise and recv-right-here are not semantically distinguishable
<wingo>e.g. if they are all in the same epoll set, who knows in which order they'll be handled
<wleslie>sure, but they won't overlap.
<wleslie>I guess it's a bit like scheme's argument evaluation compared to pythons.
<wleslie>function arguments may be evaluated in any order, but each argument is evaluated to completion before the next one is considered.
<wleslie>if you didn't get to read the Ca(sh|che Coherent) Money example, it's a good illustration of the sort of problem you can solve when you can see how the current task is delimited
<wingo>wleslie: in that case i think the problem was having global mutable state which was not managed by a single process
<wingo>i saw the example and was not convinced
<wingo>but maybe that was ignorant of me :)
<wingo>i'm sure there are oodles of erlang bank account examples out there
<wleslie>it's two values - bank accounts - managed by a single process. the problem is that other tasks may run between the querying of sufficient funds and committing the change.
<daviid>ACTION wants an erlang account :)
<wingo>hmm, i don't think they are managed by one process are they? i mean those accounts must be visible to other processes
<wleslie>nope, one process
<wingo>other threads i mean
<wingo>other user-space thread
<wingo>s
<wingo>other callbacks etc
<wleslie>it doesn't matter, no other callback runs between the start of the function and the yield
<wleslie>well, you might have a database thread or something, but it shouldn't be touching the account objects
<wingo>i think we are not using the same words
<wingo>or using the same words but in different ways
<wleslie>could be
<wleslie>two invocations of this function will not be running at the same time (except in the broken example)
<wleslie>between any two yields, the function owns the only thread that is allowed to touch account objects
<wingo>what i meant by "mutable state owned by one process" is violated if anyone can access "payer" or "payee" without being the thread/chain-of-promises/chain-of-callbacks that owns them
<wingo>like in concurrent ml.
<wleslie>oh, sorry wingo, I misread
<wleslie>I thought you said that a thread owns a single mutable value :$
<wingo>just talking about concurrency is confusing :)
<wingo>to me too :)
<paroneayea>rekado: 8sync has an actors model subsystem you could also use to build this, keep in mind that 8sync is pretty alpha :)
<wingo>8sync might be less alpha than fibers, dunno :)
<wingo>lots happening in this area :)
<paroneayea>in the future, it should be possible to split off actors onto multiple processes
<paroneayea>and you won't have to change any of your code
<paroneayea>that's one nice feature of using the actor model
<wingo>ah be careful i was using the word process in a different way just lines before :)
<paroneayea>I've put most of the infrastructure in place for that, but haven't actually set it up yet :)
<paroneayea>I meant actual different processes!
<paroneayea>but
<wingo>that is just a convention!
<wingo>erlang processes are also processes!
<rekado>paroneayea: I also looked at 8sync, but I'm having a hard time to figure out how I would implement this.
<paroneayea>you can still do things asynchronously between different actors which are in the same process
<daviid>fibers is a serious bank! :)
<paroneayea>rekado: if I weren't under such a tight deadline, I'd try to implement it
<daviid>rekado you may look at guile-async [and guile-asunc2 for 2.2] as well, I'm using it to interact with g-main-loop and inotify2
<rekado>hah, third!
<rekado>:)
<daviid>rekado: yes, fibers did not exists and 8sync can't interact with a gtk loop afaict anyway
<paroneayea>yeah 8sync can't interact with the gtk loop
<paroneayea>it has its own loop
<paroneayea>it might be possible to set it up to do so, but it isn't possible now
<rekado>the only way I've ever done things is to let one process write to redis and have workers pick up tasks via redis.
<daviid>rekado: here https://github.com/ChrisVine/guile-a-sync.git
<rekado>when they're done they write back to redis
<rekado>meanwhile JS polls the status by GET'ing the target page.
<paroneayea>ACTION writing a form library right now
<paroneayea>kind of like wtforms
<rekado>(the server then checks the state in redis and prints the URL to the result when it's ready)
<paroneayea>I have less than 2 weeks to get pubstrate ready for demo at TPAC and get ActivityPub ready for Candidate Recommendation X_X
<wleslie>wingo: so I'm handling an event, I call a function foo that calls another function that attempts to read from a queue and blocks, and so my event is stashed and another runs, and eventually my event is scheduled again and continues
<rekado>I have a hard time understanding how to do this without this intermediary database.
<rekado>daviid: thanks!
<daviid>rekado: welcome, it has a good manual as well
<wleslie>wingo: if I had any invariants that I expect to hold across the call to foo, I'm in trouble, even though I've only got one address space and thread here
<wleslie>wingo: if I have to syntactically indicate that I allow foo to yield control, I can locally determine if my invariants hold or not
<wleslie>I mean not decidably or anything, but I can clearly see where some other task may run and mess them up
<rekado>paroneayea: 8sync-0.1.0 still has the SIGABRT bug, no?
<paroneayea>rekado: nah I fixed that
<paroneayea>oh
<paroneayea>wait
<paroneayea>0.1.0
<paroneayea>yeah probably
<paroneayea>I haven't released the new exciting version with the actor model yet :)
<rekado>hah :)
<paroneayea>ACTION is the worst
<rekado>any plans to make a new release?
<paroneayea>rekado: yeah I should probably just do it...
<paroneayea>rekado: let's see if I get around to it later tonight.
<paroneayea>rekado: 8sync doesn't yet use the cool port suspending stuff in guile 2.1 yet tho
<paroneayea>it came out before that...
<paroneayea>I need to refactor to enable that
<paroneayea>it'll make things much simpler
<paroneayea>instead, you set up listeners on ports which spawn events
<nalaginrut>amz3: I have no plan yet, but I think I'm interested in giving machine soul rather than vision/hearing
<amz3>nalaginrut: exciting
<nalaginrut>amz3: I'd like to implement python3, but Lua seems easier, although it's complicated enough for building a usable one
<amz3`>héllo again!
<amz3`>rekado: if you need something done quickly you'd rather use redis as job queue
<amz3`>IMHO
<paroneayea>form library mostly written
<paroneayea>so now, a form widgets library, signed cookies... starting to look like a real collection of web application tools! :)
<wingo>evening :)
<mark_weaver>sneek: later tell jmd: fwiw, my preferred way of getting pi from guile is (acos -1)
<sneek>Okay.
<wingo>mark_weaver: you have time for an idea/feedback about atomic ops and scheme?
<mark_weaver>wingo: sure
<wingo>cool
<wingo>i want to add support for atomic operations to scheme
<wingo>via vm ops probably.
<wingo>there are two ways this could go
<wingo>one would be some generic facility whereby any memory location could be operated on atomically
<wingo>the other would be a special data type that supports only atomic operations
<wingo>the advantage of the former would be that we could do atomic things without allocating a cell or whatever for the atomic object
<wingo>but then the vm would have to deal with raw pointers. maybe that's the way things will go in the future but for now it sounds not great.
<wingo>the advantage of an atomic-box data type is that we can be pretty sure that it's used correctly
<wingo>but it's more memory and another type to know about.
<mark_weaver>hmm
<wingo>i think we should do an atomic-box approach because if it turns out we need to switch to the other one, we can implement atomic boxes in terms of some lower level facility
<wingo>like, it seems conservative somehow
<wingo>dunno
<wingo>so you'd have make-atomic, atomic-ref, atomic-set!, atomic-swap!, atomic-compare-and-swap!
<wingo>i think that's it actually since they would be SCM objects
<wingo>because semantics of atomic-add! or whatever would be hard to guarantee with a fast path
<wingo>better to atomic-ref, add, and compare-and-swap! in a loop
<mark_weaver>no memory barrier operations?
<wingo>the atomic-ref and atomic-compare-and-swap! would have appropriate barriers
<wingo>we can use c11 inside guile if it's available, otherwise fall back to something with one global lock (horrors)
<mark_weaver>libatomic-ops, used by bdw-gc, provides atomic operations
<mark_weaver>the thing is, single-cell CAS is not sufficient to implement multi-cell atomic operations, iirc.
<wingo>i looked at that but i am not sure it is necessary tbh
<wingo>istr it is, but i will have to check
<wingo>with gc many of these algorithms are easy
<wingo>er
<wingo>easier
<wingo>sorry :)
<wingo>mark_weaver: also see http://git.savannah.gnu.org/cgit/guile.git/tree/libguile/atomics-internal.h, used by ports.c
<mark_weaver>I found a paper once that described how to implement multi-word CAS based on single-word CAS, but it was really gnarly and inefficient, and actually doesn't even work on modern weakly-ordered memory architectures.
<wingo>the classic use case for multi-word CAS is queues, and for that single-word CAS + gc is sufficient i think
<wingo>maybe i am misremembering
<wingo>right, because gc has the property that you can make fresh objects
<wingo>whereas with a queue implemented as an array (mutations in place), you have to think about the ABBA problem
<mark_weaver>I guess that if we're going to add a new set of concurrency primitives, it would be good to choose a set that's sufficiently powerful, and also one that allows more efficiency than is possible with traditional locks.
<mark_weaver>and I'm not sure that single-word atomics meets those criteria
<wingo>ACTION nod
<wingo>the thing i want to avoid is the hazard of critical regions where code can be interrupted or cancelled
<wingo>mostly by asyncs i guess
<wingo>(with-mutex ...) has many of these hazards
<mark_weaver>the set of atomics and memory barriers provided by C11, and the ones provided by libatomic-ops, both allow considerably greater efficiency in some cases, at the cost of more complex proofs.
<wingo>which i would prefer to solve via use of atomics instead of more flags and mutual exclusion
<mark_weaver>hmm, yes, that is indeed a problem..
<wingo>mark_weaver: i see your point. i wonder though, woundn't any 'proper' solution have single-word CAS as an operation? in that regard perhaps it is not too risky to add them. dunno.
<wingo>like if we need to do something more powerful in the future, we can add that interface to (ice-9 atomics) or whatever we use to define single-SCM atomic boxes
<wingo>i wonder what good prior art is out there :)
<mark_weaver>wingo: if you want to add a new type for atomics, supported by a small number of VM ops, I'm fine with that. even if it doesn't end up being our preferred approach in the long run, it's not a big deal.
<mark_weaver>and it could perhaps grow into supporting the full set of C11 atomic operations at some point.
<mark_weaver>*atomic operations and memory barriers
<wingo>thanks! i will try to keep it isolated in such a way that it can be replaced in the future.
<mark_weaver>sounds good to me :)
<wingo>ACTION reads http://manticore.cs.uchicago.edu/papers/icfp09-parallel-cml.pdf
<wingo>i asked matthew flatt and matthias felleisen what the right thing is and they say "concurrent ml"
<wingo>so prolly they are right
<mark_weaver>I suspect I would agree :)
<mark_weaver>ACTION looks
<random-nick>concurrent ML uses channels like Go does?
<sapientech>say i want to create a sweet mostly static website with guile, what are my options
<sapientech>ive started using haunt for a personal blog, which ive liked so far, but curious if it can handle a moderately complex website
<sapientech>artanis ive heard of, but some people say that its gone in a direction that is not overly popular
<OrangeShark>sapientech: I believe those are the only options.
<paroneayea>sapientech: 8sync's site uses Haunt
<paroneayea>sapientech: there are things that could be done and improved in Haunt, like only recreating pages if they've changed
<paroneayea>sapientech: but one nice thing is that Haunt is pretty easy to hack on... I've gotten a couple of changes upstream; davexunit is very receptive in my experience
<paroneayea>sapientech: I'd say, see how far you can go with Haunt, and at the point where it's become hard to do, either start looking at ways to improve Haunt, or you'll know pretty well a new direction you want to go.
<mark_weaver>+1
<mark_weaver>sapientech: I would also recommend using Haunt if possible.