Salut à tous!
Voici un portage très simple et assez naif de TapTempo en Elixir. Elixir est un langage fonctionnel exécuté par la machine virtuelle d'Erlang. Il comprend des features intéressantes de flow programming, pattern matching etc. Les variables sont immuables de base et le langage ne comprend pas d'instructions pour boucler (le for
est utilisé uniquement pour des compréhensions) et incite donc a utiliser la récursion, plus fonctionnelle.
Le port lui-même est assez naïf mais fonctionne bien. Notez la compacité du code:
defmodule Taptempo do
def get_input do
get_input("", 0)
end
def get_input("q", count) do
{count, Time.utc_now()}
end
def get_input(_, count) do
IO.read(1)
|> String.trim
|> get_input(count + 1)
end
def calc_tempo({taps, end_time}, start_time) do
time_diff = Time.diff(end_time, start_time, :microsecond)
taps / (time_diff / 1000000) * 60
end
def print_tempo(tempo) do
IO.puts("Tempo: #{:erlang.float_to_binary(tempo, [decimals: 2])} bpm")
end
def main do
IO.puts("Appuyer sur la touche entrée en cadence (q pour quitter).")
start_time = Time.utc_now()
get_input()
|> calc_tempo(start_time)
|> print_tempo()
end
end
Taptempo.main()
Notez l'utilisation du pattern matching sur la fonction get_input
. Le pattern matching permet d'éxécuter des variations de la même fonction par rapport aux arguments qui sont passés. Elixir va chercher la fonction qui convient aux arguments donnés de haut en bas, d'où la définition du get_input
générique en dernier.
Le symbole |>
permet d'utiliser du flow programming en passant le retour d'une fonction en tant que premier argument pour la fonction suivante, un peu comme une pipe unix. Le flow dans main
pourrait donc s'écrire comme suit:
taps_info = get_input()
tempo = calc_tempo(taps_info)
print_tempo(tempo)
Ou aussi:
print_tempo(calc_tempo(get_input)))
Enfin, la fonction get_input
retourne un tuple, dénoté comme suit: {count, Time.utc_now()}
. Ce tuple est ensuite pattern matché directement par la fonction calc_tempo
, comme suit:
def calc_tempo({taps, end_time}, start_time) do
...
end
Si vous souhaitez exécuter le code, copiez-collez dans un fichier taptempo.ex
puis exécutez avec elixir taptempo.ex
.
# Elixir
Posté par mzf (site web personnel) . Évalué à 3.
Sympa cette version !
Je ne vois pas où se situe la boucle qui permet d'afficher les tempi successifs comme dans l'original. Est-elle cachée dans les appels récursifs ou il n'y a qu'un seul tempo qui est calculé lorsqu'on entre la lettre “q” ?
[^] # Re: Elixir
Posté par Cheuteumi . Évalué à 2. Dernière modification le 11 mars 2018 à 14:47.
Apparemment le programme n’affiche le résultat qu’une fois la touche "q" appuyée effectivement, car la fonction get_input se rappelle elle même jusqu’à trouver "q" en paramètre, et à ce moment là le compteur va être retourné avec le temps.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.