Je suis en train d'apprendre le lisp avec le livre de Graham "ANSI Common Lisp" et comme exercice j'écris des calculs de calendrier basés sur le jour de Julian. Comme vous le savez, le dimanche de Pâques change d'année en année et il y a environ 10 autres jours spéciaux dont la date réelle dépend de la date du dimanche de Pâques.Utilisation d'une macro pour définir les fonctions de calcul des 10 dates liées à Pâques
Je veux définir une fonction pour chacun de ces jours, tous suivant le schéma suivant:
(defun carnaval (year)
"Carnaval Monday of YEAR.
This is 48 days before Easter Sunday."
(- (easter year) 48))
Au lieu de répéter 10 fois des déclarations similaires, il semble approprié d'utiliser une macro:
(defmacro %defeasterday (function-name screen-name offset)
`(defun ,function-name (year)
,(format nil "~A of YEAR.~%~%This is ~A day~:p ~A Easter Sunday"
screen-name
(abs offset)
(if (< 0 offset) "after" "before"))
(+ (easter year) ,offset)))
(Le début %
marque mon intention de ne pas exporter la macro dans le package où elle est définie.)
La macro peut être utilisée pour d éfinir une fonction pour chacun des jours dont la date est basée sur la date de l'est Dimanche:
(%defeasterday carnaval "Carnaval Monday" -48)
(%defeasterday mardi-gras "Mardi gras" -47)
(%defeasterday ash "Ash Wednesday" -46)
…
Maintenant, pour le bien de l'exercice, je voudrais emballer toutes les données sur une liste et utiliser la %defeasterday
macro ses articles. Ma tentative a été
(mapC#'(lambda (args) (apply #'%defeasterday args))
'((carneval "Carneval Monday" -48)
(mardi-gras "Mardi gras" -47)
(ash "Ash Wednesday" -46)))
Cela échoue avec
Execution of a form compiled with errors.
Form:
#'%DEFEASTERDAY
Compile-time error:
The :macro name %DEFEASTERDAY was found as the argument to FUNCTION.
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]
qui me apprend qu'une macro est pas « juste un code de mappage de fonction code » car apply
est pointilleux sur les cours d'exécution.
Comment puis-je utiliser la macro %defeasterday
ci-dessus pour itérer sur une liste?
(Si vous avez besoin d'une fonction ad hoc easter
aux fins de test, s'il vous plaît (defun easter() 2457860)
qui donne la réponse attendue pour 2017.)
Merci beaucoup pour votre réponse, c'est une très belle proposition. Je laisse la question ouverte pendant quelques jours, au cas où quelqu'un voudrait aussi écrire une réponse alternative. –