pgf-tikz / pgf

A Portable Graphic Format for TeX
https://pgf-tikz.github.io/
1.13k stars 108 forks source link

ifthenelse evaluates both branches #1006

Open hmenke opened 3 years ago

hmenke commented 3 years ago

Brief outline of the bug

ifthenelse always evaluates both branches, regardless of the condition. It should short-circuit and only evaluate the branch that is actually taken.

Minimal working example (MWE)

\documentclass{article}
\usepackage{pgfmath}
\begin{document}
\pgfmathprint{ifthenelse(1 == 1, 1, 1/0)}
\pgfmathprint{ifthenelse(0 == 1, 1/0, 1)}
\end{document}
muzimuzhi commented 3 years ago

It seems some laziness support is needed, either internal to ifthenelse and ?, or public as, for example \pgfmathdeclarelazy(function|operator).

ilayn commented 3 years ago

Also related questions in TeX.SX

hmenke commented 3 years ago

The culprit lies in the fact that the definition of \pgfmathifthenelse is

\pgfmathifthenelse:
macro:#1#2#3->\pgfmathparse {#1}\let \pgfmath@argument@1 =\pgfmathresult \pgfmathparse {#2}\let \pgfmath@argument@2 =\pgfmathresult \pgfmathparse {#3}\let \pgfmath@argument@3 =\pgfmathresult \pgfmathifthenelse@ {\pgfmath@argument@1 }{\pgfmath@argument@2 }{\pgfmath@argument@3 }

So we either need some separate implementations for all functions to handle laziness or we just redefine \pgfmathifthenelse after it has been defined using \pgfmathdeclarefunction. Are there any other functions that have to evaluate their arguments lazily?

muzimuzhi commented 3 years ago

Are there any other functions that have to evaluate their arguments lazily?

and and or

\pgfmathprint{and(false, 1/0)}
\pgfmathprint{or(true, 1/0)}