IRC channel logs

2015-04-24.log

back to list of logs

<please_help>syntax-case is like a hygienic version of C++ template metaprogramming while syntax-rule is like a hygienic version of C macros?
<ijp>not really, C macros just do text substitution
<ijp>which means you can end up with things that are not even well formed C expressions
<please_help>ijp: is that not the same thing for syntax-rule?
<ijp>no, the arguments to a syntax rule are sexps
<ijp>the output is sexps
<ijp>there is no way to make something that isn't a sexp
<please_help>ijp: a string :^)
<please_help>are macros with "macro-recursion" kosher?
<mark_weaver>I'm not exactly sure what that means, but if it's what I think it means, the answer is yes.
<mark_weaver>macros can expand into uses of the same macro
<mark_weaver>or can contain uses of the same macro within the expansion.
<mark_weaver>but it's actually done iteratively, not recursively
<mark_weaver>it's all a bit tricky, but in broad terms, the outermost macro is expanded, and then the result of expansion is expanded again until there's nothing left to expand.
<mark_weaver>but the macro expander also need to be aware of the primitive language constructs, notably forms that introduce lexically-scoped variables such as 'let' and 'lambda'.
*mark_weaver goes afk
<please_help>I see, thanks
<please_help>Is there a way to perform 1-step macro expansion and displaying the resulting code?
<please_help>I have the following definitions: (define-macro (test-first-term pred expr)
<please_help> `(,pred ,(car expr)))
<please_help>(define-macro (extract-rest expr)
<please_help> (cdr expr))
<please_help>(define-syntax-rule (test-macro expr)
<please_help>(unless (test-first-term null? expr)
<please_help>(test-macro (extract-rest expr))))
<please_help>I want it to go through the expressions until the end and successfully expand to nothing, but that doesn't work
<please_help>(test-macro (+ 1 2)) -|unknown location: source expression failed to match any pattern in form extract-rest
<please_help>I think the problem is that at some point we're left with nothing of the expression, but I'm not sure, since (extract-rest ()), (extract-rest (())), (extract-rest) don't have the same error.
<nalaginrut>morning guilers~
<please_help>So anyway, the problem is basically: how do I walk a sexp without losing the ability to check the type of the elements I deal with? Macros don't seem to be the right way.
<mark_weaver>please_help: there's no way to do it
<mark_weaver>because the subexpressions could use arbitrary macros, and you have no way to understand them.
<mark_weaver>btw, 'define-macro' is unhygienic and deprecated. it should not be used in new code.
<mark_weaver>at a higher level, what are you trying to do?
<mark_weaver>you can walk s-expressions using syntax-case macros, but you can't understand what they mean in general.
<mark_weaver>syntax-case is a general pattern matcher and destructuring operator.
<mark_weaver>it is the way to take about s-expressions within a macro. it needn't only be used at the top-level of a macro definition.
<mark_weaver>s/take about/take apart/
<nalaginrut>ArneBab_: seems emscripten use LLVM to generate asm.js as its own core compiler, so maybe asm.js of GCC is still worth to go
<nalaginrut>it's named 'fastcomp'
***michel_mno_afk is now known as michel_mno
***koz__ is now known as koz_
<dummiii>Hi all!
<dummiii>When I try to compile this program: http://www.gnu.org/software/guile/manual/html_node/Linking-Guile-into-Programs.html#Linking-Guile-into-Programs
<dummiii>I get an error about invalid conversion from ‘scm_unused_struct* (*)()’ to ‘scm_t_subr {aka void*}’ [-fpermissive]
<dummiii>I tried to compile it with g++
<dummiii>Is it possible to use Guile in C++ programs?
<muep_>c++ is more strict than c about conversions between void* and other pointers
<dummiii>muep_, Thank you for your answer! So what do I have to change and think about when using Guile in C++?
<muep_>so you should add something like void * thing = static_cast<void*>(some_nonvoid_pointer);
<muep_>instead of just void * thing = some_nonvoid_pointer;
<dummiii>Thank you! I'll try that. Is there any manual or tutorial or howto or whatever about using Guile in C++?
<dummiii>Or is it not recommended to use Guile in C++?
<davexunit>a bunch of people use guile in C++ programs
<davexunit>I write pure guile these days so I can't be of much help here
<dummiii>Is there a wrapper library for "Guile + C++"?
<davexunit>no, just libguile
<dummiii>muep_, I'm sorry! I didn't get that. In the given example: What should I change?
<bipt>dummiii, i changed my_hostname in the scm_c_define_gsubr call to 'reinterpret_cast<scm_t_subr> (my_hostname)' and it worked
<bipt>(it might not be the best solution though; i don't really know anything about c++)
<dummiii>bipt, Thank you very much!!
<muep_>bipt: my impression is that static_cast should suffice when one of the pointers is a pointer-to-void
<bipt>i tried static_cast but got this error: invalid static_cast from type ‘scm_unused_struct*()’ to type ‘void*’
<bipt>maybe it has something to do with one of the types being a function pointer?
<bipt>i don't think it's technically allowed to convert between void and function pointers in C either
<bipt>or rather, it's undefined behavior in C and POSIX, IIRC, but it works on the compilers and platforms guile supports
<bipt> http://c-faq.com/ptrs/generic.html
<please_help>mark_weaver: I need to walk a sexp and transform it based on the type of elements I'm dealing with in order to generate a compute graph for symbolic processing. The define-macro are needed because the alternative is to emulate define-macros with syntax-case to do the same thing. No other construct can generate operations on the raw sexp elements such as detecting the type of element being dealt with apparently. Since the
<please_help>class of elements being dealt with is limited (symbols, variables, procedures), it should be doable.
<davexunit>I question whether a macro is needed for this
<taylanub>davexunit: an example mentioned yesterday was (make-graph (sigm (mat+ (mat* W x) b))) where W and b are lexically bound but not x, and this should return an object where values for x can then be inserted. if I understood correctly, this should work generically for all unbound identifiers, hence using (procedural) macros.
<davexunit>taylanub: okay, that's too much for me to think through right now :)
<taylanub>please_help: I'm not sure if a defmacro style macro can even tell apart bound and unbound identifiers?
<please_help>taylanub, the macros I posted correctly apply the predicate pred on the first term of a sexp. I could verify if items were bound by extracting them and local-eval'ing them if they're not a sexp and catching the error, but for now I assume every symbol is actually a variable to be bound later.
<please_help>but for now, I am making the simplification to get something that resembles the goal working :)
<please_help>using the defmacro-style macro seems to be required (of course, syntax-case can do the same but why bother reinventing defmacro?) to extract the terms, though.
<taylanub>please_help: was there a link to your macro? I seem to have missed it.
<please_help>No, I just posted it straight: (define-macro (test-first-term pred expr) `(,pred ,(car expr)))
<mark_weaver>please_help: with 'define-macro', you get no hygiene at all. with syntax-case you can selectively avoid hygiene but get it by default.
<mark_weaver>can you explain at a higher level what you are trying to accomplish?
<mark_weaver>I really think that what you're doing is extremely gross and likely to cause problems later
<please_help>mark_weaver, as taylanub posted, (make-graph (sigm (mat+ (mat* W x) b))) where x isn't bound at this point -> $1 -> (exec-graph $1 value-for-x) -> the actual output of the graph; (derive $1 #:wrt x) -> graph that represents the diff of $1 wrt x; likewise with integrate; (optimize $1) -> transform graph to remove duplicate ops, change the op order to be faster, etc.
<mark_weaver>please_help: the other thing is that 'define-macro' will interfere with the hygiene of other macros in the same expression.
<mark_weaver>it will fail to preserve the extra information of the syntax objects its working on.
<dsmith-work>Happy Friday, Guilers!!
<mark_weaver>please_help: you might want to look at scmutils
<mark_weaver>which is used in the book Structure and Interpretation of Classical Mechanics by Sussman, who was one of the original inventors of Scheme.
<mark_weaver>see http://groups.csail.mit.edu/mac/users/gjs/6946/refman.txt and http://www.cs.rochester.edu/~gildea/guile-scmutils/
<mark_weaver>even if you can't use the code, you might consider something closer to that approach for working with symbolic expressions.
<please_help>It seems they only care about derivatives (not differentiation) and strip information about which variable is named what, both properties are unsuitable for my use-case. I guess I could use the same kind of approach and explicitly define matching ops for those that I handle instead of automatic resolution at least for now though.
<please_help>is there a way to specify a meta-macro that generates a syntax-rule macro that may or may not contain "real ellipses"? (meta-macro (name args ...)) for instance, without conflict from the meta-macro's use of ... as it does not know itself how many terms it might encounter.
<mark_weaver>please_help: see the following sections of the manual: 6.10.2.5 (Specifying a Custom Ellipsis Identifier
<mark_weaver>) and 6.10.3.2 (Custom Ellipsis Identifiers for syntax-case Macros)
<mark_weaver>these features were added in Guile 2.0.10, but there were less pleasant ways to do it before
<please_help>This seems to imply that I know I'm dealing with a form that includes ellipses, so there's no alternative to case-based analysis of the form with regard to argument arity?
<mark_weaver>no
<mark_weaver>because of hygiene (assuming that you don't undermine it by using 'define-macro'), if you set a custom ellipsis identifier, it is guaranteed that it won't conflict with another ellipsis from another lexical environment.
<mark_weaver>in the same way that a macro can generate code that introduces a binding, and needn't worry about its name conflicting with another variable of the same name in the environment of the macro use.
<mark_weaver>but the distinctions between bindings of the same name introduced in different environments is completely flattened by the use of 'define-macro', so if you use that, all bets are off.
<mark_weaver>anyway, I have to go afk for a long while... good luck!
***michel_mno is now known as michel_mno_afk
<please_help>so I have a macro defined like so: http://paste.lisp.org/+35RJ where the second form is to be used first to create an initial binding, and the first form is to be used second, to complete the binding while taking into account self-reference. The problem is that if the first form is used thus, as one would expect, the function gets into an infinite loop. Any clean way to fix it? I actually want the inner references to use
<please_help>the previous binding, not the new binding. I tried with syntax-case and #'(define-syntax-rule... instead of define, but the same problem happens, to my surprise.
<mark_weaver>please_help: I'm sorry, but you are not communicating clearly enough for me to understand
<mark_weaver>it might help if you gave a concrete example of usage of this macro, and what you want to happen.
<mark_weaver>which bindings are colliding?
<mark_weaver>since 'args' is "introduced" by the macro, it effectively gets a fresh name every time the macro is invoked.
<mark_weaver>however, 'a' and 'as' are copied from operands in the macro use, so those can collide if the have the same names.
<mark_weaver>s/if the/if they/
<mark_weaver>if you need to generate fresh identifiers for all of those, then 'generate-temporaries' is the tool for that
<mark_weaver>and to use that you'd switch to using 'syntax-case' and use ellipses instead of ". as"
*mark_weaver goes afk
<please_help>mark_weaver, (register-op (s:+ x . xs) '+) (register-op (s:+ (s:+ derive 'params) (s:+ integrate 'params) x . xs) '+)
<mark_weaver>please_help: so, both of those 'register-op' forms expand into top-level definitions of 's:+', but you want them to become two distinct bindings, and you want the uses of 's:+' in the second definition to refer to the first binding of 's:+', not the second one?
<mark_weaver>if the right-hand-sides of definitions didn't refer to the same thing being bound, then it would be rather inconvenient to write recursive definitions.
<mark_weaver>e.g. if I write (define (factorial n) (if (zero? n) 1 (* n (factorial (- n 1)))))
<mark_weaver>you want the use of 'factorial' on the right-hand-side to refer to some earlier definition of 'factorial' instead of the one I just made?
<please_help>mark_weaver: that is correct. Of course, it probably shouldn't work with functions, but why doesn't it work with macros either?
<please_help>Alternatively, is there a way to rename every reference to some gensym, and then swap out the names of the actual function and the gensym, say?
<mark_weaver>we often write macros that expand recursively as well
<mark_weaver>well, it happens iteratively, but it feels recursive anyway.
<mark_weaver>e.g. (define-syntax register-op
<mark_weaver> (syntax-rules ()
<mark_weaver> ((_ (op-name d i a . as) proc)
<mark_weaver> (define (op-name a . as)
<mark_weaver> (let ((args (cons a as)))
<mark_weaver> (make-proc proc
<mark_weaver> args
<mark_weaver> (apply append
<mark_weaver> (map parse-arg args))
<mark_weaver> d
<mark_weaver> i))))
<mark_weaver> ((_ (op-name a . as) proc)
<mark_weaver> (define (op-name a . as)
<mark_weaver> (let ((args (cons a as)))
<mark_weaver> (make-proc proc
<mark_weaver> args
<mark_weaver> (apply append
<mark_weaver> (map parse-arg args))
<mark_weaver> '()
<mark_weaver>bah, sorry about that.
<mark_weaver>here's an example of a macro that feels recursive:
<mark_weaver>(define-syntax and
<mark_weaver> (syntax-rules ()
<mark_weaver> ((_) #t)
<mark_weaver> ((_ x) x)
<mark_weaver> ((_ x y ...) (if x (and y ...) #f))))
<mark_weaver>it's important that the 'and' in the expansion of that macro to refer to the same macro.
<mark_weaver>s/to refer/refers/