IRC channel logs

2015-09-27.log

back to list of logs

<taylanub>if I use (list uint8 uint8) instead of (list uint16) for a function returning a 'struct { uint16_t x; }', won't I get a pointer to a two-byte array with the bytes of the uint16 ordered in native endianness? that would be sufficient for me. my system is aware of endianness, alignment/padding, etc., so if I get a pointer to the raw bytes laid out in a fairly conventional layout, that should cover
<taylanub>most archs I think?
<mark_weaver>taylanub: I'm sorry, but if you're not able to give libffi the information it needs, then this is not a viable approach, IMO.
<mark_weaver>and you should not determine was works by experimentation on the systems you happen to have around to play with
<mark_weaver>s/was/what/
<mark_weaver>rather, you should be looking at things like C standards to see what guarantees they make
<taylanub>does the C standard guarantee 8-bit bytes nowadays? :)
<mark_weaver>I'm sorry, I don't understand your question.
<mark_weaver>does the C standard guarantee <...>?
<mark_weaver><...> there needs to be a statement, not a noun phrase.
<taylanub>I haven't read much from any C standard, but from what I keep hearing, it guarantees very very little
<mark_weaver>it guarantees a lot of stuff
<mark_weaver>what you've heard doesn't imply that it guarantees very little, but rather that it fails to guarantee some things that people intuitively expected it to guarantee.
<taylanub>(I meant to ask whether it guarantees that a char is 8 bits wide)
<mark_weaver>I don't remember off hand, but it guarantees a fair bit about structure layout
<mark_weaver>however, returning to the question at hand:
<mark_weaver>if it's a problem to distinguish (list uint8 uint8) from (list uint16) in a returned structure, then I suppose it will also be a problem to distinguish (list uint8 uint8 uint8 uint8) from (list double), eh?
<mark_weaver>and if so, you're already screwed
<mark_weaver>or at least I think you are
<mark_weaver>because I suspect that some ABIs optimize structures that can fit within a register, and may choose that register based on whether it's a floating-point value or an integer.
<mark_weaver>*optimize structures that can fit within a register, when used as a return type, and maybe also argument types
<taylanub>hmm, indeed, I was thinking of handling all structs uniformly, so I would try representing a struct with a double64 as a struct with 8 uint8s
<taylanub>maybe I'll just look into how I can attach more metadata to descriptors so a full conversion is possible at least for the most common types: numbers, pointers, structs. is a foo[n] argument just a pointer for libffi?
<mark_weaver>yes to the last question
<mark_weaver>well, that's a fact about C, not libffi
<taylanub>indeed... kinda confusing that structs are passed by value (copied) but fixed-length arrays by reference. I tend to think of them as conceptually similar. anyway.
<taylanub>mark_weaver: thanks for all the help. I guess I have to do it the hard way.
<please_help>arrays obey pointer semantics "most of the time" whereas structs don't.
<please_help>also arrays live on the stack as opposed to pointers which you consider to be arrays don't they?
<please_help>(which could exist on the heap)
<taylanub>AFAIUI, a function-local declaration foo_t x[n]; for a constant n will allocate sizeof(foo_t) * n bytes on the stack and make x point to it.
<daviid>paroneayea: guile-squee is autotool chainned, and make distcheck pass
<paroneayea>daviid: \\o/
***androcles is now known as androclus
<goglosh>do we have r7rs compliance yet?
<goglosh>compliance/compatibility/something
<mark_weaver>goglosh: no
<mark_weaver>there's a branch in our git repo that implements most of it
<goglosh>so, I'd have to build it?
<goglosh>or is it guile code?
<mark_weaver>but I don't have much confidence in the R7RS-large process, and I've been having second thoughts about whether to support R7RS
<goglosh>oh, why so?
<mark_weaver>well, R6RS exists, and IMO is superior to R7RS.
<mark_weaver>and R7RS is completely incompatible with R6RS
<mark_weaver>so there's a fork in the road for the scheme community
<goglosh>ooh I see
<goglosh>completely incompatible
<mark_weaver>and at the moment, I'm inclined to follow the R6RS path instead
<mark_weaver>R6RS has been fairly well supported by Guile for some time now
<goglosh>yes that I notices
<goglosh>notied
<goglosh>it makes sense to keep it that way
<mark_weaver>we will certainly continue to support R6RS
<mark_weaver>we *may* support R7RS in the future, but I'm not yet sure about that
<goglosh>is it a much fundamental incompatibility?
<mark_weaver>no, not fundamental, but the syntax for writing both libraries and programs are gratuitously incompatible, such that there's no way to write even the simplest library that works with both.
<mark_weaver>terrible
<goglosh>oh
<goglosh>sounds deliberate
<mark_weaver>the R7RS was written by the subset of the scheme community that didn't like R6RS, and mostly pretended it didn't exist and started from R5Rs
<goglosh>^ yes
<mark_weaver>R5RS and built in a deliberately incompatible direction
<goglosh>man the schism of the lisp community at every level
<goglosh>:(
<mark_weaver>there are some details that are difficult to reconcile, e.g. 1.0+0.0 is a real number in R7RS but not a real number in R6RS.
<mark_weaver>but I would just ignore the R7RS on that issue
<mark_weaver>the R6RS included substantial and well-designed improvements to numerics, which were mostly ignored by R7RS
<goglosh>I still don't understand what exactly is it that people didn't like about r6rs
<mark_weaver>s/1.0+0.0/1.0+0.0i/
<zacts>hello guilers
<mark_weaver>hi zacts!
<zacts>hey mark_weaver! :-)
<zacts>ah, sad. mark_weaver: https://news.mit.edu/2015/frank-urbanowski-director-mit-press-dies-79-0921
<zacts>davexunit: https://news.mit.edu/2015/frank-urbanowski-director-mit-press-dies-79-0921
<zacts>I don't know how to tell the bot to give the link to davexunit
<artyom-poptsov>zacts: To tell the bot to pass a message to a person you should use the following command: "sneek: later tell <person> <message>"
<tj_>what should i do to a script so that i can chain it up between bash pipes? : ./script.py arg | ./guile_script.scm | ./some_other_script.hs
<tj_>it's pretty easy to do in haskell, there's a special function in System.IO called interact
<artyom-poptsov>tj_: When you're working with Unix pipes, you're basically using stdin (standard input) and stdout (standard output).
<tj_>artyom: Da, and? does guile have special functions for it? spasiba
<artyom-poptsov>So if you want to read a data from a pipe (stdin), you could just use Guile IO procedures like 'read-line'.
<artyom-poptsov>tj_: Пожалуйста :-)
<tj_>: D
<artyom-poptsov>Same with output -- print anything you want to stdout and then the next program in the pipe will be able to read it.
<tj_>do you happen to know in which module does read-line jivet? : ))
<tj_>is it ice-9 popen?
<artyom-poptsov>(ice-9 rdelim), i think.
<tj_>ah, kewl
<tj_>i knew how to say cool
<tj_>kruta : DD
<tj_>is that right? : ))
<artyom-poptsov>You're right. :-)
<tj_>Horosho
<artyom-poptsov>tj_: Besides, warmest welcome to the Guile community.
<tj_>thanks, it's my first time here, really, thanks
<tj_>i'll stick around, i love scheme
<artyom-poptsov>Great.
<artyom-poptsov>Is Russian your native language?
<tj_>nah, i'm romanian, i once had a russian flatmate
<tj_>and i read Metro : ))
<artyom-poptsov>I see.
<artyom-poptsov>tj_: Well, hi from Russia. Alas, I need to go. See you!
<tj_>seeya : )
<tj_>we have similar time-zones
<roelj>How would I return a list from C to Guile? So, let's say I parse some stuff in C that is a list of integers. I'd like to work with it in Scheme/Guile as if it were (1 2 3 4 5).
<please_help>let ((ret (make-s32vector 5))) (c-function (s32vector->pointer ret)) ret)
<please_help>and actually (s32vector->list ret)
<roelj>Is there no way to represent a list using the SCM type?
<please_help>are you using the guile c api instead of the ffi?
<roelj>Yes, I'm using the Guile C API
<please_help>then there's scm_make_list and the SCM_SET* macros.
<roelj>Hmm, I overlooked that. I'm going to dive in the reference manual again. Where is it described?
<roelj>Can't seem to find it in 2.0 and 2.2 reference manuals.
<iyzsong>Yes, I find scm_cons but no scm_make_list. And I think use vector in C is more easy than list.
<roelj>I see
<roelj>I also found scm_array_to_list
<roelj>I could also use scm_cons on a scm_cons-created object to make a longer list.
<roelj>Thanks for the help. I'm going to try these options.
<mark_weaver>roelj: see section 6.7.2.3 (List constructors) in the guile manual
<mark_weaver>scm_list_* might be appropriate
<mark_weaver>or 'scm_cons' and SCM_EOL
<mark_weaver>SCM_EOL is ()
<roelj>mark_weaver: Thanks!
<mark_weaver>np!
<roelj>Is there also a 'scm_prepend', or is the performance of 'scm_append' equally good?
<taylanub>roelj: what exactly would this scm_prepend do? do you perhaps just want cons?
<taylanub>(cons 'x '(y z)) => (x y z)
<mark_weaver>roelj: how would scm_prepend be different from scm_append ?
<roelj>taylanub: Ah yes you're right. I want cons instead. I thought I could add an element to a list using the scm_append function.
<roelj>So I thought in that case, append would have to walk to the last element, while prepend could just add it in front.
<roelj>But that's not how the scm_append funciton works..
<taylanub>(append '(x y) 'z) => (x y . z) ;this is kind of a special-case I think, or implementation detail...
<taylanub>append does indeed walk to the end
<mark_weaver>not quite
<mark_weaver>well, it has to copy all the lists except for the last one
<mark_weaver>so it takes time proportional to the total length of all the lists except for the last one (which is reused)
<roelj>Does scm_append simply cons the second list to the first?
<mark_weaver>roelj: it doesn't modify any existing lists. it creates a new list
<mark_weaver>but the last list ends up being reused in the result, so it doesn't need to be copied.
<roelj>So it allocates a new list of the size of the combined length of the already-existing lists?
<roelj>Oh.
<mark_weaver>well, in scheme, lists are linked lists of cons cells (called "pairs"). there is one cons cell for each element in the list.
<mark_weaver>so 'append' has to allocate a cons cell for every element that's not in the last list passed to it.
<taylanub>oh right, it's 'append!' (not append) that may walk and set the cdr of the last pair (but isn't guaranteed to do so either), right?
<roelj>Right.
<roelj>I meant, right for mark_weaver . I don't know taylanub.
<mark_weaver>taylanub: that's right
<mark_weaver>'append!' is permitted (but not required) to modify the lists you pass it in order to create the result.
<roelj>I have one other question. When I compile a C library for use with Guile. And I load it in a Guile interpreter.. Can I somehow guarantee it won't spawn more than two threads at any time (if my C code obeys this rule, and I don't explicitly spawn new threads in the scheme code).
<roelj>It's kind of silly, but it's an artificial rule for an assignment I'm trying to use Guile for.
<mark_weaver>so, (append a b) where 'a' has 2 elements and 'b' has a million elements, allocates 2 cons cells and is basically equivalent to consing those two elements to the front of 'b'.
<taylanub>roelj: if you point out that Guile uses some extra threads for purely internal reasons (I don't know what but AFAIK it does some things), maybe it will be fine for the assignment?
<mark_weaver>roelj: Guile creates an auxiliary thread for handling signals, but otherwise does not create any threads unless you use one of the procedures that explicitly creates threads.
<roelj>Ok. Is that somewhere explained in the manual as well? (sorry I haven't looked)
<mark_weaver>roelj: probably not. in general, we reserve the right to create auxiliary threads, i guess.
<mark_weaver>however, it's possible to build guile without thread support at all
<roelj>I believe it doesn't work any different from Java or Python, or does it?
<roelj>mark_weaver: That would be quite interesting.
<mark_weaver>I'm sorry, my knowledge of Java and Python is not sufficient to answer that question, and it's a very broad question anyway.
<roelj>Sorry. It is.
<roelj>Well, I'm going to have a chat about whether these auxiliary threads are tolerable.
<roelj>Thanks a lot!
<mark_weaver>but if you build guile from source code, passing --without-threads to configure, then it should not create threads.
<roelj>Awesome!
<mark_weaver>one more thing though.
<mark_weaver>bdw-gc uses multiple threads by default to do marking during garbage collection
<mark_weaver>but I believe that can probably be disables by setting GC_MARKERS=1
<roelj>Ok
<roelj>that is a shell environment variable, isn't it?
<mark_weaver>yes
<roelj>Col
<roelj>I have to give it a try then
<roelj>Thanks a lot guys!
<mark_weaver>'ps' can show threads, so you can also check by experiment
<roelj>yep
<mark_weaver>(although it may be hard to run it at the right time when GC runs)
<mark_weaver>good luck!
<roelj>Well, if it isn't detectable using that method, it is fine anyway ;)
<mark_weaver>I suppose creation of threads would also show up on 'strace'.
<mark_weaver>although I'm not sure of the details
<mark_weaver>I think it's possible to build bdw-gc without thread support also, if needed
<zacts>sneek later tell davexunit https://news.mit.edu/2015/frank-urbanowski-director-mit-press-dies-79-0921
<sneek>Got it.
<amz3>naquada+rainbow parens is very nice
<amz3>next: smartparens