Arc Forumnew | comments | leaders | submitlogin
Apropos
7 points by waterhouse 5391 days ago | 2 comments
I learned somewhat recently that Scheme has this 'namespace-mapped-symbols procedure that returns a list of all symbols bound in the given namespace (defaulting to the current namespace). Now, all Arc symbols show up in the Scheme namespace with an underscore in front of them (e.g. as _def). Given a way to execute Scheme expressions (with my version of ac.scm, this is done by wrapping the expression in 'mz; Anarki does something similar with '$), we can get all Arc symbols like this:

  arc> (map [sym:cut _ 1] (keep [is _.0 #\_] (map string (mz
  (namespace-mapped-symbols)))))
  (username-taken goodname vals thatexpr equal ... [and 900 more symbols])
We can use this to construct a nice "apropos" function, sort of like what Common Lisp provides. The following code works in Anarki (the only thing not in vanilla Arc is the $ thing for raw Scheme code):

  (def arc-environment ()
    (map [sym:cut _ 1] (keep [is _.0 #\_]
                             (map string ($.namespace-mapped-symbols)))))
  
  (def apropos-fn (x)
    (map sym (keep [findsubseq x _]
                   (map string (arc-environment)))))
  
  (mac aps (x) `(apropos-fn (string ',x)))
Here it is in action (most of these functions are mine):

  arc> (aps cli)
  (clipboard click tclick reclist click-sleeps click-secs click-drag
  unclick client-ip)
We can even use the dot notation! I find it very pleasant to type a dot instead of two parentheses into the REPL.

  arc> aps.cli
  (clipboard click tclick reclist click-sleeps click-secs click-drag
  unclick client-ip)
For how to make raw Scheme expressions work without the whole Anarki package, consult either http://arclanguage.org/item?id=8719 or http://awwx.ws/scheme0. Then replace the $ in my code with mz or scheme.


1 point by shader 5390 days ago | link

Neat!

This seems to complement 'help, 'sig, and 'src fairly well.

If I remember correctly though, this will only work for global variables (such as globally defined functions and macros, and variables used on the repl). Local variables are handled by scheme lsmabdas, and don't actually undergo any symbol transformation.

How hard and useful do you think it would be to try and get it to work for local vars as well?

-----

2 points by waterhouse 5390 days ago | link

I would normally use 'apropos when I'm sitting at the REPL trying to remember the name of a function (or, more rarely, a global variable bound to a hash-table or something). For 'apropos to work on local variables, I assume you would have to use 'apropos within the lexical environment in which the variable exists. I.e. you would go

  (let thingamajig 2
    (do-stuff)
    ;hmm, what was that variable again? thing-something.
    (aps thing))
Which seems a bit useless to me, as the local variables are printed right there within the block of code you're currently writing. I suppose one could have some macro that creates a huge lexical environment, or something... am I missing your meaning? At any rate, 'namespace-mapped-symbols appears to be blind to local variables:

  > (let ((ach 2))
      (member 'ach (namespace-mapped-symbols)))
  #f
To obtain a list of local variables, I think you would have to hack with ac.scm. Or write a macro that searches/walks your code for lexical variables.

-----