IRC channel logs

2014-02-27.log

back to list of logs

<didi>Is there some mechanism in the FFI that converts strings to arrays of chars using C functions declarations? e.g. (pointer->procedure void "foo" (list string))
<davexunit>didi: string->pointer ?
<davexunit>I may be misunderstanding you
<didi>davexunit: Right, right. But I want to call the procedure with a string as an argument.
<didi>(foo "bar") and not (foo (string->pointer "bar")).
<davexunit>so write a wrapper function that does the conversion?
<didi>davexunit: Sure.
<davexunit>if foo calls C code, then you need to do some sort of transformation.
***haroldwu_ is now known as haroldwu
<Televangelor>In what way can one run a command and capture the output of that command in guile?
<didi>davexunit: Something like <http://pastebin.kde.org/plchxy1v7/rv2xao>, but classier.
<davexunit>Televangelor: what do you mean by "capture the output"
<davexunit>write to a file? display on screen? assign to a variable?
<davexunit>didi: oh I was thinking simpler.
<davexunit>for what you're trying to do there, you probably want a macro instead.
<didi>davexunit: Macros, bad. Procedures, gud. :^P
<davexunit>well they're good when you're generating code! which it looks like you're trying to do.
<didi>davexunit: Nah, (lambda args ...) take care of it for me.
<didi>davexunit: You are probably right tho.
<didi>davexunit: Hum, `pointer->procedure' looks like a procedure to me. I wonder how does it generate a lambda with a fixed number of arguments.
<didi>How strange. I'm not finding the definition of `pointer->procedure'.
<nalaginrut>morning guilers~
<didi>Ah, it's a naughty C function.
<didi>AFAICS it's a procedure but, as it's implemented in C, it can output another procedure with the right amount of parameters.
<mark_weaver>Televangelor: I guess you probably want 'open-output-pipe' from (ice-9 popen)
<mark_weaver>Televangelor: sorry, I meant to say 'open-input-pipe'.
<mark_weaver>though it's more robust to avoid the shell (with all its complications of proper quoting of arguments) and instead use 'open-pipe*' with OPEN_READ as its first argument.
<mark_weaver>Madsy: if you were going to do another test of Guile on Windows, you might want to hold off a bit. I'm about to add more gnulib modules and make more things work on Windows.
<didi>Crude. I need to use `syntax-case', don't I?
<mark_weaver>for what?
<didi>mark_weaver: For a better version of <http://pastebin.kde.org/plchxy1v7/rv2xao>. Specifically, I want to generate a lambda with the right number of parameters.
<mark_weaver>I'm pretty sure this can be done with syntax-rules macros
<didi>Ah. Good.
<mark_weaver>it's a little tricky though, best done with the help of 'ck'.
<didi>mark_weaver: `ck'?
<mark_weaver> http://okmij.org/ftp/Scheme/macros.html#ck-macros
<mark_weaver>recent versions of guile include 'ck' in (system base ck)
<didi>mark_weaver: 2.0.9?
<mark_weaver>the basic problem you have to confront is that macros are evaluated from the outside in, and they are only evaluated in places where expressions are expected.
<mark_weaver>iirc, 'ck' has been in guile since 2.0.7.
<mark_weaver>although it's small enough that it wouldn't be a problem to include it in your own code.
<mark_weaver>in this caes, it might be easier to just use syntax-case.
<mark_weaver>s/caes/case/
<didi>mark_weaver: I'm still considering if it's worth the effort just to avoid a rest parameter.
<mark_weaver>well, there's also the fact that you're doing more work at each call than you need to.
<mark_weaver>your wrappers are not as efficient as they could be.
<didi>mark_weaver: I can pre-compute more stuff.
<mark_weaver>I'm writing a macro for you
<didi><3
<mark_weaver>or at least for you to look at.
<mark_weaver>didi: http://paste.lisp.org/+313L
<mark_weaver>didi: use ,expand at the REPL with various things to see what it expands into.
<didi>mark_weaver: Very cool. Thank you.
<mark_weaver>I haven't actually tested it, other than to look at the expansions...
<didi>Nah, no worries.
<mark_weaver>btw, this macro assumes that the list of arg-types will not have a quote in front of it. instead it should just be a parenthesized list of expressions, e.g. (int string '*)
<mark_weaver>for example, try: ,expand (pointer->procedure* int blah (int string '*))
<didi>mark_weaver: Nice.
<didi>Ah, `generate-temporaries'.
<didi>Tricky.
<mark_weaver>one thing: I haven't actually evaluated the GC-safety of this, and I wonder about it.
<didi>What do you mean?
<mark_weaver>well, I think the string could be freed when the SCM foreign-pointer object is no longer accessible.
<mark_weaver>and it's not clear to me that the SCM foreign-pointer object returned by 'string->pointer' will necessarily stay alive until the C function returns.
<mark_weaver>so you might need to arrange for that specifically.
<didi>mark_weaver: I've been worrying about it lately.
<didi>AFAICT, Guile's FFI philosophy is to not let others alloc/free memory themselves.
<didi>So sometimes I don't know for how long something will be available.
<mark_weaver>wingo is a good person to ask about this.
<didi>But your remark about `string->pointer' worries me. I thought it would last at last until we return from C.
<mark_weaver>I could do the research, but he probably already knows without having to research it.
<didi>s/last/least
<didi>I've been happily passing pointers to strings to C functions.
<didi>Maybe I might need to wrap them with `let's.
<didi>(let ((string-ptr (string->pointer "foo"))) (call-c string-ptr))
<mark_weaver>well, 'let' won't necessarily solve the problem, if indeed there is a problem at all (i'm not sure)
<mark_weaver>my impression is that the code you just wrote with 'let' is likely to be optimized into the current code anyway.
<didi>Uuuuuh...
<didi>Stalemate.
<nalaginrut>alas, after reading this article, I'm considering to drop ORM to implement a new SQL-mapping, let alone ORM took me long painful time to write too...
<nalaginrut> http://www.codinghorror.com/blog/2006/06/object-relational-mapping-is-the-vietnam-of-computer-science.html
<mark_weaver>at present, I believe that arguments to procedures are kept alive until the procedure returns, but I don't know if that's guaranteed to remain the case in future guile or not.
<didi>mark_weaver: I wonder what would be the solution then.
<didi>Also, there is the problem of C functions wanting strings but refusing to copy it, so one has to hold a reference to it as long as the C library demands.
<mark_weaver>well, the solution that comes to mind for me is to pass the objects that you want to keep alive to a top-level dummy procedure that does nothing.
<mark_weaver>(after calling the C function)
<didi>Sounds hacky.
<mark_weaver>well, yes. maybe we should add a core procedure for this purpose.
<didi>We would be easier with we could alloc memory.
<mark_weaver>I don't know of a better solution, though.
<didi>s/with/if
<mark_weaver>would you never free this memory?
<didi>I would. Explicitly.
<didi>`foreign-alloc' and `foreign-free'.
<mark_weaver>what about exceptions? and first-class continuations?
<didi>I don't know enough to know how these impact allocation of memory.
<didi>But as a general rule, FFIs suck.
<mark_weaver>well, if an exception in thrown, you'd want to free this object.
<didi>I still don't understand.
<mark_weaver>if an exception in thrown between 'foreign-alloc' and 'foreign-free', then 'foreign-free' would never be called.
<mark_weaver>s/in/is/
<didi>`foreign-alloc' would probably allocate memory outside GC reaches.
<didi>Why?
<mark_weaver>I think this is so obvious that I don't even know how to clarify.
<mark_weaver>(let ((x (foreign-alloc ...))) (call-c x) (foreign-free x))
<didi>Ah.
<didi>Memory leak.
<didi>That's it.
<mark_weaver>right
<didi>So don't.
<mark_weaver>I think that calling some (keep-alive x) at the end is better, for several reasons including this.
<didi>Well, I'm up for any solution, really. The allocation of memory is the one I'm familiar with from CFFI.
<mark_weaver>it also means that if the continuation is captured somewhere, and a reference to 'x' still exists, that the memory won't be freed.
<mark_weaver>anyway, maybe it's better that we should just decide to guarantee that if you pass a foreign-pointer object to an FFI-wrapped C function, that the pointer will stay alive until the C function returns.
<mark_weaver>I think that's probably currently the case, anyway.
<didi>mark_weaver: That's a start. But it's not sufficient.
<mark_weaver>and we could decide to make that a promise going forward.
<mark_weaver>if you need the string to stay alive longer than that, then you need to keep a reference somewhere else, like in a global hash table.
<didi>Right.
<didi>Which is not ideal. But FFIs aren't either, so.
<mark_weaver>I don't think we should keep these objects alive forever by default, because that's usually not needed and would be a major space leak.
<nalaginrut>mark_weaver: isn't dynamic-wind useful in that memory-leak case? or it can't catch the proper continuation at this situation?
<mark_weaver>btw, I want to again point out that if you configure libgc to handle interior pointers, then all these problems go away and are handled most satisfactorily.
<didi>Crashes are an uglier problem than memory leaks, but we can crash FFIs without the help of the GC anyway.
<mark_weaver>the actual 'char *' pointer to the string data, or the C pointer to a 'make-c-string' object, are interior pointers.
<mark_weaver>if libgc is configured to detect those, then it will keep those objects alive regardless.
<mark_weaver>well, actually I'm not 100% of that either, I confess. I don't know off hand the set of things that libgc scans.
<mark_weaver>maybe we should continue this discussion on guile-devel?
<didi>Well, I don't think I know enough to sustain a discussion, really.
<mark_weaver>well, you could ask the questions.
<mark_weaver>I don't actually mix Scheme and foreign C code all that much. The C code that I do write and use with Scheme are typically specifically written to work nicely with GC, so I don't face these nasty impedance mismatches.
<mark_weaver>wingo has a lot more experience in this area.
<didi>That's *precisely* the money quote: "nasty impedance mismatches"
<mark_weaver>yep :)
*didi hates it
<mark_weaver>out of curiosity, what C library are you wrapping?
<didi>I'm doing some experimentation with GTK+.
<mark_weaver>you know about guile-gnome, right?
<didi>I do.
<Televangelor>mark_weaver, how would one go about executing a command in guile and capturing its stdout in a string?
<Televangelor>system and system* only return the exit code
<Televangelor>Or return it as port, either is fine.
<didi>Televangelor: `with-output-to-string'
<mark_weaver>Televangelor: as I said, use 'open-input-pipe', or better yet 'open-pipe*' with OPEN_READ as the first argument.
<mark_weaver>'with-output-to-string' won't actually work here, because a subprocess needs a proper POSIX file descriptor as its stdout, and a Guile string port isn't backed by a real POSIX file descriptor.
<didi>Oh. That's surprising.
<Televangelor>mark_weaver, oh sorry, didn't see that.
<mark_weaver>Televangelor: both of those return a port that you can read the output from.
<mark_weaver>when you're done, use 'close-pipe' on the returned value to close the pipe and shutdown the subprocess.
<mark_weaver>for robust error handling, check the exit value with something like: (unless (zero? (status:exit-val (close-pipe port))) (error "subprocess didn't exit cleanly"))
<Televangelor>so open-pipe* returns a port? the docs don't seem to clear on that
<mark_weaver>yes. I agree that the docs could use some work.
<mark_weaver>to read everything from the command as a string, you could use 'read-string' from (ice-9 rdelim)
<mark_weaver>you could also use 'read-line' if appropriate, which has the benefit of stripping the line terminator by default (sometimes desirable).
<mark_weaver>I should mention that 'read-string' was added in Guile 2.0.9 (the latest release). 'read-line' is much older.
<mark_weaver>didi: I agree that we could do better here, but fwiw, making that work as expected would require creating a new pipe to act as a bridge between the subprocess stdout and the internal string port, launching a thread to copy the data from the pipe to the string, and arranging to shut down this pipe and thread at the appropriate time.
<mark_weaver>maybe some day we'll have a much more elaborate subprocess module, but it's a big job.
<Televangelor>mark_weaver, well, r6 supports get-string-all which seems to work in guile.
<didi>mark_weaver: oic. Well, it's "surprising" but not much more than that. You already presented another way of accomplishing the task.
<mark_weaver>Televangelor: that's true, and we've had that for much longer.
<Televangelor>Honestly, I think read-line is a bit of awkward nomenclature, 'read' to me as always implied parsing external repraesentations of data
<Televangelor>read-line would imply 'get all the data on one line as values
<mark_weaver>I agree that the R6RS interfaces are nicer.
<mark_weaver>I often consider switching to mostly R6RS code, and importing selected procedures from (guile) and elsewhere when needed.
<Televangelor>Scheme nomenclature in general shows how old the language is, it's almost like English, it evolved enough to no longer make sense. :")
<Televangelor>I like how r6 calls it list-sort instead of simply sort for sorting on lists seemingly breaking the tradition of not giving any function operating on lists the name of it in front of it.
<didi>Televangelor: I would call it `sort-list'.
<Televangelor>That's what I do currently.
<Televangelor>r6 + srfi + whatever modules you want gets you quite far and portably so.
<Televangelor>I really wouldn't mind if you'd just use list:ref and vector:ref where list: and vector: are praefixes.
<Televangelor>Why not ref-vector intead of vector-ref then?
<mark_weaver>given how often lists are used, I'd find it a bit too verbose to prefix all of those procedures with "list:".
<mark_weaver>but I agree that the nomenclature is not very consistent.
<nalaginrut>Televangelor: I think the name 'read-line' is to avoid conflict to GNU Readline involved in Guile
<Televangelor>Well, it could be getline I guess.
<Televangelor>mark_weaver, well, you can choose to import the list libraries and not praefix them.
<mark_weaver>indeed, we can all make that choice independently :)
<Televangelor>This is very common in OCaml, open up the list stuff so map is for lists but you get Vector.map for vectors, unless you're mostly working with vectors.
<Televangelor>I've honestly dabbled into the idea from time to time to completely re-write a feasible standard library from scratch which does away with most of the errors of the past
<Televangelor>The single best thing about is of course that it currently has [<function> <= <expression>] clauses in conds rather than just [<expression> => <function>]
<mark_weaver>I can sympathize with your desire to clean up everything, but I suggest that you resist that temptation :)
<mark_weaver>our community is fractured enough as it is.
<mark_weaver>it's bad enough that we've split into R6RS and R7RS camps.
<Televangelor>Yeah, the reason I'll probably never finish it is because no one will use it and they'd be wise to do so.
<Televangelor>I never really got the need for R6
<Televangelor>R6 added a module system over R5, there was a big need for portable modules but R7 seems to just be "new standard, because we can"
<mark_weaver>well, it depends what you're doing. most programmers want more than R5 + modules, and if there's no standard for the extra stuff then those programs end up being non-portable.
<zRecursive>i feel portable is a joke in Scheme
<mark_weaver>well, quite a bit of portable R6RS code has been written.
<mark_weaver>but it's true that most people don't bother trying to make their code portable.
<mark_weaver>anyway, it's worth pointing out that many other languages have only one popular implementation, and yet they don't get bashed as much as Scheme does.
<zRecursive>It seems it is easy for a program to support different impls in CL. But it is VERY hard in Scheme
<mark_weaver>that's true. CL is a much more comprehensive standard.
<mark_weaver>but why doesn't Ruby get bashed for being non-portable?
<mark_weaver>or perl?
<mark_weaver>somehow, the fact that there are tons of Scheme implementations is counted against us.
<zRecursive>Ruby is ONLY one implementation
<mark_weaver>okay, so if you are content with having just one implementation, then forget about "Scheme" and instead think about "Guile" or "Racket".
<zRecursive>sure, since using Guile, i cannot leave it now.
<mark_weaver>well, if you're concerned about that, I'd recommend writing your code mostly for R6RS and the SRFIs, and limit your use of Guile-specific interfaces where needed.
<Televangelor>mark_weaver, I feel srfi provides a better solution to standard libraries than a core operational standard like R5
<Televangelor>I wouldn't mind if Rx just gave the bare minimal operational semantics not even including things like map, but that's sor tof what R7 small is trying to do anyway
<Televangelor>zRecursive, you have some small options to leave guile, you don't have an option to leave the one ruby implementation at all.
<Televangelor>That said, I write my code portyably enough to be able to run it on multiple different implementations
<mark_weaver>Televangelor: if you prefer R7RS, then you might be interested to know that we have a mostly complete implementation of R7RS-small in a branch in the git repo, and hopefully it will be in Guile 2.0.11.
<Televangelor>Currently testing it on racket and eventually compiling it on larceny or ikarus works fine for me, r6's portable module system really helped
<mark_weaver>zRecursive: also, I think you'd find that thanks to modern scheme macros, it wouldn't be very hard to implement whatever Guile features you need in terms of some other modern Scheme implementation.
<Televangelor>^ that's what I basically do with the module system.
<Televangelor>And just put the non portable small parts into differnet module load paths
<zRecursive>ok
<didi>mark_weaver: Thanks for the macro again. I'm growing new ugly mutated expressions on it.
<mark_weaver>np!
<mark_weaver>didi: fwiw, I'm going to propose that we guarantee that any SCM foreign-pointer passed to an FFI-wrapped C function be guaranteed to be kept alive until the C function returns, and I'm reasonably sure that this has always been the case so far in Guile.
<didi>mark_weaver: Cool. Thank you.
<mark_weaver>I'd be surprised if anyone disagrees with this.
<didi>mark_weaver: I think it's fundamental for a FFI.
<mark_weaver>agreed.
<mark_weaver>I half expect that the response to this proposal will be "well, duh, of course :)"
<mark_weaver>but we should probably make it more clear in the documentation, at least.
<didi>After that we can work forward for a way for keeping it longer. Some C functions expect "buffers" to leave for long periods of time.
<didi>mark_weaver: Indeed.
<didi>s/leave/live
<mark_weaver>didi: in cases where the buffer should be kept alive longer, I would prefer to hold a reference to it during that time instead of explicitly freeing.
<didi>mark_weaver: Sure. I was concerned about you "optimization" remark.
<didi>s/you/your
<mark_weaver>yeah, a proper solution will involve some way to avoid any possibility of the variable being optimized out in the future.
<mark_weaver>but for the foreseeable future, adding the object to a mutable data structure bound to a module top-level variable should be fine.
<mark_weaver>it's hard for me to imagine that Guile could ever optimize away such a thing, given the existing body of Guile code.
<mark_weaver>but I agree that we should have primitives that make this more explicit.
<didi>mark_weaver: Incidentally, how would you expand that macro to call (pointer->string (proc ...)) if `return-type' is `string'?
<didi>Also, will the C string be freed eventually?
<mark_weaver>yes, it will be freed when the foreign-pointer object is no longer reachable.
<mark_weaver>oh, do you mean the C string passed to 'pointer->string' ?
<didi>mark_weaver: Yes.
<mark_weaver>no, you'll have to arrange for that yourself.
<didi>So I need to pointer->procedure the "free" C function.
<mark_weaver>'pointer->string' doesn't (and shouldn't) assume that the pointer passed to it was allocated using malloc.
<didi>Yes.
<didi>That's what I was getting at.
<didi>See? Memory leaks even without `foreign-alloc' and continuations.
<mark_weaver>didi: I suppose I would do something like this: http://paste.lisp.org/+313N
<didi>mark_weaver: Ah, so the symbol `proc' remains untouched.
<didi>I was worried about hygiene (funny).
<mark_weaver>The 'proc' identifier is introduced by this macro. It will be a unique identifier, but all occurrences of it generated by this macro invocation will be the same.
<didi>Oh right. It's called "identifier" inside macros.
<mark_weaver>it won't conflict with any other 'proc' elsewhere, or even a 'proc' introduced by this same macro but a different invocation of it.
<didi>Confusing stuff.
<mark_weaver>in practice, the hygiene just works automatically, unless you specifically work to avoid it.
<didi>mark_weaver: I thought I had to do the `it' trick from the manual.
<mark_weaver>an identifier is more than just a symbol. it includes information about the lexical environment where it occurs, as well as a set of marks that is unique for each macro invocation.
<didi>It goes without saying that I have a very crude understanding of macros.
<mark_weaver>yeah, understanding macros deeply (enough to implement them properly) is one of the most difficult parts of scheme.
<mark_weaver>but the good news is that in most cases, they can be written and used properly without understanding them, and the hygiene just works automatically.
<didi>That's a relief.
<didi>Now I'll expand it to free the `char *' returned.
<Televangelor>mark_weaver, scheme makes it easier than most languages though.
<mark_weaver>didi: fwiw, I'd recommend making a new procedure that works the same as 'pointer->string' but frees the pointer, and then just changing the macro to use that new procedure.
<didi>mark_weaver: Good call.
<mark_weaver>remember that you are generating code here, so it's best to minimize the size of the generated code.
<mark_weaver>anyway, time for me to sleep. happy hacking!
<didi>mark_weaver: Sleep tight.
<civodul>Hello Guilers!
<da4c30ff>Greetings!
<cluck>:)
<Madsy>:)
<didi>Can I generate a keyword with a macro? Like 'foo => #:foo
<mark_weaver>yes, it can be done. what are you trying to do exactly? convert a symbol in the macro input into a keyword in the macro output?
<didi>mark_weaver: Yes. Specifically, I'm writing a GOOPS slot definition and I want the macro to write a `#init-keyword' keyword for me. I found `symbol->keyword' but I don't know if it's the answer yet.
<mark_weaver>well, if 'id' is the pattern variable that matches the identifier, then you want something like (with-syntax ((kw (datum->syntax #'id (symbol->keyword (syntax->datum #'id))))) ...)
<didi>`syntax-case' keeps haunting me.
<didi>mark_weaver: Thank you.
<mark_weaver>np!
<mark_weaver>it takes some getting used to. these macros are a bit trickier than most because they are not merely copying/rearranging their input.
<mark_weaver>I guess you'll have more than one 'kw' and more than one 'id', so it'll be more like (with-syntax (((kw ...) (map (lambda (x) (datum->syntax x (symbol->keyword (syntax->datum x)))) #'(id ...)))) ...)
<mark_weaver>that last '...' is actually where you fill in code, not a real ellipsis.
<didi>Hum. GOOPS doesn't like my macro as one of the slots of a `define-class'.
<mark_weaver>didi: macros are only expanded when they are in expression position.
<didi>Bummer.
<mark_weaver>you can't put a macro use in some other spot.
<tupi>didi: may i ask what you are trying to do? why your slot(def) has to be the result of a macro?
<didi>I'll try writing my own `define-class'. It would be better to use metaclasses but I don't understand them.
<didi>tupi: Because the slot definition is pretty regular and long. And I'm lazy.
<tupi>i could then create a class that has this regurlar and long slot name and inherit it ...
<didi>tupi: Oh, there are many of these slot definitions. In many classes. But they all amount to an identifier, a getter and a setter.
<mark_weaver>didi: it would be much better to use metaclasses to access the gobject information directly, like guile-gnome does.
<didi>mark_weaver: Yeah. I agree.
<mark_weaver>didi: may I ask what you are working on?
<didi>mark_weaver: Nothing in particular. Like I said, I'm just experimenting with it.
<tupi>mark_weaver: speaking og guile-gnome, yesterday, for the first time, glade3 3.6.7, the latest version that reads/writes *.glade file, required by our guile-gnome-2, systamatically seg fault. so unless i would have access to an old machine, i can not evolve my app [kisĂȘ for example], which is kind of a serious [like a disaster :)] problem
<tupi>[it seg fault because what glade 3.6.7 'needs' is not part of the lower level lib(s) any more... ]
<mark_weaver>do you have any idea what changed on your system that might have broken glade3?
<tupi>not really, things removed in the gtk2 libs probably
<tupi>but as i already wrote quite a lot :), we really really need guile-gnome-3
<mark_weaver>I know. I'm just overwhelmed with important things to do. we need more help.
<tupi>i know. but it becomes really a problem now: i can not edit kise's glade file, it is kind of a disaster, which needs 'urgent' measures, i think. i understand that guile core ... but this will never ever end, it's been a couple of years now that i ask [even contributing financially], so i am very concerned
<mark_weaver>tupi: what system are you running? (distro, version)
<tupi>debian testing
<mark_weaver>well, wheezy will be supported for a while longer, so I guess that's your best option at the moment. but I agree that it's becoming increasingly critical.
<tupi>mark_weaver: how about working on this after 2.0.10 ?
<tupi>otherwise it will never be done, i think
<mark_weaver>I'll think it over. I have to go offline for a bit. ttyl!
<tupi>ok, tx
***linas__ is now known as linas
***cluck` is now known as cluck
<didi>*sigh* I suck at macros. Why doesn't <http://pastebin.kde.org/ppj6kruta/z3lelx> work? I'm trying to wrap a `define-class'. In my example, it should just do what a `define-class' does.
<didi>Oh wait. It /does/ work. *sigh* I suck at it even more.
<didi>I'm stuck. Shouldn't <http://pastebin.kde.org/phf9x0oaq/m4fyy3> work?
<turbofail>what did it do instead?
<didi>turbofail: Sorry, I didn't include the error message. <http://pastebin.kde.org/pjcvwncjc/lnyian>
<didi>It's as if `define-class' expands before `my-slot'.
<turbofail>well i'm pretty sure it does
<didi>Bah `define-class'...
<didi>Bad, even.
<turbofail>that's not define-class's fault, i'm pretty sure that's just how macros work
<didi>turbofail: Can't a change the flow somehow?
<didi>s/a/I
<turbofail>well if you call my-slot as a function on syntax instead, that might work
<didi>You mean, turn `my-slot' into a function?
<turbofail>yeah
<didi>Hum.
<didi>Same error. I /think/ `define-class' is not letting `(my-foo id)' eval, so it tries to interpret it as a slot expression.
<didi>Ah!
<didi>#` and #, to the rescue.
<didi>turbofail: Cool, your idea worked. Thank you.
<didi>Good ol' `(...) expressions.
<turbofail>np
<didi>This is the working version if anyone is curious <http://pastebin.kde.org/pmavwzdk9/kjpyee>.
<turbofail>an alternative for my-slot could be (lambda (x) (syntax-case x () (id #'(id #:init-value 42))))
<turbofail>you'd probably want it to use the syntax-case destructuring if you were doing something more complicated with it
<didi>turbofail: Cool. Thank you. .oO( search for "syntax-case destructuring" )
***u_l-lap is now known as unknown_lamer
<taylanub>didi: Destructuring is what syntax-case templates do, like when you have input (foo (bar) baz) and in your template you do (x y z), you get x=foo, y=(bar), z=baz
<didi>taylanub: oic
<taylanub>didi: The `match' macro from (ice-9 match) can do the same thing on arbitrary data. In Common Lisp it's called `destructuring-bind', which might be where the term comes from.
*didi shoots macros
<didi>It's too hard!
<didi>I'm trying to generate a keyword <http://pastebin.kde.org/pxdrfczyd/om4wze>. I suspect that the `my-slot' is receiving a syntax object, which causes problems for the `with-syntax' expression.
<mark_weaver>my-slot shouldn't be a macro, given the way you're using it. it should just be a normal procedure.
<didi>mark_weaver: Roger.
<mark_weaver>(define (my-slot id) (with-syntax ...))
<didi>We can use `with-syntax' out of `syntax-case'? o.O
<mark_weaver>yes
<mark_weaver>where, there won't be a syntax case here at all.
<didi>Magical stuff.
<mark_weaver>(define (my-slot id) (with-syntax ((kw (datum->syntax id (symbol->keyword (syntax->datum id)))) (id id)) #'(list id #:init-value 42 #:init-keyword kw)))
<mark_weaver>you just haven't taken the time to study syntax-case macros. you're operating in trial-by-error mode.
<didi>mark_weaver: Nice. Thank you.
<mark_weaver>np!