torstenanders Posted August 2, 2020 Share Posted August 2, 2020 I like how the function unfold allows for rather concisely expressed transformations. I also like that with this function, methods can easily by commented out or added without changing the nesting structure of the overall Lisp program. However, what I do not like is that the unfold methods don't support any further arguments, and as a result the required preliminary work with def-unfold-set is rather cumbersome. So, I rolled by own version of unfold that addresses this shortcoming. This new function works as follows: you can use the names of arbitrary Opusmodus functions, as long as they expect an OMN sequence as first argument. The following example applies first the function gen-retrograde and then quantum to the material mat. (setf mat '((q c4 d4 e4) (h f4 q b3))) (fn-unfold '((gen-retrograde) (quantum :fraction -0.2)) mat) => ((7W B3 7H._QT F4 -E..) (E E4 D4 S. C4 -ET)) If you would like to have functions with more concise names (as unfold does), just define functions with shorter names. Here are some examples. (defun tr (sequence transpose &key (section NIL) (exclude NIL) (ambitus 'piano) (omn NIL)) "Like pitch-transpose, but sequence as first param." (pitch-transpose transpose sequence :section section :exclude exclude :ambitus ambitus :omn omn)) (defun ld (sequence values &key set ignore seed (section NIL) (exclude NIL) (omn NIL)) "Like length-divide, but sequence as first param." (length-divide values sequence :set set :ignore ignore :section section :exclude exclude :omn omn :seed seed)) With the definitions above, we can now use fn-unfold as follows for computing an octave transposition of mat and then applying length-divide to the second bar with the given settings. (fn-unfold '((tr 12) (ld (2 3) :section 1)) mat) => ((Q C5 D5 E5) (3H E5 FS5 G5 3Q A4 BB4 CS5)) BTW: The definition of fn-unfold is pretty short. By far the longest part of this definition is the doc string (defun fn-unfold (fns sequence) "Much like the buildin Opusmodus `unfold`, but instead works with functions and additional arguments can be given to the functions. Apply to `sequence` all fns in order. * Arguments: - fns (list of lists): Each sublist has the form (<omn-fn> &rest <args>), where <omn-fn> is a function expecting an OMN sequence as first argument and arbitrary further argments, and <args> are the further arguments beyond the OMN sequence given to the function. - sequence: OMN sequence * Examples: Some material to use ;;; (setf mat '((q c4 d4 e4) (h f4 q b3))) Remember: all functions used must expect a OMN sequence as *first* argument. ;;; (fn-unfold '((gen-retrograde) (quantum :fraction -0.2)) mat) Some short-hand versions of common functions are defined for conciseness. ;;; (fn-unfold '((tr 12) (ld (2 3) :section 1)) mat) " (reduce (lambda (seq fn) (apply (if (functionp (first fn)) (first fn) (fdefinition (first fn))) seq (rest fn))) fns :initial-value sequence)) JulioHerrlein 1 Quote Link to comment Share on other sites More sharing options...
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.