Release notice: Abjad 3.12

8 views
Skip to first unread message

Trevor Bača

unread,
Sep 22, 2022, 11:10:41 AM9/22/22
to abjad...@googlegroups.com

Hi,

Abjad 3.12 is now available:

https://github.com/Abjad/abjad/releases

https://pypi.org/project/abjad/

Abjad 3.12 is a bridge release that helps users of Abjad’s rhythm-makers migrate from Abjad 3.11 to Abjad 3.13. No other changes are included in the release.

In Abjad 3.11, the usual way of working with Abjad’s rhythm-makers is through defining an (object-oriented and persistent) stack of (object-oriented and persistent) command objects. This is done with a collection of factory functions, and the resulting stack is then called (like a function) on a list of divisions to make notes, rests and tuplets:

stack = rmakers.stack(
    rmakers.even_division([8], extra_counts=[1]),
    rmakers.force_fraction(),
    rmakers.beam(),
)
divisions = [(2, 8), (2, 8), (2, 8)]
stack(divisions)
[Tuplet('3:2', "c'8 c'8 c'8"), Tuplet('3:2', "c'8 c'8 c'8"), Tuplet('3:2', "c'8 c'8 c'8")]

In Abjad 3.12, this is no longer necessary. The package’s command objects can be avoided in favor of pure functions. No object-oriented framework is required, and the output of each line of code can be examined after it runs. This makes rhythms easier to design and debug; it also makes it much easier to mix the functionality of Abjad’s rhythm-makers with user-defined custom functions:

>>> divisions = [(2, 8), (2, 8), (2, 8)]
>>> music = rmakers.even_division_function(divisions, [8], extra_counts=[1])
>>> rmakers.force_fraction_function(music)
>>> rmakers.beam_function(music)

Rhythms designed to be used throughout a score can be encapsulated in function. And it makes sense to use a temporary Abjad container when building rhythms because Abjad recognizes tied notes only when they are housed in an Abjad container. The 200+ examples in the abjad-ext-rmakers package have been rewritten according to a basic pattern that looks like this:

def make_rhythm(divisions):
    music = rmakers.even_division_function(divisions, [8], extra_counts=[1])
    container = abjad.Container(music)
    rmakers.force_fraction_function(container)
    rmakers.beam_function(container)
    music = abjad.mutate.eject_contents(container)
    return music
divisions = [(2, 8), (2, 8), (2, 8)]
make_rhythm(divisions)
[Tuplet('3:2', "c'8 c'8 c'8"), Tuplet('3:2', "c'8 c'8 c'8"), Tuplet('3:2', "c'8 c'8 c'8")]

How to migrate existing rhythm-maker code? Abjad 3.12 provides a shadow interface to facilitate migration. The old factory functions remain in the package but are deprecated in favor of a new set of pure functions, named in parallel:

DEPRECATED IN ABJAD 3.12:

rmakers.accelerando()
rmakers.after_grace_container()
rmakers.assign()
rmakers.beam()
rmakers.beam_groups()
rmakers.before_grace_container()
rmakers.bind()
rmakers.cache_state()
rmakers.denominator()
rmakers.duration_bracket()
rmakers.even_division()
rmakers.example()
rmakers.extract_trivial()
rmakers.feather_beam()
rmakers.force_augmentation()
rmakers.force_diminution()
rmakers.force_fraction()
rmakers.force_note()
rmakers.force_repeat_tie()
rmakers.force_rest()
rmakers.incised()
rmakers.invisible_music()
rmakers.multiplied_duration()
rmakers.note()
rmakers.on_beat_grace_container()
rmakers.reduce_multiplier()
rmakers.repeat_tie()
rmakers.rewrite_dots()
rmakers.rewrite_meter()
rmakers.rewrite_rest_filled()
rmakers.rewrite_sustained()
rmakers.split_measures()
rmakers.stack()
rmakers.talea()
rmakers.tie()
rmakers.tremolo_container()
rmakers.trivialize()
rmakers.tuplet()
rmakers.unbeam()
rmakers.untie()
rmakers.written_duration()

NEW IN ABJAD 3.12:

rmakers.accelerando_function()
rmakers.after_grace_container_function()
rmakers.beam_function()
rmakers.beam_groups_function()
rmakers.before_grace_container_function()
rmakers.denominator_function()
rmakers.duration_bracket_function()
rmakers.even_division_function()
rmakers.extract_trivial_function()
rmakers.feather_beam_function()
rmakers.force_augmentation_function()
rmakers.force_diminution_function()
rmakers.force_fraction_function()
rmakers.force_note_function()
rmakers.force_repeat_tie_function()
rmakers.force_rest_function()
rmakers.incised_function()
rmakers.invisible_music_function()
rmakers.multiplied_duration_function()
rmakers.note_function()
rmakers.on_beat_grace_container_function()
rmakers.reduce_multiplier_function()
rmakers.repeat_tie_function()
rmakers.rewrite_dots_function()
rmakers.rewrite_meter_function()
rmakers.rewrite_rest_filled_function()
rmakers.rewrite_sustained_function()
rmakers.split_measures_function()
rmakers.talea_function()
rmakers.tie_function()
rmakers.tremolo_container_function()
rmakers.trivialize_function()
rmakers.tuplet_function()
rmakers.unbeam_function()
rmakers.untie_function()
rmakers.written_duration_function()

Note that the pure functions introduced in Abjad 3.12 are suffixed in _function() for only one release. In Abjad 3.13, the old factory functions will be removed, and the pure functions will lose their suffix. The Abjad 3.13 version of the pattern shown above will look like this:

def make_rhythm(divisions):
    music = rmakers.even_division(divisions, [8], extra_counts=[1])
    container = abjad.Container(music)
    rmakers.force_fraction(container)
    rmakers.beam(container)
    music = abjad.mutate.eject_contents(container)
    return music

TL;DR Abjad 3.12 implements two different interfaces to the functionality of Abjad’s rhythm-makers. Use Abjad 3.12 to port existing rhythm-maker code from Abjad 3.11 to Abjad 3.13.

Happy composing,

Trevor & Josiah

Reply all
Reply to author
Forward
0 new messages