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 >>> <https://groups.google.com/d/msgid/golang-nuts/a92641f3-2eda-4d4a-ab02-d2b40e3bde75%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> >> >> -- >> >> *Michael T. jonesmichae...@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 > <https://groups.google.com/d/msgid/golang-nuts/ec41a345-163f-4a8a-a24f-b868def081a0%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- *Michael T. jonesmichael.jo...@gmail.com <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.