Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I often get conflicts between distinct sty files, due to things as simple as variable names.

The latest one was between proof.sty (which permits to more proofs automatically to the appendix) and llncs.sty (which is required by many conference and journals to insure a homogeneous look and feel), which both define a variable named exercise and hence produce a conflict.

One solution would be to expect each sty file to prefix all its variables with the name of the library implemented, but this is not a clean solution. Is there any way in LaTeX to provide some encapsulation, or at least to define some local variables, as I think is the usage in modern programming languages?

share|improve this question
3  
No, there are no namespaces in (La)TeX. Internal names should be prefixed but for user macros and environments like the exercise it is often not done. You could "undefine" this environment/macro (there are no "variables" in TeX) using \let\exercise\relax between the loading of the two packages. Also TeX is not meant as a modern programming language and should not be compared to one, IMHO. –  Martin Scharrer Feb 13 '12 at 10:04
1  
related: tex.stackexchange.com/questions/136329/… –  Jubobs Feb 20 at 12:57
add comment

3 Answers

up vote 11 down vote accepted

There is no such thing as encapsulation in (La)TeX, but even if there was one it will still possibly present a problem due to the nature of author commands. What do I mean? As (La)TeX is essentially a mark-up language, if you were to develop a package to for example provide macros to markup exercises, in all probability at the user level, you want to offer a:

\begin{exercise}
…
\end{exercise}

type of commands rather than \begin{MXexercise}. However to minimize problems and clashes with other packages, package and class authors do use prefixes and the @ symbol. A great example is the LaTeX3 conventions although IMHO this conservative approach taken to the extreme can damage code readability.

TeX also has a grouping mechanism where you can define macros and other commands locally. Anything between a group is defined locally. For example:

\def\acommand{43}

    \bgroup
       \def\acommand{42}
       In group \acommand
    \egroup

Outside group \acommand

The above will print 43 outside the group, but 42 within the group. The \bgroup and \egroup are just longhand for {}. You can have as many nesting groups as you need with the same effect.

Good practice IMHO, is for packages to stay focused to a single purpose and minimize author commands. Internally they can use prefixes or suffixes to avoid clashes.

For class authors the class itself should load a set of recommended packages for its common usage and any patches needed be applied by the class. Some classes go to the other extreme (such as the KOMA and Memoir) and define their own packages or incorporate functionality in the main code.

I understand your pain as I have been a user of hyperref for a long time. However, clashes can easily be bypassed as follows:

\usepackage{packageA}
\let\oldcommand\culprit % command from package A causing errors in package B.
\let\culprit\undefined

\usepackage{packageB}

If you want to use the \culprit somewhere do the reverse letting.

share|improve this answer
add comment

There is the simplest name-packaging, what is called block structure:

\def\foo{\begingroup{%
  \def\bar{bar}\endgroup}

where the \bar is only available inside \foo's grouping, i.e., lexically scoped inside the group of calling \foo.
(with parameters, for example: \def\foo#1{{\def\bar##1{##1}\bar{#1}}})

I don't know why blocks aren't used more often with TeX; there might be a reason for that.

share|improve this answer
2  
dont you need a group in there as well? After your first call of \foo, \bar is available in that current scope of \foo expansion? So lexically scoped in the group of calling \foo. Not just inside \foo. –  zeroth Feb 13 '12 at 11:04
    
@zeroth: oops, yeah, thanks for the correction! I wanted to keep the definition simple and omitted the grouping. One could begin a group inside the definition and then the previous statement would have been correct. I think. –  morbusg Feb 13 '12 at 11:14
add comment

The savesym package offers a way of passing off the responsibility for dealing with multiply-defined macros onto the user. Right now it's probably your best option for dealing with inconsiderate macro naming.

Moving into the realm of fantasy, it would not be hard for package authors to adopt the following strategy:

  • Put all their macros in the package "namespace". I favor the convention, which I use for internal variables in my ytableau package, of using the namespace as a suffix rather than a prefix, so the macros are indexable alphabetically. Thus, \ytableaushort@YT and so on.

  • Provide a list of all publicly available macro names, in a form such as \ThisPackageDefinesMacros{ytableaushort, ydiagram, ytableausetup} and \ThisPackageDefinesEnvironments{ytableau}. Alternatively, the \newcommand and \newenvironment macros could be replaced by package versions that do this (like the \RequirePackage macro that packages should use instead of \usepackage). These would just dump their contents into some internal list-macros that would be parsed by...

  • The user of the package can then reveal the macros they want, possibly all of them, using commands such as \UsingMacros[ytableau]{ytableaushort, ydiagram} or \UsingEnvironments[ytableau]{ytableau}. (As a convenience, the first argument should default to the last loaded package. As a further convenience, there should probably be something like \UsingAllMacros[ytableau] in case you don't care to pick and choose.)

These macros should be a standard tool provided by LaTeX itself, or at least by a package that's independent of the others (i.e. everyone should not try to define their own "using" macros). It would take me ten minutes to write such a thing, but of course, it would be useless unless most packages edited it into their code.

This would also answer the question posed by Can we easily find all the commands, tokens, whatevers defined by a package?, which I think deserves a good answer. Just because TeX is an antiquated programming language doesn't mean it can't be used to provide some modern conveniences.

share|improve this answer
    
Thanks. You (and others) have convinced me to use suffixes instead of prefixes. about your second point, though: where would it make sense to publish the list of user macros? In the log? –  Jubobs Feb 20 at 13:07
    
@jubobs I was thinking of the package documentation –  Ryan Reich Feb 20 at 16:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.