IRC channel logs

2015-03-29.log

back to list of logs

<davexunit>what's the best way to deal with date math involving time zones in guile?
<ijp>my initial response was srfi 19, but I don't know how well/if that handles timezones
<davexunit>ijp: I didn't see anything there.
<ijp>I see a few mentions of a tz offset under date, but it seems to be in seconds
<ijp>it's the final field in a date record
<davexunit>oh
<davexunit>how did I miss that...
<davexunit>that's should do
<davexunit>thanks
<dje42>mark_weaver: https://sourceware.org/ml/gdb-patches/2015-03/msg00954.html
<davexunit>FFI question:
<davexunit>a shared library "foo" depends on a function defined in shared library "bar"
<davexunit>using 'dynamic-link' on both libraries apparently isn't enough for functions in foo to use functions in bar.
<davexunit>am I doing something wrong, or did someone build the shared libraries incorrectly?
<davexunit>looks like a linking error with the library I'm using
<davexunit>but maybe not?
<davexunit>I'm not sure how to link in the right library
<please_help>how did you build foo exactly?
***michel_mno_afk is now known as michel_mno
***michel_mno is now known as michel_mno_afk
<davexunit>please_help: libfoo is built without linking to libbar, but references symbols from it.
<davexunit>(dynamic-link "libfoo") (dynamic-link "libbar") isn't enough to make functions from libfoo work.
<davexunit>the program crashes with messages like "undefined symbol: xc_die_info"
<davexunit>if this were a C program, I would just pass -lfoo -lbar to gcc and things would work.
<paroneayea>hm
<paroneayea>so fluids/params defined outside a delimited continuation, but then set to a value within it, don't retain that value
<paroneayea>is this right?
<paroneayea>or rather
<paroneayea>they mutate externally
<paroneayea>and are dependent on whatever happens externally too
<paroneayea>eg
<davexunit>paroneayea: they retain the value throughout the dynamic extent of the form that they are "parameterized" in
<paroneayea>davexunit: hm http://pamrel.lu/7b90a/
<paroneayea>I thought that would be true but my test above seems lik it isn't?
<davexunit>in Sly, I use a parameter called 'current-agenda', and the value is retained in my coroutines and such
<paroneayea>davexunit: that's what I want, but I don't seem to be getting that behavior. Could you check whta I'm doing wrong?
<davexunit>paroneayea: use 'parameterize'
<paroneayea>davexunit: ohhhh
<paroneayea>I see
<paroneayea>davexunit: that makes a lot of sense :)
<mark_weaver>paroneayea: see http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18356#17 for an explanation
<paroneayea>mark_weaver: davexunit: perfect, I now have the behavior I want
<paroneayea>thank you!
<mark_weaver>you're welcome!
<paroneayea>I really wish python had similar fluids/parameters!
<paroneayea>that would make writing asyncio stuff much easier
<davexunit>they have their weaknesses, but they are very useful for certain things.
<davexunit>just use sparingly :)
<davexunit>parameters and lazy evaluation don't play nicely.
<ijp>parameters in python would be pretty easy to do with the "with" statement
<ijp>it basically boils down to a Box class
<ijp>well, except it probably wouldn't interact with treads correctly
<ijp>hmm, no, this would fail because with binds a new variable lexically
*ijp waves hands
<paroneayea>ijp: yeah
<paroneayea>ijp: it wouldn't work with asyncio type coroutines stuff either
<paroneayea>afaik
<ijp>you can probably still fake it, by making parameter objects just mutate a shared "obarray"
<ijp>which would ideally need to be weak
<paroneayea>ijp: I have no idea how that would work, but will trust your judgement :)
<ijp>I might hack it up
<mark_weaver>in guile, fluids are implemented as follows (slightly simplified): every thread has a thread-local array of fluid values. every fluid is assigned an integer, which is the index into those arrays.
<paroneayea>mark_weaver: interesting
<mark_weaver>with-fluids and parameterize save the current values of the fluids being modified, and then modify them.
<mark_weaver>and they arrange that if a non-local exit happens, the old values will be restored
<mark_weaver>there's a bit more though
<mark_weaver>since scheme allows you to "re-enter" after a non-local exit, more is needed
<mark_weaver>when the non-local exit happens though a 'with-fluids', the current values of the fluids are *swapped* with the saved values.
<mark_weaver>because fluids+parameters can simply be modified in place, when the non-local exit happens, the fluids might not have the same values assigned to them by the 'with-fluids'
<mark_weaver>so the current inner values are saved when the non-local exit happens, and then restored (by swapping again) if the 'with-fluids' is re-entered.
<mark_weaver>although python doesn't have first-class continuations, it does have generators which are co-implementable with delimited continuations, iirc.
<mark_weaver>so it may be that a proper implementation of fluids/parameters in python needs to take generators into account, dunno.
<ijp>paroneayea: https://gist.github.com/2b86da261569a314b9ff
<ijp>abusing __call__ but whatever
<paroneayea>ijp: interesting
<paroneayea>does this handle if something happens outside a coroutine?
<paroneayea>eg, if a coroutine which binds the parameter suspends, the parameter gets changed, but then the coroutine wakes up again
<paroneayea>will it keep the external parameter value or its internal one?
<paroneayea>ijp: and no worries about abusing __call__, that's the python way ;)
<ijp>I really doubt this works with coroutines
<paroneayea>yeah, that's my use case, hence the trouble
<paroneayea>I want a way to specify the current language to gettext for instance
<mark_weaver>ijp: could the approach in that sketch be used to handle exceptions, or would a different approach be needed?
<paroneayea>and obviously globals fail in an asyncio environment
<ijp>mark_weaver: maybe, but AFAIK with is just a wrapper on try/finally, so you'd really need the exceptions infrastructure to begin with
*davexunit messes around with guile's ffi and fpgatools
<davexunit>the ffi is so fantastic.
<paroneayea>I'd like to play with it
<civodul>Hello Guilers!
<djcb>i'd like to implement a parser for a little query language in guile
<ijp>and how can we help you?
<djcb>something like (define my-query '(or (contains foo "bar") (not (contains cuux "blurb"))))
<djcb>and turn that into an sql-query
<djcb>seems like a not-too-atypical thing to do, so perhaps there are some examples somewhere?
<davexunit>djcb: I've been down this road and didn't get very far
<davexunit>my first question, which SQL? each database has a similar, but different query language.
<ijp>you can probably abuse the sxslt stuff to do it, but I may be the only person who uses that
<djcb>for now, it'll be sqlite
<davexunit>you need to somehow encode all of the possible syntax
<davexunit>some keywords use prefix notation, some postfix, some infix
<davexunit>that fact destroyed my dreams of having something like sxml for SQL
<djcb>i think i'll just restrict myself to prefix for now
<taylanub>I thought SQL was standardized? :\\
<ijp>taylanub: so?
<ijp>here was the jokey interpreter I wrote using pre-post-order last year <https://gist.github.com/ijp/fb1b62413ed858a1a0c6>
<ijp>"interpreter"
<djcb>mapping a sexp into a WHERE clause should be quite portable, except for some extensions, like sqlite's REGEXP
<djcb>ijp: oh, that looks interesting
<ijp>.oO(I should go through my gists and remove all the nonhilarious entries)
<davexunit>djcb: well, do you plan to only parse SQL?
<davexunit>if you can go sql -> sexp, it would be nice to go sexp -> sql
<davexunit>taylanub: every database has its own quirks and features
<davexunit>so you can't expect to have a general purpose reader/writer for SQL, unfortunately
<djcb>davexunit: it's a bit less general than that
<djcb>i'd like to take some s-exp, parse it and turn it into some sql
<davexunit>so it's not a sql parser, but a sexp->sql writer.
<djcb>yes
<davexunit>so yeah, you'll have to know how to write out each expression
<davexunit>(or (< id 10) (> id 100)) becomes "id < 10 OR id > 100"
<djcb>yes indeed!
<djcb>that seems like not too hard for a non-pedestrian schemer like myself :-)
<djcb>so, it'll be an interesting excercise
<davexunit>djcb: I'm very interested in using such a thing if you come up with a good implementation
<davexunit>call it guile-ssql and release it when you're done ;)
<ijp>pre-post-order aside, I don't suspect there is much general "parser generators" for sexps, most of that work is focussed on strings/ports -> sexp
<ijp>djcb: I think nalaginrut has something similar to this as part of artanis, but I don't know how far he got
<davexunit>I'd like a parser combinator library for Guile
<ijp>davexunit: riastradh's one (parscheme) is on guildhall
<davexunit>ijp: wait, it exists already???
<ijp>I started writing one based on iteratees, but iteratees aren't fashionable anyway...
<davexunit>wow
<davexunit>I want to try writing a markdown parser with it
<ijp>I had used it once, but it was way overkill for my use case
<davexunit>ijp: thanks for knowing about all the cool libs
*paroneayea keeps going to sleep and waking up with weird fever dreams http://dustycloud.org/blog/fever-dream-cryptocurrency/
<zarac>hello folks
<zarac>so quiet..
<mark_weaver>hi zarac
<zarac>: )
<zarac>heh
<zarac>so, anyway.. i'm new to guile. just testing it out.. following info guile..
<zarac>got an issue :
<mark_weaver>what's up?
<zarac>How come.. when i run `export HOSTNAME=foobar ./simple-guile` (my-hostname) prints 'foobar', but when i run `export HOSTNAME=foobar ./simple-guile simple-guile.guile` the expected 'foobar' is not displayed. (simple-guile.guile is just (my-hostname)).
<zarac>that took a while to type.. ; )
<zarac> http://sprunge.us/RKKK
<zarac>that was simple-guile.guile
<zarac>and here's simple-guile.c : http://sprunge.us/dVRO
<mark_weaver>you aren't doing anything to print the result of (my-hostname)
<zarac>i have to (display (my-hostname)) ?
<mark_weaver>the way you wrote that script, the result is being ignored
<zarac>omg
<zarac>nevermind
<zarac>: )
<zarac>ok
<zarac>thanks
<mark_weaver>:)
<zarac>:)
<mark_weaver>btw, guile has 'getenv' built in from scgeme
<mark_weaver>scheme
<mark_weaver>(getenv "HOSTNAME")
<zarac>yeah, i fugred it did. and i was wondering what it was, thanks again. ; )
<zarac>s/fgured/figured
<mark_weaver>np
<zarac>how awesome is guile?
<zarac>=D
<zarac>got another question..
<zarac>some compiled / temporary files are stored somewhere (..?) where?
<mark_weaver>btw, to specify environment variables while running a single command, you don't need to write 'export' there.
<mark_weaver>you can just write "HOSTNAME=foobar ./simple-guile"
<zarac>the first time i run a guile script it displays some compiling information.. but not the second time it's run..
<zarac>oh, yeah, thanks : )
<mark_weaver>zarac: they are stored in ~/.cache/guile/ccache
<zarac>i actually didn't write export.. not sure why i did when i asked ; )
<zarac>ah, sweet
<mark_weaver>it should have told you where they were being stored when it did the compiles, no?
<zarac>geez, can't belive i missed that : )
<zarac>actually read it.. guess i'm dyslectic
<zarac>or something.. =D
<mark_weaver>heh :)
<zarac>so, how awesome is it?
<zarac>guile? .
<zarac>don't like opinion questions? : )
<mark_weaver>it's a meaningless question
<mark_weaver>and also very subjective
<mark_weaver>I'm overloaded, no time to try to answer such questions, sorry
<zarac>hehe, np. thanks again for your help. much appreciated!
<mark_weaver>np
<mark_weaver>it's my programming environment of choice, anyway...
<zarac>: ) after just being introduced to it, i can understand.
<zarac>what editor do you use/recommend?
<zarac>emacs i suppose?
<zarac>i mean for interactive programming..
<taylanub>zarac: Emacs with Geiser
<zarac>sweet
<daviid`>zarac: http://wingolog.org/archives/2013/01/07/an-opinionated-guide-to-scheme-implementations
<zarac>thank you, sirs
<zarac>haha, ; )
<zarac>spot on
<zarac>daviid`: great article.
<daviid`>wc! thanks wingo!
<zarac>thanks wingo! =D
<daviid``>oftopic quiz: is there a gnu make way for: make uninstall --purge [or something like that]
<daviid``>thta wuld lete the directories install created ?
<davexunit>it is possible to pass a port to a C function via the FFI?
<ArneBab_>zarac: I consider guile as pretty awesome ☺ my longer answer is in http://draketo.de/proj/py2guile
<mark_weaver>make targets don't support options
<daviid``>mark_weaver: thanks
<mark_weaver>daviid``: but I can tell you how to delete all directories in a tree that contain no non-directories
<ArneBab_>daviid``: I think you’d have to add a purge command
<davexunit>I see that I can get a port's file descriptor. Do I just create a foreign pointer containing it?
<mark_weaver>davexunit: do you want the C function to receive the file descriptor or the SCM port?
<davexunit>mark_weaver: the file descriptor.
<davexunit>it's an existing function in a shared library
<davexunit>that knows nothing of guile
<civodul>there's 'fileno' and 'port->fdes' but read the manual carefully
*civodul always forgets which one does what
<mark_weaver>davexunit: well, I guess you should use either port->fdes or dup->fdes and then it's just an integer, to pass like any other integer
<mark_weaver>right, fileno also
<mark_weaver>not sure which one you should use offhand.
<davexunit>okay
<davexunit>the function takes a "FILE *"
<mark_weaver>oh, that's different.
<mark_weaver>that's a bit squirrelly, to have two different buffered I/O implementations talking to the same underlying FD.
<daviid``>mark_weaver: since there is no such purge target [per default], i'd like to write 1 configure.ac/Makefile.am, if possible
<davexunit>hmm, okay.
<mark_weaver>I guess maybe it could be managed by making sure to flush before going back and forth, but there may be other issues when you close them.
<mark_weaver>davexunit: the C library has 'fdopen' that allocates a FILE* based on an already-open file descriptor.
<davexunit>so it would be best to use that new file descriptor for the foreign call?
<daviid``>like: cd /your/prefix; find . -name yourproject -exec rm -rf {} \\; will talk to autoconf, someone prob has done this before... tx
<mark_weaver>I don't remember off-hand whether closing a FILE created with 'fdopen' will call 'close' on the underlying FD.
<davexunit>I'll find out
<mark_weaver>I also don't remember off-hand whether duplicating an FD leaves them each with an independent file position.
<civodul>davexunit: if you want to use exclusively the FFI, you could try to make a custom binary port that uses fread, fwrite, & co.
<mark_weaver>no, they have a shared position
<mark_weaver>civodul: but if the C function he wants to call expects a FILE*, how could that be connected to a custom binary port? I suppose it could be done with a pipe.
<davexunit>mark_weaver: looks like it closes it
<davexunit>this throws:
<davexunit>(call-with-output-string
<davexunit> (lambda (port)
<davexunit> (close (fdopen (port->fdes port) "w"))
<davexunit> (display "foo" port)))
<davexunit>oops, pardon formatting.
<mark_weaver>davexunit: my first guess is that you should dup->fdes and then call C 'fdopen' to create a FILE* and then pass that to the function.
<mark_weaver>and then you need to call 'fclose' on that FILE* at some point.
<mark_weaver>davexunit: okay
<mark_weaver>also, you'll probably also want to 'force-output' before calling the C function, to make sure that guile has flushed pending output to the port.
<davexunit>okay
<davexunit>I'll try dup->fdes now
<mark_weaver>and then whatever the C function wrote will need to be flushed before Guile writes anything more to the port.
<mark_weaver>calling 'fclose' is one way to do that.
<davexunit>got it
<mark_weaver>or use 'fflush' if you want to flush before closing.
<mark_weaver>(before closing the FILE* and duplicated FD... the original FD will stay open after the 'fclose')
<davexunit>I can't seem to keep the port open after closing it...
<davexunit>there's a 'close' procedure, but not 'fclose'
<mark_weaver>the C library has 'fclose', which takes a FILE*
<mark_weaver>that's the one you'll need here
<davexunit>ah okay, a foreign procedure.
<davexunit>got it.
<mark_weaver>davexunit: out of curiosity, what are you working on?
<davexunit>mark_weaver: I'm just messing around at this point, but I'm playing around with the fpgatools libraries with the FFI
<mark_weaver>will guile actually be writing anything to this port?
<mark_weaver>or only the C functions?
<davexunit>I'd like to create a wrapper that accepts any output port
<mark_weaver>oh, well, not all ports have FDs
<davexunit>hmm, maybe I should just write to an output string and return that
<mark_weaver>davexunit: string ports don't have FDs
<mark_weaver>davexunit: maybe a 'pipe' is the right answer here.
<mark_weaver>or a temporary file
<mark_weaver>the issue with pipes is that if you try to write too much to them, it will block until the reading happens. so the writer and reader really need to be in different threads (or processes)
<davexunit>mark_weaver: and then read the temp file and write it to a port?
<mark_weaver>davexunit: right
<davexunit>mark_weaver: sounds like the best solution.
<davexunit>I'll do that.
<mark_weaver>hmm, although I see that glibc has "string streams"
<mark_weaver>see 'fmemopen'
<mark_weaver>but the temporary file method is fine, even if it seems a bit clunky
<mark_weaver>glibc also has "custom streams".
<mark_weaver>see section 12.21 of the libc manual (Other Kinds of Streams)
<mark_weaver>I suppose we could use those to convert an arbitrary scheme port to a FILE*, but only on glibc.
*mark_weaver never knew about 'fopencookie' before.
*mark_weaver tries writing port->FILE*
<civodul>yeah i think the trick is to use fopencookie to encapsulate a port, or a custom binary port to encapsulate a FILE*
<mark_weaver>right, one technique for each direction
<mark_weaver>fopencookie to implement port->FILE*, and a cbp to implement FILE*->port
<mark_weaver>I'm working on the fopencookie thing now
<daviid``>it appears we don't (nobody does?) install LICENSE, COPYING, NEWS... in $pkgdatadir, is this right? it seems once 'make install' is done, if you delete $scrdir, then none of these files are 'visible' to the user
<mark_weaver>davexunit: http://paste.lisp.org/+354M
<mark_weaver>^^ convert arbitrary scheme ports into FILE* (for glibc only)
<davexunit>mark_weaver: wow, awesome!
<davexunit>thanks!
<mark_weaver>np! :)
<mark_weaver>daviid``: right
<davexunit>I'm eager to see if the floorplan generated from my guile-fpga program is exactly the one generated by one of the examples written in pure C.
<mark_weaver>davexunit: so, with that, there's no need to flush the scheme port before calling into C. however, you *will* need to call 'fflush' after calling the C function.
<mark_weaver>(and at some point you should call 'fclose' also)
<davexunit>alright, I can do all of that from the wrapper procedure
<mark_weaver>davexunit: the "modes" argument should be "r" or "w" for single-direction ports.
<davexunit>got it.
<mark_weaver>or "r+" for bidirectional. it corresponds to the OPENTYPE argument of 'fopen'.
<mark_weaver>(see the libc manual)
<mark_weaver>also, I'm not sure if the existence of that FILE* will protect the associated port from the garbage collector.
<mark_weaver>(I wouldn't count on it)
<davexunit>okay
<davexunit>mark_weaver: wow, it worked! yay!
<mark_weaver>woohoo!