Jump to content

Featured Replies

Posted

I'm experimenting witn namespaces in Common Lisp. When I create a namespace like below, the symbols from the opusmodus namespace seems to be unknown:

 

(defpackage :com.wimdijkgraaf.tonnetz
  (:nicknames "TONNETZ" "TNNZ")
  (:use "COMMON-LISP" "OPUSMODUS" "TESTFRAMEWORK")
  (:export "APPLY-TONNETZ"))

(in-package :tonnetz)

;;; setup hash table for quick lookup
(defparameter *triad-interval-to-degrees* (make-hash-table :test 'equal))
;; major triads
(setf (gethash '(4 3) *triad-interval-to-degrees*) '(1 3 5))
(setf (gethash '(7 -3) *triad-interval-to-degrees*) '(1 3 5))
(setf (gethash '(8 -5) *triad-interval-to-degrees*) '(3 1 5))
(setf (gethash '(5 4) *triad-interval-to-degrees*) '(5 1 3))
(setf (gethash '(3 5) *triad-interval-to-degrees*) '(3 5 1))
(setf (gethash '(9 -4) *triad-interval-to-degrees*) '(5 3 1))

;; minor triads
(setf (gethash '(3 4) *triad-interval-to-degrees*) '(1 3 5))
(setf (gethash '(7 -4) *triad-interval-to-degrees*) '(1 3 5))
(setf (gethash '(9 -5) *triad-interval-to-degrees*) '(3 1 5))
(setf (gethash '(5 3) *triad-interval-to-degrees*) '(5 1 3))
(setf (gethash '(4 5) *triad-interval-to-degrees*) '(3 5 1))
(setf (gethash '(8 -3) *triad-interval-to-degrees*) '(5 3 1))

(defun get-root-intervals (triad)
  (midi-to-interval 
   (sort-asc (pitch-to-midi (ambitus-octaves 'c4 1 triad)))))

;;; tests
(deftest test-get-root-intervals ()
  (check 
    (equal (get-root-intervals '(g1 c9 e6)) '(4 3))
    (equal (get-root-intervals '(f3 d4 a4)) '(3 4))))
(test-get-root-intervals)

What happens is that the symbol ambitus-octaves is no longer found.

 

What do I do wrong?

Namespaces (packages) are a useful device to structure larger programs for avoiding clashes of functions names, variables etc.

 

If you want to import the symbols from another package you can use them, as you do in your code, but this only works for symbols explicitly exported by these packages. Judging from the response of opmo (Janusz?), this has not been done with the Opusmodus package.

 

You can do this yourself explicitly for all relevant symbols with export  (http://www.lispworks.com/documentation/HyperSpec/Body/f_export.htm), but that would mean a lot of work for 700 or so user-level functions in Opusmodus.

 

Alternatively, you could export all symbols of your package and use them in the Opusmodus package.

 

You can also use internal symbols of a package outside that package with a double-colon notation like om::ambitus-octaves. This notation is supposed to look ugly, but it is a convenient solution for you right now...

 

Best,

Torsten

Actually, Opusmodus uses very many symbols that are local to a certain package for pitches, note lengths, dynamics and articulations. You may need to make sure that all these symbols are always in the correct package. I just ran a little test, and it seems that certain things also work with the equivalent symbols in other packages such as (:h :c4 :pp), but I am not sure whether this always works. In other words, it is likely best to import your definitions into Opusmodus :)

 

Nevertheless, to keep your own code separate and portable it might still be useful to define it in its own package.

 

Best,

Torsten

 

 

 

  • Author

Thanks for the answers.

 

Have to give this a further thought how to best deal with this. Explicitly referencing to the package using the double-colon notation would be fine to me but unfortunately doesn't work (yet).

  • 2 months later...

> As from ver.1.2.21732 pitch, length, velocity and articulation symbols are part of the OM package and can be used with other packages.

Just for completeness, does this mean all these symbols are now exported? Also, does this include user-defined articulations?

 

BTW: For those who want to move expressions between packages, I defined the following (a very long time ago).

(defun convert-to-package (form from-package to-package)
  "converts the given form in the given package, i.e. if package is not the current package
it will add <package-name>:: in front of every symbol."
  (if (eq (find-package from-package) (find-package to-package))
    form
    (cond ((null form) nil)
          ((listp form)
           (loop for item in form 
                 collect  (convert-to-package item from-package to-package)))
          ((constantp form) form)
          ((symbolp form)
           (if (eq (symbol-package form) 
                   (find-package from-package))
             (intern (symbol-name form) to-package)    ; converts it to to-package
             form))                       ; pass it unchanged otherwise
          (T (error "Do not know how to handle ~A" form)))))

 

In order to get the user defined attributes (articulations) to the package you need the export the symbols:

(defpackage :Opusmodus
  (:nicknames :om)
  (:use :common-lisp)
  
  (:export
   user-symbol1
   user-symbol2
   ))

Everything else is in the package.

I like your CONVERT-TO-PACKAGE function.

Create an account or sign in to comment


Copyright © 2014-2025 Opusmodus™ Ltd. All rights reserved.
Product features, specifications, system requirements and availability are subject to change without notice.
Opusmodus, the Opusmodus logo, and other Opusmodus trademarks are either registered trademarks or trademarks of Opusmodus Ltd.
All other trademarks contained herein are the property of their respective owners.

Powered by Invision Community

Important Information

Terms of Use Privacy Policy