There is Massimiliano Ghilardi’s gomacro.... Github.com/cosmos72/gomacro Note that in case of untyped constants, there is no need to use temps so your idea can still work.
>> On Nov 8, 2019, at 9:30 AM, Michael Jones <michael.jo...@gmail.com> wrote: > > Alas. Thus the need for and glory of macros, hold/uneval, and backtick in > LISP. (Problems solved in the 1970s) > >> On Fri, Nov 8, 2019 at 9:08 AM André Eriksson <ean...@gmail.com> wrote: >> That works in simple cases, but does not work when the expression is an >> untyped constant, like 1 or nil. In the case of 1 the variable will get a >> concrete type of int, while fn may accept a float32, or even a private type >> that cannot be named in the current package. >> >>> On Friday, November 8, 2019 at 5:51:10 PM UTC+1, Michael Jones wrote: >>> If expr was evaluable in the original code then why not rewrite in place >>> after assigning temporaries? >>> >>> go fn(e1,e2) >>> >>> { >>> t1,t2 := e1,e2 >>> go func() { >>> defer instrument() >>> fn(t1,t2) >>> } >>> >>> >>>> On Fri, Nov 8, 2019 at 8:38 AM André Eriksson <ean...@gmail.com> wrote: >>>> I am working on a type of Go preprocessor that rewrites source code to add >>>> additional instrumentation to certain types of statements. >>>> >>>> One such statement is the go statement. I would like to instrument the >>>> newly created goroutine, injecting some instrumentation code at the start >>>> and finish of the goroutine. >>>> >>>> In the simple case, the rewrite is straightforward: >>>> >>>> go fn() >>>> >>>> becomes >>>> >>>> go func() { >>>> defer instrument()() >>>> fn() >>>> }() >>>> >>>> However this approach does not work when fn takes parameters. >>>> If we were to rewrite go fn(expr) into the equivalent form above: >>>> >>>> go func() { >>>> defer instrument()() >>>> fn(expr) >>>> }() >>>> >>>> >>>> the semantics change, since in the rewrite expr gets evaluated inside the >>>> newly created goroutine, which can change the behavior and introduce data >>>> races. >>>> >>>> My attempts to address this have not been particularly fruitful. >>>> >>>> One cannot pass in expr as an argument to the closure, because the type of >>>> the expression may not have a valid name in the current package (for >>>> example if expr evaluates to a private type in some other package). >>>> >>>> Similarly, if expr is a constant expression (like 1 or nil) the type may >>>> depend on the corresponding parameter in fn’s signature. >>>> >>>> The only semantics-preserving rewrite I can think of revolves around using >>>> package reflect, and rewriting like so: >>>> >>>> go func(fn reflect.Value, vals …reflect.Value) { >>>> defer instrument() >>>> fn.Call(vals) >>>> }(reflect.ValueOf(fn), reflect.ValueOf(expr)) >>>> >>>> As far as I understand, this should be semantics-preserving, although with >>>> a slight performance cost. (Though I imagine the cost of a >>>> reflection-based call is dwarfed by the cost of spawning a goroutine.) >>>> >>>> Unfortunately this also comes with a major downside: the rewritten code >>>> does not typecheck identically to the original code. Ideally I would like >>>> the rewritten form to cause identical typechecking failures to the old >>>> code, so that these errors are caught at compile time without requiring a >>>> separate typechecking pass for the original code. >>>> >>>> Am I correct in the above reasoning? Can anyone think of a way to do this >>>> sort of rewrite in a semantics-preserving and typechecking-preserving way? >>>> >>>> -- >>>> You received this message because you are subscribed to the Google Groups >>>> "golang-nuts" group. >>>> To unsubscribe from this group and stop receiving emails from it, send an >>>> email to golan...@googlegroups.com. >>>> To view this discussion on the web visit >>>> https://groups.google.com/d/msgid/golang-nuts/a92641f3-2eda-4d4a-ab02-d2b40e3bde75%40googlegroups.com. >>> >>> >>> -- >>> Michael T. Jones >>> michae...@gmail.com >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/ec41a345-163f-4a8a-a24f-b868def081a0%40googlegroups.com. > > > -- > Michael T. Jones > michael.jo...@gmail.com > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/CALoEmQxe--frSeHfKo822bKhWStJoQdJpkNdAYM6zTPLUuZ%2BAg%40mail.gmail.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/3FD4DE2A-6466-49F8-AB1D-A0328841A2FC%40bitblocks.com.