# Defining a dimension with or without @

If I am writing a TeX package (as one can find such on CTAN), there are following approaches to define a new dimension length that should be changeable by a user of that package.

• Approach A: Define an inaccessible dimension with @ and an accessible macro for setting (see also meaning of @)

\newdimen\PKG@length \PKG@length=5pt
\def\setPKGlength#1{\PKG@length=#1}


and ask the user to modify the dimension with \setPKGlength{7pt}

• Approach B: Define an accessible dimension without @

\newdimen\PKGlength \PKGlength=5pt


and ask the user to modify the dimension with standard techniques like \setlength{\PKGlength}{7pt} in LaTeX or \PKGlength{7pt} in plain TeX (see also What is the right way to set a dimension parameter?).

Which approach is safer to use or has more advantages? Any alternatives?

-
I think the answer to your question will depend on what you're trying to do. Are you writing a package? Are there parameters in the package that are necessary for implementation but not at the user level? Who are you writing the code for? And other similar questions. If you can provide a little bit more of context for what you're trying to accomplish, I think you'll get a much more satisfactory answer. –  A.Ellett Jan 20 '13 at 2:48
Thx. More info is added in first sentence. Please assume I want to write an package and the package is like one on CTAN. Yes, there are parameters that are used only for implementation, but they are hidden with @ anyway. My question is about a parameter that is used by both, implementation and user. –  e-birk Jan 20 '13 at 12:36

## Setting a dimension

There are several ways:

• LaTeX:

\newcommand*{\setPKGlength}[1]{\setlength{\PKG@length}{#1}}


Advantage: Package calc is automatically supported.

• e-TeX:

\def\setPKGlength#1{\PKG@length=\dimexpr(#1)\relax}

• plain-TeX:

\def\setPKGlength#1{\PKG@length=#1\relax}


Do not forget the final \relax (see Joseph Wright's answer)

## Approach A (setter function and internal register name)

• If the fact that PKGlength uses a TeX dimension register is an implementation detail, then it should be hidden, e.g. by using the @-notation and providing a setter function. Then the internal representation can be easily changed, e.g. using a macro instead of a register.

• An additional macro for setting is needed at least.

• Without a getter function it is hard to obtain the current value and, thus, it is difficult to set a relative value, e.g. setting the length value to 50% of the current setting.

## Approach B (direct dimension register)

• Fast access without overhead for setting the value.

• Read access, it is possible to set relative values, e.g.:

\PKGlength=.5\PKGlength


• The dimension register becomes part of the package interface that forbids later changes of the storage type (dimension register, macro, ...).

## Setting via key value interface

The question mentions both LaTeX and plain TeX, therefore I am using my packages kvdefinekeys and kvsetkeys that can be used with LaTeX, plain TeX and even iniTeX. Alternatives for LaTeX are keyval, xkeyval, pgfkeys, l3keys, ...

\newdimen\PKG@length
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname RequirePackage\endcsname\relax
% plain TeX
\input kvdefinekeys.sty\relax
\input kvsetkeys.sty\relax
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname dimexpr\endcsname\relax
% without \dimexpr
\kv@define@key{PKG}{PKGlength}{\PKG@length=#1\relax}%
\else
% with \dimexpr
\kv@define@key{PKG}{PKGlength}{\PKG@length=\dimexpr(#1)\relax}%
\fi
\else
\RequirePackage{kvdefinekeys}%
\RequirePackage{kvsetkeys}%
\kv@define@key{PKG}{PKGlength}{\setlength{\PKG@length}{#1}}%
\fi
\def\PKGsetup#1{% or \newcommand for \LaTeX
\kvsetkeys{PKG}{#1}%
}

% usage example
\PKGsetup{PKGlength=5pt}

-
A potential advantage of the setter/getter approach may also be its extensibility: If in a future release or another package you need to do THING whenever the dimension is changed (such as recalculate a layout) then this can be accomplished by hooking into the setter. –  Daniel Jan 20 '13 at 18:07
@heiko-oberdiek Just a note: Was the edit at Approach A, Disadvantages, from "getter" to "setter" function correct? Maybe the sentence was hold too short and it should read: "Without a getter function it is hard to obtain the current value and, thus, it is difficult to set a relative value, e.g. ......" –  e-birk Jan 20 '13 at 22:04
@e-birk You are right, thanks, answer edited accordingly. –  Heiko Oberdiek Jan 21 '13 at 9:29

Using a specific author interface rather than exposing the internals to the author has the benefits of flexibility for future changes. For example, I as an author, I might have used your macro \setPKGlength{7pt} in five papers.

If this command was used by the package internally and you as the maintainer of the package might have decided to change you macro to \setlengthPKG{7pt} for readability reasons, I will not be able to still process my previous papers.

Exposing an interface rather than internal commands is a common paradigm in many computer languages programming. In the case of TeX/LaTeX it also brings consistency in the equation (internal commands should have an @), external should not have them.

Edit

My own preference is to expose PGF keys style interface for cases where a multitude of parameters are required (see longer example), such as:

\cxset{try textheight/.code=\global\setlength\trytextheight@cx{#1},
try textheight/.default=\textheight,
....
try topmargin/.code=\global\setlength\trytopmargin@cx{#1},
try topmargin/.default=\topmargin,...
}


For simpler cases, setting quick setters and getters is my preferred coding style:

\documentclass{article}
\usepackage{lipsum}
\makeatletter
%  Properties.
\def\ece#1#2{\expandafter#1\csname#2\endcsname}%

% \setproperty@cx{atom}{propertyname}{value} defines the property
% propertyname  on the atom'' atom to have value.

\def\setproperty@cx#1#2#3{\ece\protected@edef{#1@p#2}{#3}}%

% \getproperty@cx{atom}{propertyname} expands to the value of the property
% propertyname on atom.

\def\getproperty@cx#1#2{%
\expandafter\ifx\csname#1@p#2\endcsname\relax
\else \csname#1@p#2\endcsname
\fi
}

\long\def\setminipage@cx#1#2{%
\setproperty@cx{boxwidth}{width}{\dimexpr#1\relax}%
\fbox{%
\minipage{\getproperty@cx{boxwidth}{width}}
\raggedright #2
\endminipage
}%
}

\def\setparindent@cx#1{%
\setproperty@cx{parindent}{value}{\dimexpr#1\relax}%
\parindent\getproperty@cx{parindent}{value}%
%begins a paragraph if necessary
\leavevmode
}

% Author command API

\let\SetParagraphIndentation\setparindent@cx
\let\SmallBox\setminipage@cx

\makeatother

\begin{document}

\SmallBox{25pt+35pt}{lorem ipsum dorem. Lorem\par lorem.}

\lipsum[5]
\SetParagraphIndentation{.5in + 2cm + 10pt}
\lipsum[5]
\end{document}

-
The problem of name changing applies to macros as well as parameters. Hence, a stable interface is good and necessary as you said. But what should the interface contain? Macros (approach A) or parameters directly (approach B)? I am not so clear about that from your answer... –  e-birk Jan 20 '13 at 13:01
@e-birk I always prefer a macro and preferably using a key value interface. If LaTeX, I would use PGF keys. Will expand on my answer to make it a bit clearer. –  Yiannis Lazarides Jan 20 '13 at 14:15
@e-birk Please see edit. Hope it is now a bit more clear. –  Yiannis Lazarides Jan 20 '13 at 17:46
Thank you! Hence, key value interfaces are the state of the art. And otherwise using getter and setter functions to hide the implementation. –  e-birk Jan 20 '13 at 22:22
@e-birk Think of key values as your json implementation for LaTeX:) –  Yiannis Lazarides Jan 21 '13 at 9:41