[erlang-questions] Best choice for complex data structure

zxq9 <>
Thu Jan 24 19:00:48 CET 2019


On 2019年1月24日木曜日 11時08分09秒 JST you wrote:
> Hi Craig,
> 
> Thanks so much for sharing this.  You're very generous.
> 
> I have a fully functional MIDI module with a tested and effective set of 
> low level IO.  I'm working now at the meta level (as a composer), 
> looking to translate some impressionistic higher level ideas through 
> intermediary functions to MIDI output.
> 
> I'm also just learning Erlang, so I'm sure some of my questions are very 
> naive.
> 
> What is:
> 
> Score :: [{InsertTime, Title, SegmentStart, SegmentStop, MIDI_Data, 
> RepeatMeta}]
> 
> Is Score a variable -- or a type that is a list of tuples?

Nice! Welcome to Erlang!
Once your eyes adjust I think you'll thoroughly enjoy it around here. :-D

And yes, you are spot on, `Score` above is a type specification.
You'll find this helpful:
http://erlang.org/doc/reference_manual/typespec.html

It is the required notation when talking to Dialyzer (obviously) but also useful when communicating amongst Erlangers.
I gave quite a few type specification examples in the original message, so that link will help you decipher them.

Everything capitalized is a possible type (a type variable that I left undefined -- use your imagination about what type of values might be useful in those places) and everything that is lower-case is an actual definite type. Parens after a lower-case string are a defined type, an atom with no parens is just the atom. A pipe (like `|`) is an "or".

To get more specific...


  Score :: [{InsertTime, Title, SegmentStart, SegmentStop, MIDI_Data, RepeatMeta}]
    where InsertTime   :: time_unit(),
          Title        :: string(),
          SegmentStart :: time_unit(),
          SegmentStop  :: time_unit(),
          MIDI_Data    :: binary(),
          RepeatMeta   :: none | repeat_meta().

  -type time_unit() :: non_neg_integer() % an integer value in milliseconds representing absolute time
                     | {time_signature(), Beats :: non_neg_integer()}.


The above isn't 100% proper type notation (the way Score is defined looks like a -spec, not a -type, but it is a useful notation amongst erlangers, anyway), and I never defined what `repeat_meta()` should be, but should convey some general idea what I intended.

The point in expressing things this way is that a list of MIDI segments (which already carry their own musical data, relative to themselves) can be included as data into a higher-level program with the addition of metadata that is meaningful to that higher-level program, and the resulting list of MIDI segment points (some composed locally, some referenced from a library -- the origin not being important) can be synthesized by a program to produce a new MIDI output readable by a musical notation output program that reads MIDI, or by a player.

That may or may not be what you're looking for (maybe you want to write a musical synthesis program that focuses specifically on musical architecture, in which case your real focus is the segment meta and arrangements among the segments, not the actual MIDI data), but hopefully this gives you some ideas for thinking of data as more than just nested data or OOP-style "objects".

-Craig


More information about the erlang-questions mailing list