Giter VIP home page Giter VIP logo

cl-annot's Introduction

cl-annot

cl-annot is an general annotation library for Common Lisp.

cl-annot is tested under the following implementations:

  • Allegro CL v8.2
  • SBCL v1.0.45
  • CMU CL v20b
  • Clozure CL v1.6
  • ECL v11.1.1
  • GNU CLISP v2.48

Overview

Annotations is a special syntax for annotating and transforming forms. Annotations look like Python's decorator:

@annot
(defun foobar ()
  ...)

Any functions and macros can be annotations which takes one argument by default. For example, if you define the following function,

(defun trace (object)
  (print object)
  object)

you can use the function as an annotation like:

@trace (+ 1 2)

This expression prints 3 and returns 3. Internally, this expression will be regarded as (trace (+ 1 2)).

Standard annotation export exports the symbol of the given definition. For example,

@export
(defun foobar ()
  ...)

defines a function foobar and exports the symbol foobar. This equivalents to:

(progn
  (export 'foobar)
  (defun foobar ()
    ...))

Annotations help you to write the simple and declarative codes.

Usage

Just write the following code at the header of each files:

(annot:enable-annot-syntax)

After this code, @... syntax can be used.

Emacs Configuration

If you use Emacs, it is recommended to install misc/slime-annot.el which contains some features of annotations. After locating misc/slime-annot.el into your loadpath, write the following code into your .emacs.

(require 'slime-annot)

Standard Annotations

Package: annot.std

This package contains very basic and useful annotations. You don't need to use-package this package.

Annotation: export

@export DEFINITION-FORM

export is a macro which adds an export form of the definition form. For example,

@export (defun f () ...)

is equivalent to

(progn
  (export 'f)
  (defun f () ...))

Annotation: ignore

@ignore VARIABLES

ignore is a macro which is equivalent to (declare (ignore ...)) form. For example,

@ignore v

is equivalent to

(declare (ignore v))

ignore can take a list of variables like:

@ignore (a b c)

Annotation: ignorable

@ignorable VARIABLES

Same as ignore annotation except that this is equivalent to

(declare (ignorable v))

Annotation: type

@type TYPESPEC NAME

type is a macro which is equivalent to (declare (type ...)) form. For example,

@type integer v

is equivalent to

(declare (type integer v))

Annotation: optimize

@optimize QUALITY

optimize is a macro which is equivalent to (declare (optimize ...)) form. For example,

@optimize (speed 3)

is equivalent to

(declare (optimize (speed 3)))

Annotation: inline

@inline NAME

inline is a macro which is equivalent to (proclaim (inline ...)) or (declare (inline ...)) form. If NAME is just a symbol, declaration will be used. If NAME is a definition form, proclamation will be used. For example,

@inline f

is equivalent to

(declare (inline f))

And

@inline
(defun f () ...)

is equivalent to

(proclam (inline f))
(defun f () ...)

Package: annot.eval-when

This package contains annotations eval-when special form.

Annotation: eval-when-compile

@eval-when-compile FORM

eval-when-compile is a macro which is equivalent to (eval-when (:compile-toplevel) ...). For example,

@eval-when-compile
(defun macro-util () ...)

is equivalent to

(eval-when-compile (:compile-toplevel)
  (defun macro-util () ...))

Annotation: eval-when-load

@eval-when-load FORM

Same as eval-when-compile except that this is equivalent to (eval-when (:load-toplevel) ...).

Annotation: eval-when-execute

@eval-when-execute FORM

Same as eval-when-compile except that this is equivalent to (eval-when (:execute) ...).

Annotation: eval-always

@eval-always FORM

eval-always is a macro which is equivalent to (eval-when (:compile-toplevel :load-toplevel :execute) ...).

Package: annot.doc

This package contains documentation annotations.

Annotation: doc

@doc DOCSTRING DEFINITION-FORM

doc is a macro which inserts documentation string into the definition form. For example,

@doc "docstring"
(defun f () ...)

is equivalent to

(defun f ()
  "docstring"
  ...)

Mixture of export annotation and doc annotation is allowed, means

@export
@doc "docstring"
(defun f () ...)

works as you expected.

Package: annot.class

This package contains annotations about classes.

Annotation: metaclass

@metaclass METACLASS CLASS-DEFINITION-FORM

metaclass embeds (:metaclsas METACLASS) into class-options of CLASS-DEFINITION-FORM. For example,

@metaclass persistent-class
(defclass foo ()
     ())

is equivalent to

(defclass foo ()
     ()
  (:metaclass persistent-class))

Annotation: export-slots

@export-slots CLASS-DEFINITION-FORM

export-slots adds (export ...) form for slots of CLASS-DEFINITION-FORM. For example,

@export-slots
(defclass foo ()
     (bar baz))

is equivalent to

(progn
  (export '(bar baz))
  (defclass foo ()
     (bar baz)))

It can also be used with defstruct as of the commit 9043a74815a028a7db664f2fd77a8b009c736df9 (8/31,2013).

Annotation: export-accessors

@export-accessors CLASS-DEFINITION-FORM

export-accessors adds (export ...) form for accessors (i.e. readers, writers and accessors) of CLASS-DEFINITION-FORM. For example,

@export-accessors
(defclass foo ()
     ((bar :reader bar-of)
      (bax :writer bax-of)
      (baz :accessor baz-of)))

is equivalent to

(progn
  (export '(bar-of bax-of baz-of))
  (defclass foo ()
     ((bar :reader bar-of)
      (bax :writer bax-of)
      (baz :accessor baz-of))))

It can also be used with defstruct as of the commit 9043a74815a028a7db664f2fd77a8b009c736df9 (8/31,2013).

Annotation: export-constructors

It can be used as of the commit 9043a74815a028a7db664f2fd77a8b009c736df9 (8/31,2013).

According to the {CLHS: Macro DEFSTRUCT}[http://www.lispworks.com/documentation/HyperSpec/Body/m_defstr.htm], defstruct can define more than one constructor, for example:

@export-constructors
(defstruct (s (:constructor abya a c)
              (:constructor abya2 a b c))
  a b c)

is equivalent to

(progn
  (export '(abya abya2))
  (defstruct (s (:constructor abya a c)
                (:constructor abya2 a b c)) a b c))

and it might have no constructor like this.

(defstruct (s (:constructor nil)) a b c)

Annotation: export-class and export-structure

export-class combines export, export-slots and export-accessors. export-structure also combines export-constructors in addition.

Package: annot.slot

This package contains annotations about slots.

Annotation: optional

@optional INITFORM SLOT-SPECIFIER

optional embeds :initarg SLOT-NAME and :initform INITFORM into SLOT-SPECIFIER. For example,

(defclass c ()
     (@optional nil
      foo))

is equivalent to

(defclass c ()
     ((foo :initarg :foo
           :initform nil)))

Annotation: required

@required SLOT-SPECIFIER

required embeds :initarg SLOT-NAME and :initform (annot.slot:required-argument SLOT-NAME) into SLOT-SPECIFIER so that MAKE-INSTANCE will raise errors when no argument for the slot given. For example,

(defclass c ()
     (@required
      foo))

is equivalent to

(defclass c ()
     ((foo :initarg :foo
           :initform (annot.slot:required-argument :foo))))

Writing Annotations

As I mentioned, any functions and macros can be annotations. Basically, if you have a function or a macro named annot, the following code

@annot (+ 1 2)

will be expanded like

(annot (+ 1 2))

Aliasing

You may use an alias for specifying annotations. This is useful when you want to use more general names as annotation names. Actually, annot.std uses this technique to overriding the meanings of symbols in common-lisp package. Here is how to alias:

(setf (annotation-real 'do) 'long-long-name)

Now you can use do as meaning long-long-name at annotations like:

@do ...

Multiple Arguments

By default, annotations can take only one argument. If you want to write an annotation taking two or more arguments, you need to specify a number of arguments into the annotation symbol like:

(use-package :annot.core)

(defun my-annot (x y) (+ x y))
(setf (annotation-arity 'my-annot) 2)

Now you can use this annotation like:

@my-annot 2 3
;; => 5

Inlining

In some cases, you want annotations to be expanded at read-time. You can do it by:

(setf (annotation-inline-p 'annot) t)

Be caseful to use feature.

Macro: defannotation

defannotation NAME LAMBDA-LIST (:alias ALIAS :arity ARITY :inline INLINE) &body BODY

defannotation is an utility macro for creating annotations. Here is an example:

(defannotation my-annot (x y)
    (:arity 2 :inline t)
  `(+ ,x ,y))

Annotation: annotation

annotation (:alias ALIAS :arity ARITY :inline INLINE) FUNCTION-DEFINITION-FORM

annotation is an annotation for creating annotations in a way of defannotation. Here is an example:

@annotation (:arity 2 :inline t)
(defmacro my-annot (x y)
  `(+ ,x ,y))

Copyright (C) 2011 Tomohiro Matsuyama <[email protected]>

cl-annot's People

Contributors

fukamachi avatar guicho271828 avatar m2ym avatar mmontone avatar yasuyk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cl-annot's Issues

cl-annot should leave :@ alone.

cl-annot comes in the way of using :@ keyword. So it would be good if cl-annot could leave @ in the keyword package alone.

Reader macro conflict on Allegro CL

On a Travis CI worker running Allegro CL 9.0 [Linux (x86)], (use-syntax :annot) triggers Reader macro conflict while trying to merge the dispatch macro characters #\# #\U from #<readtable named CL-ANNOT.SYNTAX> into #<readtable>.

Reproduced in Scalpl's Job #7.2, which seems to occur when CL-DBI compilation reaches this call to use-syntax.

Please specify the license for this package

Could you please specify the license used for this package?

Assuming that you want to release under "the GPL v3 or any later version", the best way to do that would be to add this permission statement to the library header:

;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also consider adding a LICENSE file containing the text of the GPL-3. You could add just that file without also adding the above persmission statement, but if you do that, then the "or (at your option) any later version" bit won't be known. So I recommend that you add both the actual license and the permission statement.

If you find the permission statement to be too noisy, then you could instead add one of these following lines to the header. If you do that, then it becomes more important to also add the LICENSE file - a judge might decide that such a line by itself is not sufficient. Still, adding just such a line is better than not specifing the license at all.

;; License: GNU General Public License version 3, or (at your option) any later version
;; License: GNU General Public License version 3, or any later version
;; License: GNU GPL version 3, or (at your option) any later version
;; License: GPL version 3, or (at your option) any later version
;; License: GPL version 3, or any later version
;; License: GPL v3, or (at your option) any later version
;; License: GPL v3, or any later version
;; License: GPL-3+

`cl-annot` on SBCL doesn't work

Compilation of cl-project and clack fails. I guess this is due to cl-annot on SBCL and so here's a report.

I use SBCL 1.10, FreeBSD 9.1.

With ABCL, I had no errors.

Code:

(ql:quickload :cl-project)

Backtrace:

The value #<FDEFINITION for SB-IMPL::READ-LIST>
is not of type
  (OR FUNCTION SYMBOL).
   [Condition of type TYPE-ERROR]

Restarts:
 0: [TRY-RECOMPILING] Recompile contrib/annot and try loading it again
 1: [RETRY] Retry loading FASL for #<CL-SOURCE-FILE "cl-syntax-annot" "contrib/annot">.
 2: [ACCEPT] Continue, treating loading FASL for #<CL-SOURCE-FILE "cl-syntax-annot" "contrib/annot"> as having been successful.
 3: [RETRY] Retry ASDF operation.
 4: [CLEAR-CONFIGURATION-AND-RETRY] Retry ASDF operation after resetting the configuration.
 5: [ABORT] Give up on "cl-project"
 --more--

Backtrace:
  0: (SET-MACRO-CHARACTER #\( #<FDEFINITION for SB-IMPL::READ-LIST> NIL #<NAMED-READTABLE CL-ANNOT::SYNTAX {1003BD0AC3}>) [tl,external]
  1: (EDITOR-HINTS.NAMED-READTABLES:MERGE-READTABLES-INTO #<NAMED-READTABLE CL-ANNOT::SYNTAX {1003BD0AC3}> :STANDARD)
  2: ((SB-C::TOP-LEVEL-FORM (LET ((READTABLE (EDITOR-HINTS.NAMED-READTABLES:FIND-READTABLE #1=???))) (COND ((NOT READTABLE) #2=(SETQ READTABLE #1#)) (T #2# (EDITOR-HINTS.NAMED-READTABLES::SIMPLE-STYLE-WARN..
  3: (SB-FASL::LOAD-FASL-GROUP #<SB-SYS:FD-STREAM for "file /usr/home/keno/.cache/common-lisp/sbcl-1.2.8-bsd-x64/usr/home/keno/.quicklisp/dists/quicklisp/software/cl-syntax-20120520-git/contrib/annot.fasl"..
  4: (SB-FASL::LOAD-AS-FASL #<SB-SYS:FD-STREAM for "file /usr/home/keno/.cache/common-lisp/sbcl-1.2.8-bsd-x64/usr/home/keno/.quicklisp/dists/quicklisp/software/cl-syntax-20120520-git/contrib/annot.fasl" {1..
  5: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-SYS:FD-STREAM for "file /usr/home/keno/.cache/common-lisp/sbcl-1.2.8-bsd-x64/usr/home/keno/.quicklisp/dists/quicklisp/software/cl-syntax-20120520-git/contrib..
  6: (LOAD #P"/usr/home/keno/.cache/common-lisp/sbcl-1.2.8-bsd-x64/usr/home/keno/.quicklisp/dists/quicklisp/software/cl-syntax-20120520-git/contrib/annot.fasl" :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T ..
  7: (UIOP/UTILITY:CALL-WITH-MUFFLED-CONDITIONS #<CLOSURE (LAMBDA NIL :IN UIOP/LISP-BUILD:LOAD*) {1004C7700B}> ("Overwriting already existing readtable ~S." #(#:FINALIZERS-OFF-WARNING :ASDF-FINALIZERS)))
  8: ((SB-PCL::EMF ASDF/ACTION:PERFORM) #<unavailable argument> #<unavailable argument> #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-syntax-annot" "contrib/annot">)
  9: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS (ASDF/LISP-ACTION:LOAD-OP ASDF/LISP-ACTION:CL-SOURCE-FILE)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-syntax-annot" "contrib/annot"..
 10: ((:METHOD ASDF/ACTION:PERFORM-WITH-RESTARTS :AROUND (T T)) #<ASDF/LISP-ACTION:LOAD-OP > #<ASDF/LISP-ACTION:CL-SOURCE-FILE "cl-syntax-annot" "contrib/annot">) [fast-method]
 11: ((:METHOD ASDF/PLAN:PERFORM-PLAN (LIST)) ((#1=#<ASDF/LISP-ACTION:COMPILE-OP > . #<ASDF/SYSTEM:SYSTEM "anaphora">) (#1# . #<ASDF/SYSTEM:SYSTEM "cl-ppcre">) (#1# . #<ASDF/SYSTEM:SYSTEM "cl-emb">) (#1# ...
 12: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
 13: ((:METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T)) ((#1=#<ASDF/LISP-ACTION:COMPILE-OP > . #<ASDF/SYSTEM:SYSTEM "anaphora">) (#1# . #<ASDF/SYSTEM:SYSTEM "cl-ppcre">) (#1# . #<ASDF/SYSTEM:SYSTEM "cl-emb">) (..
 14: ((FLET SB-C::WITH-IT :IN SB-C::%WITH-COMPILATION-UNIT))
 15: ((:METHOD ASDF/PLAN:PERFORM-PLAN :AROUND (T)) #<ASDF/PLAN:SEQUENTIAL-PLAN {10045DB0F3}> :VERBOSE NIL) [fast-method]
 16: ((:METHOD ASDF/OPERATE:OPERATE (ASDF/OPERATION:OPERATION ASDF/COMPONENT:COMPONENT)) #<ASDF/LISP-ACTION:LOAD-OP :VERBOSE NIL> #<ASDF/SYSTEM:SYSTEM "cl-project"> :VERBOSE NIL) [fast-method]
 17: ((SB-PCL::EMF ASDF/OPERATE:OPERATE) #<unused argument> #<unused argument> #<ASDF/LISP-ACTION:LOAD-OP :VERBOSE NIL> #<ASDF/SYSTEM:SYSTEM "cl-project"> :VERBOSE NIL)
 18: ((LAMBDA NIL :IN ASDF/OPERATE:OPERATE))
 19: ((:METHOD ASDF/OPERATE:OPERATE :AROUND (T T)) #<ASDF/LISP-ACTION:LOAD-OP :VERBOSE NIL> #<ASDF/SYSTEM:SYSTEM "cl-project"> :VERBOSE NIL) [fast-method]

:description

Would you please consider adding a :description option to your system definition of cl-annot?

@export multiple vars/params at once

Rather than:

@export
(defparameter +moose-height+ 7)
@export
(defparameter +moose-width+ 11)
@export
(defvar *moose-times-seen* 0)

@export
(defun handle-moose-sighting () ...)

Is there a simple way to accomplish something like:

@export-block
(defparameter +moose-height+ 7)
(defparameter +moose-width+ 11)
(defvar *moose-times-seen* 0)

@export
(defun handle-moose-sighting () ...)

Thanks!

feature request: exporting the restart name

Restarts are also the important part of API. please:

@export
(restart-bind ...
   )

@export
(restart-case ...
  (name () ...))

and also the `case,ecase, ccase' keys (less priority):

@export
(case (something)
  (key1 ...)
  (key2 ...))

well, I might have to use a keyword for the restart name.

@export-structure on structures with docstrings does not work

export-structure doesn't work on defstructs with docstrings

I've changed the slot-specifiers definition to make it work, but I don't know if there are more things involved:

(defun slot-specifiers (class-definition-form)
"Return class-specifiers of CLASS-DEFINITION-FORM."
(case (first class-definition-form)
(defclass (nth 3 (progn-form-last class-definition-form)))
(defstruct (if (stringp (nth 2 (progn-form-last class-definition-form)))
;; There's a documentation string, fetch the slots after it
(nthcdr 3 (progn-form-last class-definition-form))
;; There's no documentation string, fetch the slots
(nthcdr 2 (progn-form-last class-definition-form))))))

Annotation annotation

Writing annotations will be easier if there is annotation annotation like:

@annotation (:inline t :arity 2)
(defmacro foo (x y) ...)

export-constructors doesn't export default constructor from defstruct when another constructor specified

defstruct in CL allows to specify several constructors. If second argument to the :constructor keyword provided, it is used as a constructor name. :constructor with no arguments creates a default constructor.
However if both BOA(By Order of Arguments) and explicit default constructor provided, the export-constructors macro exports only BOA constructor, see the session below:

CL-USER 28 > (defstruct (point (:constructor create-point (x y)) (:constructor)) x y)
POINT

CL-USER 29 > (create-point 10 20)
#S(POINT :X 10 :Y 20)

CL-USER 30 > (make-point :x 10 :y 10)
#S(POINT :X 10 :Y 10)

CL-USER 31 > (pprint (macroexpand '(cl-annot.class:export-constructors (defstruct (point (:constructor create-point (x y)) (:constructor)) x y))))

(PROGN
  (EXPORT '(CREATE-POINT))
  (DEFSTRUCT (POINT (:CONSTRUCTOR CREATE-POINT (X Y)) (:CONSTRUCTOR)) X Y))

@ignore bug

@ignore might fail to insert (declare (ignore ...) at the beginning of the body.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.