Trucco usato per annidamento IF

  • Creatore
    Topic
  • #101550
    Up
    0
    Down
    ::


    Gentilissimi,
    diverso tempo fa scrissi un post nel vecchio forum al quale mi rispose il buon Enrico con una dettagliata spiegazione.
    Il tutto riguardo al trucco per l’annidamento degli \if. (\if TT\fi)
    Riporto in buona sostanza la spiegazione:

    “Supponiamo di volerci definire un comando che restituisca il ramo “vero” se un certo numero è pari, quello “falso” se il numero è dispari. Una costruzione come

    \def\ifiseven#1#2#3{\ifodd #1\relax #3\else #2\fi}

    funzionerebbe benissimo. Ma a volte questa non è una buona procedura, perché è complicato annidare i condizionali. Perciò si può fare in un altro modo:
    \newif\ifiseven
    \def\iseven#1{TT\fi\ifodd #1\relax\isevenfalse\else\iseventrue\fi\ifiseven}
    Ora il codice
    \iseven{}\else\fi

    funziona anche annidato in altri condizionali.
    Infatti l’espansione di \if prevede l’espansione del token che segue, in questo caso \iseven che prima di tutto raccoglie il suo argomento; a questo punto viene sostituita la lista di token della definizione e la lista diventa

    \if TT\fi\ifodd\relax\isevenfalse\else\iseventrue\fi\ifiseven
    \else\fi

    Dopo l’\if ci sono due token non espandibili e \if TT\fi sparisce senza fare nulla (con espansione vuota, per la precisione) e il condizionale richiesto viene valutato correttamente.

    Se invece il codice “\if\iseven{}\else\fi” fosse all’interno del ramo non seguito da un altro condizionale, TeX accoppia \if con \fi ed è felicissimo di gettare via quei token alla svelta”.

    Quello che non capisco sono le ultime due righe:
    “a cosa ci si riferisce per “ramo non seguito da altro condizionale”?
    Quale è l’\if che viene accoppiato con \fi?

    Certo del vostro aiuto vi ringrazio in anticipo
    Alessandro

Visualizzazione 4 filoni di risposte
  • Autore
    Risposte
    • #101551
      Up
      0
      Down
      ::

      IL_MAGO_GANDALF” post=101339Gentilissimi,
      diverso tempo fa scrissi un post nel vecchio forum al quale mi rispose il buon Enrico con una dettagliata spiegazione.
      Il tutto riguardo al trucco per l’annidamento degli \if. (\if TT\fi)
      Riporto in buona sostanza la spiegazione:

      “Supponiamo di volerci definire un comando che restituisca il ramo “vero” se un certo numero è pari, quello “falso” se il numero è dispari. Una costruzione come

      \def\ifiseven#1#2#3{\ifodd #1\relax #3\else #2\fi}

      funzionerebbe benissimo. Ma a volte questa non è una buona procedura, perché è complicato annidare i condizionali. Perciò si può fare in un altro modo:
      \newif\ifiseven
      \def\iseven#1{TT\fi\ifodd #1\relax\isevenfalse\else\iseventrue\fi\ifiseven}
      Ora il codice
      \iseven{}\else\fi

      funziona anche annidato in altri condizionali.
      Infatti l’espansione di \if prevede l’espansione del token che segue, in questo caso \iseven che prima di tutto raccoglie il suo argomento; a questo punto viene sostituita la lista di token della definizione e la lista diventa

      \if TT\fi\ifodd\relax\isevenfalse\else\iseventrue\fi\ifiseven
      \else\fi

      Dopo l’\if ci sono due token non espandibili e \if TT\fi sparisce senza fare nulla (con espansione vuota, per la precisione) e il condizionale richiesto viene valutato correttamente.

      Se invece il codice “\if\iseven{}\else\fi” fosse all’interno del ramo non seguito da un altro condizionale, TeX accoppia \if con \fi ed è felicissimo di gettare via quei token alla svelta”.

      Quello che non capisco sono le ultime due righe:
      “a cosa ci si riferisce per “ramo non seguito da altro condizionale”?
      Quale è l’\if che viene accoppiato con \fi?

      Certo del vostro aiuto vi ringrazio in anticipo
      Alessandro

      Hai provato a dare un’occhiata al pacchetto etoolbox?

      Ciao
      Claudio

    • #101552
      Up
      0
      Down
      ::

      IL_MAGO_GANDALF” post=101339[…]
      Quello che non capisco sono le ultime due righe:
      “a cosa ci si riferisce per “ramo non seguito da altro condizionale”?
      Quale è l’\if che viene accoppiato con \fi?
      […]

      Semplicemente, ci si riferisce a quello che succede se il codice
      `\if\iseven{}\else\fi`
      compare annidato in un altro candizionale esterno, così:
      `\if … % condizionale esterno
      % Ramo 1

      \if\iseven{}\else\fi

      \else
      % Ramo 2

      \fi`
      L’«altro condizionale» è quello marcato con il commento [tt]% condizionale esterno[/tt]. Supponiamo, per esempio, che tale condizionale esterno risulti falso: ebbene, in tal caso il «ramo non seguito da un altro condizionale» è quello etichettato [tt]% Ramo 1[/tt] e l’[tt]\if[/tt] che viene accoppiato con [tt]\fi[/tt] è quello all’inzio della linea` \if\iseven{}\else\fi`(e il [tt]\fi[/tt] è quello alla fine della stessa linea).

      Piuttosto, non capisco: Enrico ti avrebbe detto che la macro definita da
      `\def\ifiseven#1#2#3{\ifodd #1\relax #3\else #2\fi}`
      non può essere usata all’interno di altri condizionali?

      Ciao.


      Gustavo

    • #101553
      OldClaudio
      Partecipante
        Up
        0
        Down
        ::


        I comandi condizionali sono oggetti strani, anche perché vengono eseguiti durante le fasi preliminari dell’elaborazione del testo sorgente, e quindi potrebbero succedere cose stranissime; se guardi nella sezione ArsTeXnica di questo forum trovi un mio articolo sulla “fragilità degli \if che ti permette di capire il tutto, e ti permette di scrivere condizionali robusti.

        Leggilo e capirai anche perché talvolta ci vogliono costruzioni “ardite” o “sporchi trucchi” per evitare che i condizionali fragili si rompano.

      • #101554
        Up
        0
        Down
        ::


        Carissimi,
        in primis grazie a tutti per il puntuale supporto.
        @Gustavo–>enrico mi aveva spiegato il motivo per il quale si usava l’artificio “TT \fi” e quindi si passava al \newif..etc etc, cioè che l’annidamento di condizionali poteva creare un problema.
        Una sola precisazione a quello che credo sia un refuso nel messaggio di spiegazione:
        “Supponiamo, per esempio, che tale condizionale esterno risulti falso: ebbene, in tal caso il «ramo non seguito da un altro condizionale» è quello etichettato % Ramo 1 e l’\if che viene accoppiato con \fi è quello all’inzio della linea”
        Se il condizionale esterno risulta falso il ramo da seguire non è il ramo 2 quello con l’else?(se appunto \if di partenza risulta falso)
        Un grazie ancora e….ora provo a leggere l’articolo nella sezione ArsTexnica.
        Buon weekend a tutti
        Alessandro

      • #101555
        Up
        0
        Down
        ::

        IL_MAGO_GANDALF” post=101348[…]
        Una sola precisazione a quello che credo sia un refuso nel messaggio di spiegazione:
        “Supponiamo, per esempio, che tale condizionale esterno risulti falso: ebbene, in tal caso il «ramo non seguito da un altro condizionale» è quello etichettato % Ramo 1 e l’\if che viene accoppiato con \fi è quello all’inzio della linea”
        Se il condizionale esterno risulta falso il ramo da seguire non è il ramo 2 quello con l’else?(se appunto \if di partenza risulta falso)
        […]

        …E quindi il ramo non seguito è il ramo 1. 🙂

        Ciao.


        Gustavo

    Visualizzazione 4 filoni di risposte
    • Devi essere connesso per rispondere a questo topic.

    Go to top