vshesh
Hi everyone,
trying to encode some information about music (a different structure than the harmonex package).
I have an earlier implemenation of what I want in python (from a previous project). It heavily uses enums to describe the structure of pitch classes, intervals, chords etc.
eg one of them:
"""
Simple mapping of note name to MIDI value mod 12.
MIDI 0th octave begins at 12 + this value. (so C0 = 12, A0 = 21, etc)
"""
import aenum
Pitch : 'Pitch' = IntEnum('Pitch', {
# note, this order is NOT random
# raw note names are preferred to enharmonic equivalents
# flats are preferrable to sharps (jazz musician here)
'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11,
'Db':1, 'Gb':6, 'Ab':8, 'Bb':10, 'Eb': 3,
'C#':1, 'D#':3, 'G#':8, 'A#':10, 'F#': 6,
# these are just weird, so they exist only as aliases for B/C E/F respectively.
'Fb':4,'E#':5,'B#':0, 'Cb':11
})
Is there something equivalent in erlang/elixir that allows me to have similar properties as an enum like this? “Just use a map” only allows me to do lookups in one direction - i also want to be able to do them in the other direction. So would want to be able to do:
> Pitch.C
Pitch.C (as opposed to 0 as the representation)
> Pitch("A#") => Pitch.Aꖛ #found a unicode character that elixir accepts that looks like a sharp
> Pitch(:Cꖛ) => Pitch.Cꖛ
> Pitch(12) => Pitch.C #appropriate instance, mod 12
> Pitch(10) => Pitch.Bb # chooses the first instance when there are more than one option
> Pitch.C => Directly choose the right instance
> Pitch.C = Pitch.Cꖛ => :false
> import Pitch; import Interval
> C + m2 => Pitch.Cꖛ
> major_scale = [U, M2, M3, P4, P5, M6, M7] # these are Interval.U, Interval.M2 etc
> minor_11 = ~I(m3 P5 m7 M9 P11) => [m3, P5, m7, m9, P11] # again, Interval.m3, Interval.P5 etc
The shorthand import structure are very useful to not have to type out Pitch._ and Interval._ every time.
Is this what @ is for?
defmodule Pitch
@C = 0
@Cs= 1
@Db= 1
@D = 2
...
end
?
Trending in Questions
Hello!
Suppose you are building workflow (order / task / payment) processing system with the following requirements:
Each workflow con...
New
I’m aware of 2 such projects, are there others?
git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hi everyone.
My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
How Can I Optimise Compile Time Dependencies
I have been building an elixir application for about 2 years now. Many modules and files ha...
New
Other Trending Topics
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #performance










Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
kip
Since the order is important, an Elixir/erlang map is not the right structure since order is not defined
If the list is known at compile time (ie its static) then you can compile your mappings into functions. For example:
Since functions clauses are resolved in lexical order, this implementation does rely on the keys and the values being unique.
vshesh
how are you unquoting outside of a
quote do ... endblock?kip
In Elixir this is referred to as an unquote fragment.
You may also find this post helpful.
eksperimental
Just to illustrate how to achieve the bi-directional structure you were looking for.
eksperimental
Elegant solution.
The only one caveat is that since the numbers are not unique you will get a warning saying a previous clause always matches
kip
Yes, you are right and I’m definitely not sure my approach is the best one but I like it for its expressiveness and simplicity.
vshesh
Spent some time working on @kip’s solution and ended up with
(I broke up some of what I wrote above into a forward search
pitchfunction and a backwards lookupnamefunction. Doing them both in one function was just weird now that I decided to have a struct, which is the only way to get an implementation ofto_stringandinspectworking).used like so:
Then I can do
I don’t understand this warning:
I read the docs and it doesn’t explain how to make this warning change? Just explains that consolidation is used for improving lookup speed.
Let me know if this is sensible or downright strange
eksperimental
when are you calling this line?
If that happens after your code has been compile, you will get that warning. It usually happens in tests or from IEx
vshesh
Yeah I learned that ElixirLS is just complaining and things work fine when I run with
iex -S mixI’m pretty happy with this final solution for now, so leaving it here in case it helps others: