Truth table generator for an arbitrary function Summary: This function generates a truth table for a boolean function of variable number of arguments. The name of the function passed and its arguments are deduced outside of the computable function scope. The returned value is a logical matrix with columns corresponding to function arguments and result.

library(R.utils)
library(stringr)

truthTable &lt;- function(func, valuesOnly = F) {
  numArguments &lt;- length(formals(func))
  if(valuesOnly) {
    values &lt;- vector(length = 2^numArguments)
    for (i in 1:(2^numArguments)) {
      arguments &lt;- rev(as.logical(intToBits(i-1)))[-(1:(32-numArguments))]
      values[i] &lt;- do.call(func, as.list(arguments))
    }
    return(values)
  }
  result &lt;- matrix(nrow = 2^numArguments, ncol = numArguments + 1)
  colnames(result) &lt;- c(names(formals(func)), as.character(substitute(func)))
  for (i in 1:(2^numArguments)) {
    arguments &lt;- rev(as.logical(intToBits(i-1)))[-(1:(32-numArguments))]
    result[i, ] &lt;- c(arguments, do.call(func, as.list(arguments)))
  }
  return(result)
}


Example:

majority &lt;- function(a, b, c) {
  return ((a &amp; b) | (b &amp; c) | (a &amp; c))
}

truthTable(majority)


Result:

         a     b     c majority
[1,] FALSE FALSE FALSE    FALSE
[2,] FALSE FALSE  TRUE    FALSE
[3,] FALSE  TRUE FALSE    FALSE
[4,] FALSE  TRUE  TRUE     TRUE
[5,]  TRUE FALSE FALSE    FALSE
[6,]  TRUE FALSE  TRUE     TRUE
[7,]  TRUE  TRUE FALSE     TRUE
[8,]  TRUE  TRUE  TRUE     TRUE


Possible improvements:


Faster conversion of numeric iterator to logical vector
Usage of apply instead of iterative computation


What could be improved?

Any advice would be appreciated.
The main flaw that can be observed in your function is the presence of code duplication: expressions such as 2^numArguments and arguments &lt;- rev(as.logical(intToBits(i-1)))[-(1:(32-numArguments))] appear multiple times. Code duplication is generally bad, you could refactor so that each of them appears only one time.

Other little things:


R.utils and stringr are loaded but never used.
It's better to use FALSE instead of F.


Here is an alternative solution using expand.grid:

truthTable2 &lt;- function(func, valuesOnly = FALSE) {
  args &lt;- formals(func)
  L &lt;- setNames(rep(list(c(TRUE, FALSE)), length(args)), names(args))
  df &lt;- expand.grid(L)
  result &lt;- sapply(1:nrow(df), function(i) do.call(func, lapply(df, `[`, i)))
  # or result &lt;- do.call(func, df) if func is vectorized
  if (valuesOnly) {
    unname(result)
  } else {
    df[[substitute(func)]] &lt;- result
    as.matrix(df)
  }
}

truthTable(majority)
#          a     b     c majority
# [1,]  TRUE  TRUE  TRUE     TRUE
# [2,] FALSE  TRUE  TRUE     TRUE
# [3,]  TRUE FALSE  TRUE     TRUE
# [4,] FALSE FALSE  TRUE    FALSE
# [5,]  TRUE  TRUE FALSE     TRUE
# [6,] FALSE  TRUE FALSE    FALSE
# [7,]  TRUE FALSE FALSE    FALSE
# [8,] FALSE FALSE FALSE    FALSE




Benchmark:

bench::mark(
  truthTable(majority),
  truthTable2(majority),
  check = FALSE
)
# # A tibble: 2 x 13
# expression                min  median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result memory time 
# &lt;bch:expr&gt;            &lt;bch:t&gt; &lt;bch:t&gt;     &lt;dbl&gt; &lt;bch:byt&gt;    &lt;dbl&gt; &lt;int&gt; &lt;dbl&gt;   &lt;bch:tm&gt; &lt;list&gt; &lt;list&gt; &lt;lis&gt;
# 1 truthTable(majority)   89.5us  97.4us     9634.    1.44KB     6.22  4650     3      483ms &lt;lgl[~ &lt;df[,~ &lt;bch~
# 2 truthTable2(majority) 189.6us 204.7us     4292.        0B     4.07  2110     2      492ms &lt;lgl[~ &lt;df[,~ &lt;bch~
# # ... with 1 more variable: gc &lt;list&gt;


bigf &lt;- function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) TRUE

bench::mark(
  truthTable(bigf),
  truthTable2(bigf),
  check = FALSE
)
# # A tibble: 2 x 13
#   expression             min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result               memory            time    gc           
#   &lt;bch:expr&gt;        &lt;bch:tm&gt; &lt;bch:tm&gt;     &lt;dbl&gt; &lt;bch:byt&gt;    &lt;dbl&gt; &lt;int&gt; &lt;dbl&gt;   &lt;bch:tm&gt; &lt;list&gt;               &lt;list&gt;            &lt;list&gt;  &lt;list&gt;       
# 1 truthTable(bigf)     2.13s    2.13s     0.469      64MB     5.63     1    12      2.13s &lt;lgl[,18] [131,072 ~ &lt;df[,3] [262,351~ &lt;bch:t~ &lt;tibble [1 x~
# 2 truthTable2(bigf)    2.43s    2.43s     0.412    76.5MB     5.77     1    14      2.43s &lt;lgl[,18] [131,072 ~ &lt;df[,3] [262,218~ &lt;bch:t~ &lt;tibble [1 x~
# Warning message:
# Some expressions had a GC in every iteration; so filtering is disabled.