- Questo topic ha 7 risposte, 4 partecipanti ed è stato aggiornato l'ultima volta 5 anni, 5 mesi fa da
egreg9.
-
CreatoreTopic
-
9 Marzo 2021 alle 9:00 #119708::
Salve a tutti,
molto spesso nel valutare le espansioni mi sono accorto che ho un deficit nel metabolizzare il comportamento dei tokens in presenza delle parentesi graffe che delimitano i gruppi.
Sono andato in tilt analizzando un caso schematizzabile come sotto:
\expandafter\token1{ \token2….\tokenennesimo }
Come si comporta l’expandafter?
A naso mi verrebbe qualcosa del tipo
\token1{espansione del solo token2….\tokenennesimo}
E’ corretto?
Un saluto ed un grazie a tutti
A.
-
CreatoreTopic
-
AutoreRisposte
-
-
9 Marzo 2021 alle 10:11 #119709::
IL_MAGO_GANDALF” post=120184Salve a tutti,
molto spesso nel valutare le espansioni mi sono accorto che ho un deficit nel metabolizzare il comportamento dei tokens in presenza delle parentesi graffe che delimitano i gruppi.
Sono andato in tilt analizzando un caso schematizzabile come sotto:
\expandafter\token1{ \token2….\tokenennesimo }
Come si comporta l’expandafter?
A naso mi verrebbe qualcosa del tipo
\token1{espansione del solo token2….\tokenennesimo}
E’ corretto?
Un saluto ed un grazie a tutti
A.Ciao Mago Gandalf.
No. In quel caso viene espansa la parentesi graffa in se stessa.
Dovresti usare un altro \expandafter:
`\expandafter\token1\expandafter{\token2….\tokenennesimo }`Un saluto.
R.PS. molto meglio aggiungere un esempio di codice.
-
9 Marzo 2021 alle 10:46 #119710::
\expandafter è spiegato bene nella guida Appunti di programmazione in TeX e LaTeX.
Nel mini esempio che hai accluso al tuo messaggio hai fatto molta confusione fra i tipi di token. Non si legge bene sel dopo \token ci sia una L minuscola o una cifra 1 (problema dei font usati dal forum o problema dei miei occhi).
Tuttavia in linea di principio [t]\expandafter\A\B[/tt] espande prima \B e poi \A; se \A o \B non sono espandibili non è facilde dire che cosa succeda, ma certamente non quello che ci si aspetta; che cosa sia espandibile è un altro busillis; certo lo sono le macro; ma le macro non sono solo delle stringhe di lettere precedute ca \; sono tutto ciò che può ricevere una definizione, quindi anche \& oppure ~. Le graffe giocano ruli diversi e, come ti ha detto @robytex, viene considerata come una macro che non fa niente di particolare.
Nel guida che ti ho segnalato ci sono vari esempi di uso di \expandafter; compreso un esempio incui ne appaiono 7 di seguito, con la spiegazione del perché ce ne vogliono 7. Usarne 3 è relativamente frequente quando si creano macro; usarne 5 è meno frequente; usarne 7 è raro, ma mi pare di ricordare che Enrico una volta ne ha usati 15 di seguito; può darsi che mi ricordi male,ma non lo escludo.
Usare \expandafter è una cosa per acrobati molto navigati; quindi fai attenzione, perché rischi di combinare guai irreparabili.
-
9 Marzo 2021 alle 11:01 #119711::
Era una generalizzazione di un esempio inserito in un articolo di Enrico sui condizionali TeX/Latex
Mi sono accorto di aver errato pazzescamente io.
Riporto dall’articolo di Enrico :\def\fdef#1{%
\expandafter\def
\expandafter#1\expandafter
}
\fdef\testa{\iftrue a\else b\fi}L’argomento di \fdef è il solo token \testa e non il token \testa con il SUO argomento
che invece viene posto nella lista tokens alla fine, DOPO l’expandafter
L’expandafter finale consente di “saltare” la graffa (aperta) che racchiude appunto l’argomento della macro \testa.
Se non vado errato…questa volta…
Un saluto ed un grazie ancora!
-
12 Marzo 2021 alle 16:49 #119712::
IL_MAGO_GANDALF” post=120187Era una generalizzazione di un esempio inserito in un articolo di Enrico sui condizionali TeX/Latex
Mi sono accorto di aver errato pazzescamente io.
Riporto dall’articolo di Enrico :\def\fdef#1{%
\expandafter\def
\expandafter#1\expandafter
}
\fdef\testa{\iftrue a\else b\fi}L’argomento di \fdef è il solo token \testa e non il token \testa con il SUO argomento
che invece viene posto nella lista tokens alla fine, DOPO l’expandafter
L’expandafter finale consente di “saltare” la graffa (aperta) che racchiude appunto l’argomento della macro \testa.
Se non vado errato…questa volta…
Un saluto ed un grazie ancora!Infatti: se seguiamo l’espansione, da [tt]\fdef\testa{\iftrue a\else b\fi}[/tt] si ottiene
`
\expandafter\def\expandafter\testa\expandafter{\iftrue a\else\fi}
`
e in questo modo [tt]\iftrue[/tt] è espanso prima che venga elaborata la definizione; quindi si ottiene come se fosse
`\def\testa{a\else b\fi}`
con una differenza fondamentale. Esaminiamo
`
\def\fdef#1{%
\expandafter\def
\expandafter#1\expandafter
}
\fdef\testa{\iftrue a\else b\fi}
\def\testb{a\else b\fi}\ifx\testa\testb UGUALI\else DIVERSI\fi
\testa
\testb
\bye
`
da compilare con [tt]pdftex[/tt]. Il risultato è[attachment=2604]Screenshot2021-03-12at18.45.55.png[/attachment]
con alcuni messaggi di errore
`
! Extra \else.
\testb ->a\else
b\fi
l.12 \testb?
! Extra \fi.
\testb ->a\else b\fil.12 \testb
`
Nel caso di [tt]\testa[/tt], i token [tt]\else[/tt] e [tt]\fi[/tt] non producono errori perché sono già “marcati” come usati da un condizionale. Ma solo la prima volta che [tt]\testa[/tt] viene chiamata. I condizionali in TeX sono brutte bestie. 😆L’idea di [tt]\fdef[/tt] è solo di dimostrare che l’espansione di un condizionale non va “fino in fondo al [tt]\fi[/tt] corrispondente”, cosa che invece fa l’espansione di [tt]\else[/tt] se il condizionale che lo usa risulta vero.
Ciao
Enrico
Attachments:
You must be logged in to view attached files. -
16 Marzo 2021 alle 14:45 #119713::
Grazie Enrico,
per la tua preziosissima e dettagliata spiegazione.
Tutte queste perle mi aiutano molto nell’addentrarmi attraverso il complesso mondo delle marcro.
La più grossa difficoltà che ho è quella che incontra il programmatore “classico”.
Cioè la “serializzazione” delle operazioni che creano liste di tokens e che via via ad ogni espansione “lasciano sul campo di battaglia” i caratteri stampabili che compongono l’elaborato.
Grazie ancora
-
16 Marzo 2021 alle 17:03 #119714::
Enrico scusami il nuovo messaggio.
Riflettevo sull’esempio illuminante. Due soli chiarimenti:1) perchè l’errore sulla macro \testa compare solo dalla seconda chiamata?(se non vado errato è da qui che in memoria ho la definizione compiuta in cui è scomparso i\ftrue)
2) il messaggio che si voleva trasmettere è che:
se attraverso il condizionale partendo dalla prima condizione tutto scorre ma
se pensassi di “attraversare” solo il ramo \else le cose andrebbero diversamente non arrivando ad un regolare passaggio per l’ \else sino all’espansione del \fiHo capito bene 🙂
Un saluto ed un grazie ancora per questi preziosissimi esempi che aiutano a capire a fondo ciò che si usa.
A.
-
18 Marzo 2021 alle 16:23 #119715::
IL_MAGO_GANDALF” post=120239Enrico scusami il nuovo messaggio.
Riflettevo sull’esempio illuminante. Due soli chiarimenti:1) perchè l’errore sulla macro \testa compare solo dalla seconda chiamata?(se non vado errato è da qui che in memoria ho la definizione compiuta in cui è scomparso i\ftrue)
2) il messaggio che si voleva trasmettere è che:
se attraverso il condizionale partendo dalla prima condizione tutto scorre ma
se pensassi di “attraversare” solo il ramo \else le cose andrebbero diversamente non arrivando ad un regolare passaggio per l’ \else sino all’espansione del \fiHo capito bene 🙂
Un saluto ed un grazie ancora per questi preziosissimi esempi che aiutano a capire a fondo ciò che si usa.
A.TeX mantiene un contatore interno del livello di annidamento dei condizionali, in modo da sapere a quale livello appartenga un [tt]\else[/tt] o un [tt]\fi[/tt]. Il contatore aumenta di uno a ogni condizionale e diminuisce di uno quando viene incontrato il relativo [tt]\fi[/tt]. Lo si può verificare con [tt]\tracingifs=2[/tt]. Compilando
`
\tracingifs=2\def\fdef#1{%
\expandafter\def
\expandafter#1\expandafter
}
\fdef\testa{\iftrue\else b\fi}\testa
%\testa
\bye
`
con [tt]pdftex[/tt] si ottiene, nel file log
`
{vertical mode: \iftrue: (level 1) entered on line 7}
{\else: \iftrue (level 1) entered on line 7}
{\fi: \iftrue (level 1) entered on line 7}
`
Se togliamo il commento, otterremo nel log
`
{vertical mode: \iftrue: (level 1) entered on line 7}
{\else: \iftrue (level 1) entered on line 7}
{\fi: \iftrue (level 1) entered on line 7}
{\else: \if (level 0)}! Extra \else.
`
Non ci sarebbe alcuna annotazione se invece di [tt]\fdef[/tt] si fosse usato [tt]\def[/tt], perché TeX non interpreta in alcun modo i token nel corpo di una definizione. Ma con [tt]\fdef[/tt] il condizionale è eseguito prima che [tt]\def[/tt] faccia il suo lavoro (e, in particolare, non va “vedere” [tt]\else[/tt] e [tt]\fi[/tt].Il contatore interno non è accessibile a livello delle macro e non è influenzato dai gruppi.
Ciao
Enrico
-
-
AutoreRisposte
- Devi essere connesso per rispondere a questo topic.