Arc Forumnew | comments | leaders | submitlogin
2 points by evanrmurphy 5567 days ago | link | parent

I found this paragraph in the tutorial that I thought could be related:

  There's one thing you can't do with functions that you can do with
  data types like symbols and strings: you can't print them out in a
  way that could be read back in.  The reason is that the function
  could be a closure; displaying closures is a tricky problem.
Does this mean what I'm requesting isn't possible at the moment, or is it a different idea?


2 points by shader 5565 days ago | link

This is a different idea. He's pointing out that in general functions can't be printed out, because the function could be represented by something very complicated and hard to print. His example, closures, are function objects that were defined in a lexical context that is relevant to their function. Merely knowing their source code won't be helpful, since two identical looking functions can behave very differently.

If you knew it was a closure, you could probably substitute the variables values for their names, and then print the resulting code, but that requires that you know both what the values are, and the fact that the function is a closure.

Also, I think he's describing the more complicated concept of reverse engineering the actual data type of a function, and printing a representation of it. Taking code that runs, and turning it into code you can read is not an easy challenge. I dare you to macex even a simple function. Taking that and turning it back into something you can read, with meaningful names, is impossible (I think).

At any rate, with 'src I took the shortcut of storing the source code in a table every time a function is defined. This has the disadvantage of only working for global, named functions defined with a small set of function creators (def and mac, mainly) since it uses a global name table. If it stored the string representing the code with the function object itself, it would probably be able to handle local, un-named functions as well, but would still only work with select function creators. This is mainly because you wouldn't want to see the crud added by defop over defop-raw, etc.

So, in general, displaying executable code in a human-readable format is an immense challenge. The more about the original function definition you keep around at run-time, the more easily you can represent it in a human readable form. The hack that is 'src achieves pretty function printing at the cost of storing the whole source code of global functions in a table at run-time. It still lacks a lot of information, and doesn't cover functions defined in local contexts, but it achieves at least a portion of the goal of exploratory, interactive programming.

-----

1 point by evanrmurphy 5561 days ago | link

Thanks for such a thorough explanation, shader. Gives me more to grok. :)

-----

1 point by shader 5560 days ago | link

Supposing you knew that a function was a closure, couldn't you print it out as

  (= fname
    (with (var1 val1 var2 val2 ...)
      (fn (arg1 arg2)
         ...)))
When read in, it should produce an identical closure. The problem is knowing under what variables the function is closed in the first place.

It would be nice if there was more information about objects and source code in arc. I.e. the source codes of functions, the current namespace, the variables captured in a closure, the stack trace, etc.

-----