santoshrajan / lispyscript

A javascript with Lispy syntax and macros
MIT License
572 stars 57 forks source link

add a lispy option for tracing? #57

Open darrencruse opened 9 years ago

darrencruse commented 9 years ago

Some of the quirks I saw when I tried source maps got me thinking...

What about an option for the lispy command to generate the code in a "trace" mode?

Such that when you run it outputs a trace of the program run?

Where (ideally) this might show the lispy source (and maybe the lispy source line numbers and javascript line numbers? since maybe that's not too hard since the sourcemap support in theory has that available already?)

Not that I've given it much thought - maybe less ambitious but still helpful is just a little api for log statements that are only included in the generated code if you've compiled with this special "debug"/"trace" option enabled?

To be a more concrete - I was thinking about this in the context of the "await" macro I just posted about in issue #56.

What if the macros had some optional trace statements that normally expand to nothing/no-ops but expand to console.log statements - output in the generated code - when the lispy compiler got this "trace" mode option:

So e.g.:

(macro await (result asynccall rest...)
  (trace "await for" ^result "from" ^asynccall)
    (~@asynccall (function (err ~result)
       (trace "got" ^result "from" ^asynccall ":" ~result)
       ~rest...)))

The above is just to illustrate the idea it doesn't actually work of course.

In particular in the above I've used a hypothetical e.g. "^result" to indicate "I want the macro argument as a quoted string" (which is what is needed for a console.log statement).

As opposed to the normal "~result" to get the macro argument unquoted as needed for actual generated code.

is there already a way to do domething similar I wonder?

I can see where the above might be questioned as too simple, but if it were also supported through the "keyword" handling in the "lib/ls.js" file...

And maybe even allowed for a few different tracing "levels".

I could see this being very helpful when developing real programs, esp. where complex control flow and asyncrony is involved.

darrencruse commented 9 years ago

The other thing I forgot to say is I know there's subtleties involved when e.g. you try and just plop a console.log expression in something like e.g. "if" which expects exactly two expressions (the if-expression and the else-expression).

So in these cases I notice myself adding a "do" around things to wrap my console.log expression in with the original expression so I don't break anything.

So to avoid such problems would it be best to change my "trace" suggestion above to actually wrap the expression it's meant to trace so it would take two arguments a message and an expression:

(macro await (result asynccall rest...)
  (trace ("await for" ^result "from" ^asynccall)
    (~@asynccall (function (err ~result)
       (trace ("got" ^result "from" ^asynccall ":" ~result)
       ~rest...)))))

If I'm thinking right this would avoid any/all chance that "trace" could affect the program either when enabled or when turned off where it's "expanded away".

(feel free to give feedback if I'm wrong - I might be I'm definitely still learning! :)