***michaniskin is now known as Guest6263
***cluck` is now known as cluck
<wingo>when would it be? 14th or 15th or so? <nalaginrut>alas~I have to prepare it in 10 days, but I've no idea yet... <wingo>i have been meaning to write a new bit of photo gallery software, maybe i could get a proto out by then <wingo>then once the backend and service is done i could get help from someone to make it nice to use <nalaginrut>maybe one of the easy way for me is to make guile-lua-rebirth playable, but maybe I should try a game with sly, which is more playable... *nalaginrut used the wrong word since it's not easy at all... <jmd>Whats the easiest way to chomp leading/trailing whitespace from a string? <jmd>I have a list of strings, all of the form ("key1=value1" "key2=value2" ...) <jmd>and I want to convert it into a alist. <jmd>I guess I should just use map ? <jmd>Anyone know of a routine to pretty-print an alist? <taylanub>jmd: find guile-source/modules -name \\*.scm -exec grep pretty-print {} + # ice-9/pretty-print.scm:(define-module (ice-9 pretty-print) ... :) <wingo>jmd: so i don't know if you know, but if you open the manual in info <wingo>you can press "i" and then type pretty and hit tab and you get some possibilities <wingo>or C-s and type pretty-print and keep typing C-s to search through the matches <wingo>anyway an approach like that will be useful for you i think, many of your questions can be answered that way :) <jmd>Theres a way of reading a scheme fragment from a file and then excuting it. How do I do it? <jmd>But I need to define some things before it is evaluated. <jmd>Like, the file contains say "(foo 2)" <jmd>but foo is not defined in the file, but in the place I'm calling eval/load/primitive-load <mark_weaver>please_help: that only handles a single top-level form <jmd>ERROR: Wrong number of arguments to #<primitive-procedure eval> <mark_weaver>jmd: 'load' and 'primitive-load' do the loading within (current-module) <mark_weaver>jmd: so, arrange to have those things defined in the module that is current when you run 'load' or 'primitive-load'. <jmd>According to the manual I need to pass (interaction-environment) <mark_weaver>the second argument to 'eval' is a module to evaluate it in. <jmd>Anyway it still thinks foo is undefined. <jmd>I've tried all of them so far. <jmd>But you didn't put in any suggestion delimiters, so I may have got some mixed up :) <mark_weaver>I just tried with 'primitive-load' and it works as expected <mark_weaver>why don't you show me precisely what you did with the 'primitive-load' attempt? <jmd> (find-prop my-list (lambda (c) (define (capa x) (assoc-ref c x)) <jmd> (primitive-load "the-file") )) <jmd>And it says ERROR: Unbound variable: capa <mark_weaver>taylanub: probably not, that would be spliced in at compile-time, not run-time. <mark_weaver>jmd: ah, so you want it to have access to lexical (non-toplevel) variables. <mark_weaver>'primitive-load' does not have access to non-toplevel variables, only top-level ones in the current module. <mark_weaver>if you want it to have access to non-toplevel variables, then you need 'local-eval' <mark_weaver>jmd: do you need to handle a file that contains top-level definitions? <mark_weaver>also, do you need to handle a file that contains multiple top-level forms? <mark_weaver>(e.g. where later expressions can refer to definitions made earlier in the same file? <jmd>Now I'm confused ... <jmd>What do I pass as the arg to local-eval ? <mark_weaver>jmd: or if you just want to charge ahead, follow wingo's earlier suggestion :) <jmd>I'm not sure that I understand your questions. <mark_weaver>a top-level definition is something like (define bar 5) that's not wrapped with any other parentheses in the file. <mark_weaver>do you need to be able to handle files that have those? <jmd>At least not at this stage. <mark_weaver>okay, thanks. and the second question is: can we assume that there's only one top-level form? what I mean by that is that if there are any parens in the file, then the first open paren in the file has to be matched with the last close paren in the file. <jmd>No. It will contain only one. <mark_weaver>jmd: in the example you pasted here, replace the call to 'primitive-load' with this: (local-eval (call-with-input-file "the-file" read) (the-environment)) <mark_weaver>see 'local-eval' and 'the-environment' in the manual for details. <mark_weaver>note that (the-environment) will capture more than just 'capa' in your environment. it will also capture 'c' (the lambda argument) and everything outside, including the top-level definitions in the same module. <mark_weaver>it is essentially as if the contents of the file were put right in place of the 'local-eval' call. <jmd>That might cause problems later. Is there a way to limit it to the environment of the lamba expression? <mark_weaver>(assuming that the call to 'the-environment' is directly put in the second argument to 'local-eval') <mark_weaver>jmd: is the set of definitions available to the imported files always the same? <mark_weaver>jmd: then forget 'local-eval'. instead, make a module just for evaluating these things. <jmd>I'll have to read up on how to do that. <mark_weaver>you create modules all the time with 'define-module'? there's nothing special about it. <jmd>I don't think I've ever used that. But I will look it up. <mark_weaver>when I asked "are they always the same" I meant not only "are the set of identifiers available always the same?", but also "are the values of those bindings always the same?" <jmd>Well in this example, (define (capa x) (assoc-ref c x)) will always be the same, but c will change <mark_weaver>there's an issue with top-level modules: currently, they can never be freed <mark_weaver>jmd: ah, okay, nevermind then. better stick with local-eval here. <jmd>ok. thanks for your help <mark_weaver>jmd: another thing to beware: that code I gave you reads only the first expression from the file. if there are any more, they will simply be ignored. this could be made more robust in various ways. <jmd>Ok. I will bear it in mind. <mark_weaver>(define (read-file-as-one-expression port) `(let () ,@(list-ec (:port x port read) x))) <mark_weaver>then replace the call to 'read' in my previous suggestion with 'read-file-as-one-expression' <mark_weaver>it can even handle top-level definitions that will be available only within the file itself. <mark_weaver>(though all of the definitions, if present, must be before the first non-definition) <jmd>I ought to mention that I'm using Guile 1.8.7 for this job <mark_weaver>basically, it wraps the contents of the file within (let () ...) and then evaluates that. <mark_weaver>well, nevermind then. I'm not motivated to try to backport this. <jmd>It seems like only yesterday that I upgraded from 1.6 <please_help>So I want to generate indices for iteration in a list of rank K, where each bound in the K dimensions are known. Is the best way to do that the standard flat -> not-flat conversion? ***dsmith-w` is now known as dsmith-work
<lloda`>please_help: does array-index-map do what you want? see (help array-index-map) <lloda`>either that or reshape a vector #(0 1 2 ...) <lloda`>in guile-ploy that would be either (i. 3 4 5) or (reshape (i. (* 3 4 5)) 3 4 5) ***dje is now known as dje42
<please_help>lloda`: no, I just want to generate the indices, I don't want to set elements of another array (yet). <please_help>I also can't reshape a vector nor multiply the indices together because that would require being able to generate the indices <please_help>(floor [(x-prev)/(product of rest of reverse of dimensions)]) <mark_weaver>(floor/ returns both the quotient and remainder in a single operation) <mark_weaver>they do different things in the case of negative integers <mark_weaver>we have a bewildering array of division operators, actually. <lloda`>so you can use array-index-map! just to generate the indices, kinda <lloda`>the args are (array-index-map! ra proc) <please_help>lloda`, that's a huge waste in both memory and processing power though <lloda`>for ra, you pass a reshaped 0-rank array <lloda`>that only takes one position, no matter how the array is logically <wingo>hehe, lloda` you are using "ra" as an abbreviation for array :) <wingo>took me forever when i was first in the source to figure why that was happening <wingo>must have been mentally mispronouncing it <please_help>lloda`, then that doesn't address the problem at all, does it? <lloda`>wingo: right, it's everywhere, it took me a while to see what that meant... <mark_weaver>please_help: SRFI-42 can be used to generate the indices very nicely <mark_weaver>something like (list-ec (: x 5) (: y 10) (: z 20) (list x y z)) <please_help>DEFINE: (add1 '(0 0 0) '(1 2 3) 1) ;=> '(0 0 1) | (add1 '(0 0 2) '(1 2 3) 1) ;=> '(0 1 0) <mark_weaver>so, given a list of the lengths along each dimension, you want a list of indices? <please_help>Given a list of starting indices and the length of each dimensions, increment the indices correctly <mark_weaver>I have a 'cartesian-product' procedure that's more general than this <lloda`>yeah, that's ndgrid in matlab/octave <please_help>Does it generate the full list of indices? That might be too large for my usage <please_help>I might deal with things that can go 64 x 28 x 28 x 3 <lloda`>so please_help, do you need to generate the full list, or just take the indices and do things with them one at a time? <lloda`>so, let me explain the array-index-map! solution in full :) <mark_weaver>please_help: I'm not sure what semantics you want in the presence of the "starting indices" you're talking about. <lloda`>step 1. define a dummy rank 0 array, (define dummy (make-array #f)) <please_help>so, '(0 0 0) + 1 => '(0 0 1); '(0 0 9) + 1 => '(0 1 0); '(0 4 9) + 1 => '(1 0 0); '(0 3 2) + 1 => '(0 3 3) (etc.) <lloda`>step 2. define a shared array over the dummy, (define A (make-shared-array dummy (lambda i '()) 2 5 10)) <lloda`>now you have (array-dimensions A) => (2 5 10) <lloda`>but this array doesn't take any space at all! <lloda`>now you do (array-index-map! A (lambda (indices) ... #f)) <lloda`>and you do whatever you need with the indices, generated one a time... <please_help>how does make-shared-array handle having more dimensions than the source array? <lloda`>like this: (shared-array-increments A) => '(0 0 0) <lloda`>the index on the actual array is computed as 0*i+0*j+0*k = 0 <please_help>will there actually be a write or is that optimized away? <lloda`>yeah there'll be a write :-/ we should have a proc that just calls with the indices. <mark_weaver>please_help: will the rank be a compile-time constant? would it be sufficient to have a general syntax that can handle any rank, if that rank is known at compile-time for any given use of the syntax? <mark_weaver>(a fully dynamic solution is also possible, just asking because the compile-time constant one could be simpler and more efficiently) <mark_weaver>and will the bounds be in separate variables that you specify, or do the bonuds have to be in a list? <please_help>The bounds are basically specified by (array-dimensions the-arr) which returns a list. Avoiding extra conversions would be good. <mark_weaver>so how about syntax like this: (iterate! <bounds> (i j k) <body> ...) <please_help>(iterate! <bounds> var-to-which-an-index-list-is-bound <body> ...) <mark_weaver>hmm, well, that makes it very awkward to access the indices in <body>, and will be much slower <mark_weaver>maybe the thing is to operate on the result of array-contents? <please_help>That's a problem with the way array-ref, make-array, etc. operate <please_help>they should definitely accept a list instead of idx ... <mark_weaver>will the indices be used in <body> in any way except to index the array(s)? <mark_weaver>then how about using 'array-contents' to create flattened views of all the arrays and then operating on the flattened views? <please_help>I hoped there was a mechanism to use the array-style indices, but of course, that works. <lloda`>please_help, array-ref, etc. all accept a list. You just need to do (apply array-ref the-list). <mark_weaver>there's extra overhead in creating the lists that will be passed to apply <mark_weaver>that's going to mean a lot of allocation, and lots of work for the garbage collector <lloda`>that list will be created anyway, since the implementation of array-ref takes a list. There's specialized versions for 1 and 2 indices but that's it. Anything over 2 will create a list <please_help>is that why arrays accept idx ... instead of idx-lst? <mark_weaver>please_help: 'apply' should be fairly efficient I think, it's creating the list for apply that's the problem. <lloda`>if all you do with the indices is index an array, then you should use array-map, array-for-each, etc. and never create an index list :-/ <mark_weaver>or one of the reasons, anyway. the syntax is also nicer and more convenient in the common case where the rank is known at write-time. <mark_weaver>(and syntax can always be easily customized with 'define-syntax-rule') <mark_weaver>(define-syntax-rule (my-array-ref array indices) (apply array-ref (list indices))) <mark_weaver>(define-syntax-rule (my-array-ref array indices) (apply array-ref indices)) <mark_weaver>gah...(define-syntax-rule (my-array-ref array indices) (apply array-ref array indices)) <mark_weaver>but yeah, if you can otherwise avoid allocations in the inner loop, allocating those lists will kill your efficiency. <lloda`>please_help, there's no way to do what you want to do with array-for-each or array-map! ? <lloda`>avoid creating index lists that are used only for indexing <mark_weaver>yeah, lloda`'s suggestions may well be the best way to go here <please_help>I can't use array-map! because I need to know which "row" I'm on, for example. <lloda`>that makes sense, it happens often :/ <mark_weaver>please_help: I asked earlier "will the indices be used in <body> in any way except to index the array(s)?" and you said "no". <mark_weaver>if you need to know the row, then the answer should have been "yes" :-P *mark_weaver goes afk for a bit <please_help>(array-ec (: idx the-first-k--2-dimensions) (array-almost-map (lambda (x) (/ x (reduce + 0 (row-of x)))) (matrix-for-index idx)))) basically <lloda`>so you iterate over the first k-2 dimensions and sum over the last 2? <please_help>no, I produce x/(sum-of row-of x) for each element in the last 2 dimensions <please_help>row being defined as the 1st dimension in the last 2 dimensions. <lloda`>ok. and you want the result as a new array? <please_help>though I can allocate the array first and then copy the elements <lloda`>lots of opportunities for hm, improvement <lloda`>my times in 2.1.0.1337-15e47 are 0.428965702 for the raw-Guile and 1.415675267 for the guile-ploy version <lloda`>actually there's no reason to do a double loop (?), it's just sum over the last dimension... <lloda`>times are now 0.241278392 for the raw-Guile and 1.092403753 for the guile-ploy version <jgrant>Guile's documentation reads very quirky to me at least much more-so than other GNU Documentation I've read, is this just on my end? <jgrant>I mean it seems to fairly effectively convey information, just the way it accomplishes this is bit odd and/or unexpected to me. :^P <davexunit>you can tell that large chunks are written by different people with different technical writing styles. <davexunit>I really like the manual, though, despite the quirkyness. <daviid>lloda`: where is guile-ploy hosted?