Quite the series of questions you have here. Here's my take on it:
We start with a way to construct lists
- nilis a constant which represents the empty list
- cons (x, list)constructs a new list with- xadded to the front of- list
// nil : List a
const nil =
  (c, n) => n
// cons : (a, List a) -> List a
const cons = (x, y = nil) =>
  (c, n) => c (y (c, n), x)
// list : List Number
const myList = 
  cons (1, cons (2, cons (3, cons (4, nil))))
console.log (myList ((x, y) => x + y, 0))
// 10
 
 
And to satisfy your golfy variadic curried interface, here is autoCons
const autoCons = (init, n) => 
{ const loop = acc => (x, n) =>
    isFunction (x)
      ? acc (x, n)
      : loop (cons (x, acc))
  return loop (nil) (init, n)
}
const isFunction = f =>
  f != null && f.constructor === Function && f.length === 2
const nil =
  (c, n) => n
const cons = (x, y = nil) =>
  (c, n) => c (y (c, n), x)
console.log
  ( autoCons (1) ((x,y) => x + y, 0)             // 1
  , autoCons (1) (2) ((x,y) => x + y, 0)         // 3
  , autoCons (1) (2) (3) ((x,y) => x + y, 0)     // 6
  , autoCons (1) (2) (3) (4) ((x,y) => x + y, 0) // 10
  )
 
 
Our encoding makes it possible to write other generic list functions, like isNil
// isNil : List a -> Bool
const isNil = l =>
  l ((acc, _) => false, true)
console.log
  ( isNil (autoCons (1))     // false
  , isNil (autoCons (1) (2)) // false
  , isNil (nil)              // true
  )
Or like length
// length : List a -> Int
const length = l =>
  l ((acc, _) => acc + 1, 0)
console.log
  ( length (nil)                  // 0
  , length (autoCons (1))         // 1
  , length (autoCons (1) (2))     // 2
  , length (autoCons (1) (2) (3)) // 3
  )
Or nth which fetches the nth item in the list
// nth : Int -> List a -> a
const nth = n => l =>
  l ( ([ i, res ], x) =>
        i === n
          ? [ i + 1, x ]
          : [ i + 1, res]
    , [ 0, undefined ]
    ) [1]
console.log
  ( nth (0) (autoCons ("A") ("B") ("C")) // "A"
  , nth (1) (autoCons ("A") ("B") ("C")) // "B"
  , nth (2) (autoCons ("A") ("B") ("C")) // "C"
  , nth (3) (autoCons ("A") ("B") ("C")) // undefined
  )
We can implement functions like map and filter for our list
// map : (a -> b) -> List a -> List b
const map = f => l =>
  l ( (acc, x) => cons (f (x), acc)
    , nil
    )
// filter : (a -> Bool) -> List a -> List a
const filter = f => l =>
  l ( (acc, x) => f (x) ? cons (x, acc) : acc
    , nil
    )
We can even make a program using our list which takes a list as an argument
// rcomp : (a -> b) -> (b -> c) -> a -> c
const rcomp = (f, g) =>
  x => g (f (x))
// main : List String -> String   
const main = letters =>
  autoCons (map (x => x + x))
           (filter (x => x !== "dd"))
           (map (x => x.toUpperCase()))
           (rcomp, x => x)
           (letters)
           ((x, y) => x + y, "")
main (autoCons ("a") ("b") ("c") ("d") ("e"))
// AABBCCEE
Run the program in your browser below
const nil =
  (c, n) => n
const cons = (x, y = nil) =>
  (c, n) => c (y (c, n), x)
const isFunction = f =>
  f != null && f.constructor === Function && f.length === 2
const autoCons = (init, n) => 
{ const loop = acc => (x, n) =>
    isFunction (x)
      ? acc (x, n)
      : loop (cons (x, acc))
  return loop (nil) (init, n)
}
const map = f => l =>
  l ( (acc, x) => cons (f (x), acc)
    , nil
    )
const filter = f => l =>
  l ( (acc, x) => f (x) ? cons (x, acc) : acc
    , nil
    )
const rcomp = (f, g) =>
  x => g (f (x))
const main = letters =>
  autoCons (map (x => x + x))
           (filter (x => x !== "dd"))
           (map (x => x.toUpperCase()))
           (rcomp, x => x)
           (letters)
           ((x, y) => x + y, "")
console.log (main (autoCons ("a") ("b") ("c") ("d") ("e")))
// AABBCCEE
 
 
Sorry, my bad
Let's rewind and look at our initial List example
// list : List Number
const myList = 
  cons (1, cons (2, cons (3, cons (4, nil))))
console.log
  ( myList ((x, y) => x + y, 0) // 10
  )
We conceptualize myList as a list of numbers, but we contradict ourselves by calling myList (...) like a function.
This is my fault. In trying to simplify the example, I crossed the barrier of abstraction. Let's look at the types of nil and cons –
// nil : List a
// cons : (a, List a) -> List a
Given a list of type List a, how do we get a value of type a out? In the example above (repeated below) we cheat by calling myList as a function. This is internal knowledge that only the implementer of nil and cons should know
// myList is a list, not a function... this is confusing...
console.log
  ( myList ((x, y) => x + y, 0) // 10
  )
If you look back at our original implementation of List, 
// nil : List a
const nil =
  (c, n) => n
// cons : (a, List a) -> List a
const cons = (x, y = nil) =>
  (c, n) => c (y (c, n), x)
I also cheated you giving simplified type annotations like List a. What is List, exactly?
We're going to address all of this and it starts with our implementation of List
List, take 2
Below nil and cons have the exact same implementation. I've only fixed the type annotations. Most importantly, I added reduce which provides a way to get values "out" of our list container.
The type annotation for List is updated to List a r – this can be understood as "a list containing values of type a that when reduced, will produce a value of type r." 
// type List a r = (r, a) -> r
// nil : List a r
const nil =
  (c, n) => n
// cons : (a, List a r) -> List a r
const cons = (x, y = nil) =>
  (c, n) => c (y (c, n), x)
// reduce : ((r, a) -> r, r) -> List a -> r
const reduce = (f, init) => l =>
  l (f, init)
Now we can maintain List as a sane type, and push all the wonky behavior you want into the autoCons function. Below we update autoCons to work with our list acc using our new reduce function
const autoCons = (init, n) => 
{ const loop = acc => (x, n) =>
    isFunction (x)
      // don't break the abstraction barrier
      ? acc (x, n)
      // extract the value using our appropriate list module function
      ? reduce (x, n) (acc)
      : loop (cons (x, acc))
  return loop (nil) (init, n)
}
So speaking of types, let's examine the type of autoCons –
autoCons (1)                  // "lambda (x,n) => isFunction (x) ...
autoCons (1) (2)              // "lambda (x,n) => isFunction (x) ...
autoCons (1) (2) (3)          // "lambda (x,n) => isFunction (x) ...
autoCons (1) (2) (3) (add, 0) // 6
Well autoCons always returns a lambda, but that lambda has a type that we cannot determine – sometimes it returns another lambda of its same kind, other times it returns a completely different result; in this case some number, 6
Because of this, we cannot easily mix and combine autoCons expressions with other parts of our program. If you drop this perverse drive to create variadic curried interfaces, you can make an autoCons that is type-able
// autoCons : (...a) -> List a r
const autoCons = (...xs) =>
{ const loop = (acc, x = nil, ...xs) =>
    x === nil
      ? acc
      : loop (cons (x, acc), ...xs)
  return loop (nil, ...xs)
}
Because autoCons now returns a known List (instead of the mystery unknown type caused by variadic currying), we can plug an autoCons list into the various other functions provided by our List module. 
const c =
  autoCons (1, 2, 3)
const d =
  autoCons (4, 5, 6)
console.log
  ( toArray (c)                         // [ 1, 2, 3 ]
  , toArray (map (x => x * x) (d))      // [ 16, 25, 36 ]
  , toArray (filter (x => x != 5) (d))  // [ 4, 6 ]
  , toArray (append (c, d))             // [ 1, 2, 3, 4, 5, 6 ]
  )
These kind of mix-and-combine expressions is not possible when autoCons returns a type we cannot rely upon. Another important thing to notice is the List module gives us a place to expand its functionality. We can easily add functions used above like map, filter, append, and toArray – you lose this flexibility when trying to shove everything through the variadic curried interface
Let's look at those additions to the List module now – as you can see, each function is well-typed and has behavior we can rely upon
// type List a r = (r, a) -> r
// nil : List a r
// cons : (a, List a r) -> List a r
// reduce : ((r, a) -> r, r) -> List a r -> r
// length : List a r -> Int
const length =
  reduce
    ( (acc, _) => acc + 1
    , 0
    )
// map : (a -> b) -> List a r -> List b r
const map = f =>
  reduce
    ( (acc, x) => cons (f (x), acc)
    , nil
    )
// filter : (a -> Bool) -> List a r -> List a r
const filter = f =>
  reduce
    ( (acc,x) =>  f (x) ? cons (x, acc) : acc
    , nil
    )
// append : (List a r, List a r) -> List a r
const append = (l1, l2) =>
  (c, n) =>
    l2 (c, l1 (c, n))
// toArray : List a r -> Array a
const toArray =
  reduce
    ( (acc, x) => [ ...acc, x ]
    , []
    )
Even autoCons makes sense as part of our module now
// autoCons : (...a) -> List a r
const autoCons = (...xs) =>
{ const loop = (acc, x = nil, ...xs) =>
    x === nil
      ? acc
      : loop (cons (x, acc), ...xs)
  return loop (nil, ...xs)
}
Add any other functions to the List module
// nth: Int -> List a r -> a
// isNil : List a r -> Bool
// first : List a r -> a
// rest : List a r -> List a r
// ...