#+TITLE:nsymbols

*Nsymbols is a set of functions to search, filter, and group symbols in a chosen set of packages based on arbitrary conditions.*

Nsymbols extends the regular package API of ANSI CL with more operations, allowing one to list:
- ~package-symbols~.
- ~package-variables~.
- ~package-functions~ (and ~package-functions*~ in ~nsymbols/star~).
  - ~package-generic-functions~ (and ~package-generic-functions*~ in ~nsymbols/star~).
  - ~package-macros~.
  - ~package-methods*~ in ~nsymbols/star~.
- ~package-classes~ (and ~package-classes*~ in ~nsymbols/star~)
- ~package-structures~ (and ~package-structures*~ in ~nsymbols/star~).
- And other symbol types, given ~define-symbol-type~ for those.
Nsymbols can also find symbols by their name/matching symbol with ~resolve-symbol~. All these operations are aware of symbol visibility in the given packages, due to a new ~symbol-visibility~ function.

* Getting started
Clone the Git repository:
#+begin_src sh
  git clone --recursive https://github.com/atlas-engineer/nsymbols ~/common-lisp/
#+end_src

And then load Nsymbols in the REPL:
#+begin_src lisp
  (asdf:load-system :nsymbols)
  ;; or, if you use Quicklisp
  (ql:quickload :nsymbols)
#+end_src
And you can list your package symbols and resolve them right away:
#+begin_src lisp
  (nsymbols:macro-symbol-p 'defclass)
  ;; => true
  (nsymbols:package-classes :cl)
  ;; => (METHOD-COMBINATION CLASS BUILT-IN-CLASS STRUCTURE-CLASS
  ;; STANDARD-METHOD STANDARD-CLASS STANDARD-OBJECT METHOD)
  (nsymbols:package-functions :nsymbols :internal)
  ;; => (NSYMBOLS::LIST-ALL-MAYBE-SUBPACKAGES)
  (nsymbols:resolve-symbol "SUBPACKAGES" 'function :nsymbols)
  ;; => NSYMBOLS:SUBPACKAGES
  ;; => (NSYMBOLS:SUBPACKAGES)
#+end_src

* How it works

Nsymbols uses the auto-generated predicates to check whether the given symbol belongs to a certain group of symbols. For example:
#+begin_src lisp
  (define-symbol-type function ()
    (fboundp %symbol%))
#+end_src
creates a symbol type ~:FUNCTION~ that will only list ~fboundp~ symbols. Underneath this short definition, a set of helpers is generated:
- ~function-symbol-p~ predicate to check whether a symbol belongs to this group. That's where the body of ~define-symbol-type~ goes.
- ~function-symbol~ type to type-check the symbol you use.
- ~package-functions~ function to list function symbols in the package based on their visibility.

* Roadmap
- [X] Maybe use Closer MOP to get (more reliable?) list of classes, structures, and slots (current implementation makes slot listing impossible).
- [X] Introduce ~package-functions*~-like starred helpers returning function/class/method/slot objects instead of symbols designating them?
- [X] ~package-slots*~.
