Skip to content
View in the app

A better way to browse. Learn more.

Opusmodus

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Using arrows package in OM (threading macros, pipeline syntax)

Featured Replies

I would like to use the threading macros, pipeline syntax of arrows package in order to reduce the nesting in LISP code to allow a better readability and understanding (and avoid the alternative repeated reassignment of variables with overwriting multiple times setf).

I think often we have chained operations using OMs functions (see example) where the arrow syntax in my personal view is helpful to understand the step-by-step computation, simply reading from top to bottom and holds the steps still in compact form which increases comprehension.

https://quickdocs.org/arrows

I can use it in OM but need to use namespace in front of the arrow.

I cannot import the arrow symbol ->> (same for ->) into OM, see error message in comment of code block.

Any help ?

Can we use the arrows in OM directly ?

(asdf:load-system :arrows)


;; Test works, but only by prepending namespace before the symbol, which is tedious
(setf var
      (arrows:->> 
       (gen-noise 8)
       (vector-smooth 0.3)
       (vector-to-pitch '(c3 c5))
       ))
=> (d3 d3 a3 c3 d4 c5 b4 c5)


;; Trying to import the ->> symbol fails.
(import 'arrows:->>)
=>
Error: Importing this symbol into the OPUSMODUS package causes a name conflict: ->>.
  1 (continue) Unintern these symbols and try again
  2 Skip importing these symbols.
  3 (abort) Return to top loop level 0.
    
  • Cliff changed the title to Using arrows package in OM (threading macros, pipeline syntax)
  • Author

With some help of Gemeni LLM (my common-LISP skills are yet under-developed), following solution seems to work:

;; Before: Trying to import the ->> symbol fails.
;; After: Fix first unintern the symbol, before importing
(unintern '->>)
(import 'arrows:->>)

(setf var
      (->> 
       (gen-noise 8)
       (vector-smooth 0.3)
       (vector-to-pitch '(c3 c5))
       ))

=> (d3 d3 a3 c3 d4 c5 b4 c5)
;;; Nice, see how clean the code above looks like :-)

But Gemeni warns me, that this might be a hacky solution as OMs ->> may no longer be functional.

@opmo :

  • Would you as long-time developer agree that the syntax (threading macros, pipeline syntax of arrows package) is elegant and worth while to offer/expose to OM users right out of the box w/o need to load external packages ?

  • I personally would love this as a built-in feature, as it bridges the gap between thinking in step-by-step procedures (musical processing and development) and LISP.

To convince you or others, see example below how clean & powerful this syntax is 😀...

(setf var
      (->> 
       (gen-noise 8)
       (vector-smooth 0.3)
       (vector-to-pitch '(c3 c5))
       (pitch-transpose 12)
       (tonality-map '(major :root 'eb3 :map 'octave))
       (ambitus '(c4 c6))
       ))
=> (eb4 eb4 d4 c4 bb4 gs4 eb5 bb4)
    

If you see this error:

"Error: Importing this symbol into the OPUSMODUS package causes a name conflict: ->>."

then you need to assign a different name to it; otherwise, OM will stop working as it should.

Something like that can be done. I can look into it after I finish the Morpheus tool.

Personally , I like to use encapsulation:

(setf var (ambitus

'(c4 c6)

(tonality-map

'(major :root 'eb3 :map 'octave)

(pitch-transpose

12

(vector-to-pitch

'(c3 c5)

(vector-smooth

0.3

(gen-noise 8)))))))

=> (eb4 eb4 d4 bb4 eb5 eb5 bb4 d5)

  • Author

@Stephane Boussuge Thank you, as you say its a preference and there is no right and wrong.

For my eyes the unesting (reading and coding from bottom to top and inner to outer) of LISP forms is extra mental effort. I have not so much an issue during development time, but rather reading and understanding other peoples (including my future me) code is harder than it could be.

Just to add to my argument and to explain where I am coming from, in the programming language R of my day job there was several years ago a big boost in adoption by the introduction of the %>% pipe operator by the magrittr package. Today piping is part of R core and became the defacto standard in composing complex pipelines which are still very comprehensible.

  • 5 months later...
  • Author
On 12/11/2025 at 8:13 PM, opmo said:

If you see this error:

"Error: Importing this symbol into the OPUSMODUS package causes a name conflict: ->>."

then you need to assign a different name to it; otherwise, OM will stop working as it should.

Something like that can be done. I can look into it after I finish the Morpheus tool.

Dear @opmo : Any plans to enable pipeline syntax by intergrating it into OM ?

  • Author

That would be phantastic. Thanks @opmo for considering.

  • Author

Thank you very much @opmo , great addition which simplifies coding during iterative development and makes longer code pipelines more easier to read and comprehend.

My Version 4.0.31331 (latest available at time of writing) seems not to support it yet.

@opmo I guess the new version will be made available soon ?

  • Author

The arrows library is part of the OM system now. You will be able to write the code without the need of package name.

@opmo : Version 4.0.31331 (latest available at time of writing):

(->>
 (gen-noise 8)
 (vector-smooth 0.3)
 (vector-to-pitch '(c3 c5))
 (pitch-transpose 12)
 (tonality-map '(major :root 'eb3 :map 'octave))
 (ambitus '(c4 c6))
 )

results in:

Error: Undefined operator ->> in form (->> (gen-noise 8) (vector-smooth 0.3) (vector-to-pitch (quote (c3 c5))) (pitch-transpose 12) (tonality-map (quote (major :root # :map #))) (ambitus (quote (c4 c6)))).
  1 (continue) Try invoking ->> again.
  2 Return some values from the form (->> (gen-noise 8) (vector-smooth 0.3) (vector-to-pitch (quote (c3 c5))) (pitch-transpose 12) (tonality-map (quote (major :root # :map #))) (ambitus (quote (c4 c6)))).
  3 Try invoking something other than ->> with the same arguments.
  4 Set the symbol-function of ->> to another function.
  5 Set the macro-function of ->> to another function.
  6 (abort) Return to top loop level 0.
Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.

This works in the 31432 update. I've not come across this methodology before but it looks very neat.

  • Author

Thx again @opmo .

I appreciate that you added not just the ->> but also the more flexible -<> pipe syntax.

It's useful when one wants to define with <> the exact location for the former pipeline intermediate result, especially for functions where order of parameters is more involved.

Example:

(setf v1
      (-<>
       (gen-noise 8 :seed 42)
       (vector-smooth 0.3 <>)
       (vector-to-pitch '(c3 c5) <>)
       (pitch-transpose 12 <>)
       (tonality-map '(major :map 'octave) <>)
       (make-omn :pitch <>
                 :length '(h)
                 :span :pitch)))

;; (h g4 mf g4 f4 c4 a4 f5 a5 c6)

I can contribute back and make a few examples starting from canonical OM-official docu were we can showcase how to apply the pipe syntax.

Any interest in?

Create an account or sign in to comment


Copyright © 2014-2026 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

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.