g | x | w | all
Bytes Lang Time Link
nan240913T140512ZLegendar
161Scala231020T090429Z138 Aspe
025JavaScript ES6231019T234625ZNeil
051Python 3231019T232025ZNick Ken
024R231019T175216ZNick Ken
170Java 8231018T145703ZKevin Cr

Binary Lambda Calculus (25 bits)

Since lambda calculus has no general definition of a "list" and no specific argument encoding was required, I use a variation of n-tuples that directly embeds a mapping function:

lst A B C D ... = \ms.(s (m A) (m B) (m C) (m D) ...)

A variadic fixed-point combinator is then equivalent to a normal fixed-point combinator like y:

vfix = \f.(\m.(m m) \x.(f (x x))
     = 0001000110100001110011010 (25 bits)

Example

Written in pseudo lambda calculus:

g = \ghx.(zero? x true (h (x - 1)))
h = \ghx.(zero? x false (g (x - 1)))
rec = vfix \ms.(s (m g) (m h))

even :: Number -> Bool
even = rec \gh.g

odd :: Number -> Bool
odd = rec \gh.h

Here \gh.g and \gh.h are the tuple selectors. For n elements in the initial list, these will need n arguments respectively.

Scala, 161 bytes

Port of @Kevin Cruijssen'Java answer in Scala.


Golfed version. Try it online!

trait C{def t(o:Any):Any}
trait F{def f():C}
trait P{def c(func:Array[F]):C}
object P{def g(a:Array[P]):Array[F]={a.map(p=>new F{override def f():C=p.c(g(a))})}}

Ungolfed version. Try it online!

trait C {
  def t(o: Any): Any
}

trait F {
  def f(): C
}

trait P {
  def c(func: Array[F]): C
}

object P {
  def g(a: Array[P]): Array[F] = {
    a.map(p => new F { override def f(): C = p.c(g(a)) })
  }
}

object Main extends App {
  val evenOddFix: Array[P] = Array(
    new P { override def c(func: Array[F]) = new C { override def t(n: Any) = if (n.asInstanceOf[Int] == 0) true else func(1).f().t(n.asInstanceOf[Int]-1) } },
    new P { override def c(func: Array[F]) = new C { override def t(n: Any) = if (n.asInstanceOf[Int] == 0) false else func(0).f().t(n.asInstanceOf[Int]-1) } }
  )

  val evenOddFunctions: Array[F] = P.g(evenOddFix)
  val evenFunc = evenOddFunctions(0).f()
  val oddFunc = evenOddFunctions(1).f()

  for(input <- 0 to 5){
    val evenResult = evenFunc.t(input)
    val oddResult = oddFunc.t(input)
    println(s"Input: $input → Even: $evenResult; Odd: $oddResult")
  }
}

JavaScript (ES6), 25 bytes

g=a=>a.map(p=>_=>p(g(a)))

;h=g([a=>n=>!n||a[1]()(n-1),a=>n=>!!n&&a[0]()(n-1)]);for(i=0;i<6;i++)console.log(h.map(f=>f()(i)));

Port of @KevinCruijssen's Java answer.

Python 3, 55 51 bytes

y=lambda a:[(lambda x:lambda:x(y(a)))(x)for x in a]

Try it online!

A lambda taking a list of mutually recursive functions and returning a list of functions that return functions. Unlike R, Python doesn’t have lazy evaluation of function arguments so an extra step is needed to delay function evaluation from happening within the call to y itself; I think this is analogous to the Java answer from @KevinCruijsson.

The even odd and Collatz examples here look like this:

even_odd_fix = [
 lambda f:lambda n:n==0 or f[1]()(n-1),
 lambda f:lambda n:n!=0 and f[0]()(n-1)
]

collatz_fix = [
 lambda f:lambda n,d=0:d if n==1  else f[int(n%2+1)]()(n,d+1),
 lambda f:lambda n,d:f[0]()(n//2,d),
 lambda f:lambda n,d:f[0]()(3*n+1,d)
]

even_odd = [f() for f in y(even_odd_fix)]
collatz = y(collatz_fix)[0]()

[print(x, "Even:", even_odd[0](x), "Odd:", even_odd[1](x), "Collatz:", collatz(x)) for x in range(1,11)]

Note that the functions returned must be called without an argument to return the actual useful function.

R, 24 bytes

y=\(a)Map(\(x)x(y(a)),a)

Attempt this Online!

A recursive function that takes a list of functions and returns a list of functions. The input list of functions should be a list of mutually recursive functions. Each function within this list should take a list of functions as an argument, and return a function that makes use of one or more members of the function list.

Inspiration taken from the Haskell answer in Bubbler’s comment, as well as @KevinCruijssen’s Java answer.

Examples shown in the ATO link above and below are even/odd, mod 3 and Collatz problem.

even_odd_fix = list(
 is_even=\(func)\(n)!n||func$is_odd(n-1),
 is_odd=\(func)\(n)!!n&&func$is_even(n-1)
)

mod3_fix = list(
 is_0_mod3 = \(func)\(n)!n||func$is_2_mod3(n-1),
 is_1_mod3 = \(func)\(n)!!n&&func$is_0_mod3(n-1),
 is_2_mod3 = \(func)\(n)!!n&&func$is_1_mod3(n-1)
)

# Somewhat contrived mutually recursive list of functions to determine how many steps of the Collatz procedure to get to 1
coll_fix = list(
 \(func)\(n,d=0)if(n==1)d else func[[2+n%%2]](n,d+1),
 \(func)\(n,d)func[[1]](n/2,d),
 \(func)\(n,d)func[[1]](3*n+1,d)
)

even_odd = y(even_odd_fix)
mod3 = y(mod3_fix)
collatz_depth = y(coll_fix)[[1]]

Java 8, 170 bytes

interface C{Object t(Object o);}interface F{C f();}interface P{C c(F[]f);static F[]g(P[]a){return java.util.Arrays.stream(a).map(p->(F)()->p.c(g(a))).toArray(F[]::new);}}

Based on @user's Java answer for the related Implement Fix2 combinator challenge, as well as my Java answer for the related Golfed fixed point combinator challenge.

Explanation:

interface C{           // Completed Function interface
  Object t(Object o);} //  Using a function that transforms a given Object

interface F{           // Function interface
  C f();}              //  A wrapper to pass the 'Completed Function' as function

interface P{           // Program interface
  C c(F[]f);           //  Which takes an array of 'Function's as argument,
                       //  and returns a 'Completed Function'
  
  static F[]g(P[]a){   //  Recursive function that accepts an array of 'Program's as argument,
                       //  and returns an array of 'Function's
    return java.util.Arrays.stream(a)
                       //   Convert the given 'Program's-array to a generic Stream
      .map(p->         //   Map each 'Program' in this Stream to:
             (F)       //    A casted 'Function' (necessary since it's a generic instead of typed Stream)
             ()->      //    which wraps:
               p.c(    //     A completed call to its own 'Program' interface
                 g(    //      Using a recursive call to its own function
                   a)) //      with the given 'Program's-array as argument
      .toArray(F[]::new);}}
                       //   After the map: convert the Stream to a 'Function's-array

The method to call is P::g, which takes an array of P as argument and returns an array of F. To obtain a completed function C from an F, we can call F::f on it. P represents the function to be fixed, and its method c takes F as argument to prevent immediate evaluation, returning a C that represents a complete function to transform a given Object o with C's t(o).

Example even/odd implementation:

P[] evenOddFix = {
  func -> n -> (int)n == 0 ? true : func[1].f().t((int)n-1),
  func -> n -> (int)n == 0 ? false : func[0].f().t((int)n-1)
};
F[] evenOddFunctions = P.g(evenOddFix);
C evenFunc = evenOddFunctions[0].f(),
  oddFunc = evenOddFunctions[1].f();
Object evenResult = evenFunc.t(input),
       oddResult = oddFunc.t(input);

Try it online.