vendredi 24 juillet 2015

Javascript bug? Maximum stack of anonymous functions per line

Bear with me on this.

tl;dr My code only works when I put newlines between function arguments. Is there a maximum on stack size or function declarations per line in javascript?

I've been testing a hypothesis of mine that if you're creative enough, all javascript functions can be re-written (by sacrificing speed and readability) without using:

  • Spaces or newlines
    • (By extension, this prevents the use of many keywords)
  • Declared datatypes (e.g. "",[],0,false,{},etc.)
  • More than one statement per scope
  • Operators of any sort (including logical and relational)

Or, in layman's terms, the whole function should match /^[a-zA-Z(){}.,]*$/.

The biggest challenge I've faced so far in the process of proving this hypothesis (I haven't gotten to regular expressions, that ought to be fun) is dealing with mathematics, which is heavily dependent on operators and numbers.

I've written up functions which follow my parameters and:

  • calculate basic arithmetic (add(a,b) //a+b)
  • form integers (digs(one,three,six,eight) //1368)
  • get and set object properties (setprop(a,b,c) //a[b]=c)

The general idea is to structure functions like below, to make algorithms marginally more readable and writable in this manner:

function(...){(function(add,morefuncs...){algorithm...})(function(){...},morefuncs...)}

My functions work individually, as well as in this form when there are few enough of them, but as I've added more, I've noticed an extremely peculiar bug:

//For some reason, this breaks:
func(arguments,...,f1,f2)

//And this doesn't:
func(arguments,...,
    f1,f2)

Given the large amount of anonymous functions my code requires, I presumed there was a maximum number of anonymous functions javascript can handle in one line, but I can't find any documentation that says this or otherwise.

Here are three versions of my code:

VERSION 1: Without newlines, Doesn't work

(function(){return(function(domath){return(domath)(function(getprop,setprop,add,sub,mlt,div,cct,digs,zero,one,two,three,four,five,six,seven,eight,nine){console.log(getprop,setprop)})})((function(){return(function(m,i,o,c,g,h){return(function(a,d){return(function(s,t){return(function(r,n){return(function(f){return(f).apply(null,Array(g,h,function(x,y){return(r(a(x,y)))},function(x,y){return(r(s(x,y)))},function(x,y){return(r(m(x,y)))},d,c,function(){return(Number(Object.keys(arguments).map(function(k){return(g(arguments,k))}).join(String())))}).concat(n))})})(function(x){return(Number(x.toFixed(t)))},Array(Number(),Math.exp(Number()),Array(Number(),String()).toString().length,Array(Number(),Number()).toString().length,Boolean(Math.exp(Number())).toString().length,Boolean(Number()).toString().length,Array(Boolean(),String()).toString().length,Array(Boolean(),Number()).toString().length,Array(Boolean(),Number(),String()).toString().length,Array(Boolean(),Number(),Number()).toString().length))})(function(x,y){return(Math.log(d(Math.exp(x),Math.exp(y))))},Number(c(String(o),String(Number()))))})(function(x,y){return(Math.log(m(Math.exp(x),Math.exp(y))))},function(x,y){return(m(x,i(y)))})})(function(x,y){return(Math.log(Math.pow(Math.exp(x),y)))},function(x){return(Math.pow(x,Array().indexOf(Number())))},Math.exp(Number()),function(x,y){return(Array(x,y).join(String()))},function(x,y){return(Object.getOwnPropertyDescriptor(x,y).value)},function(x,y,z){Object.defineProperty(x,y,Object.getOwnPropertyDescriptor(Array(z,Number()).slice(Number(),Math.exp(Number())),Number()))})})())})()

Logs function anonymous(urn) function anonymous(urn) on Chrome. (What is "urn"? I don't have any variables by that name, and the only instances of that string are in "return" keywords.)

Logs function anonymous() function anonymous() on Firefox.

VERSION 2: With one newline, works

(function(){return(function(domath){return(domath)(function(getprop,setprop,add,sub,mlt,div,cct,digs,zero,one,two,three,four,five,six,seven,eight,nine){console.log(getprop,setprop)})})((function(){return(function(m,i,o,c,g,h){return(function(a,d){return(function(s,t){return(function(r,n){return(function(f){return(f).apply(null,Array(g,h,function(x,y){return(r(a(x,y)))},function(x,y){return(r(s(x,y)))},function(x,y){return(r(m(x,y)))},d,c,function(){return(Number(Object.keys(arguments).map(function(k){return(g(arguments,k))}).join(String())))}).concat(n))})})(function(x){return(Number(x.toFixed(t)))},Array(Number(),Math.exp(Number()),Array(Number(),String()).toString().length,Array(Number(),Number()).toString().length,Boolean(Math.exp(Number())).toString().length,Boolean(Number()).toString().length,Array(Boolean(),String()).toString().length,Array(Boolean(),Number()).toString().length,Array(Boolean(),Number(),String()).toString().length,Array(Boolean(),Number(),Number()).toString().length))})(function(x,y){return(Math.log(d(Math.exp(x),Math.exp(y))))},Number(c(String(o),String(Number()))))})(function(x,y){return(Math.log(m(Math.exp(x),Math.exp(y))))},function(x,y){return(m(x,i(y)))})})(function(x,y){return(Math.log(Math.pow(Math.exp(x),y)))},function(x){return(Math.pow(x,Array().indexOf(Number())))},Math.exp(Number()),function(x,y){return(Array(x,y).join(String()))},
function(x,y){return(Object.getOwnPropertyDescriptor(x,y).value)},function(x,y,z){Object.defineProperty(x,y,Object.getOwnPropertyDescriptor(Array(z,Number()).slice(Number(),Math.exp(Number())),Number()))})})())})()

Logs function anonymous(x, y) function anonymous(x, y, z).

VERSION 3: Beautified for your viewing pleasure

(function() {
  return (function(domath) {
      return (domath)(function(getprop, setprop, add, sub, mlt, div, cct, digs, zero, one, two, three, four, five, six, seven, eight, nine) {
          console.log(getprop, setprop)
      })
  })((function() {
      return (function(m, i, o, c, g, h) { //multiplication, inverse, one, concatenation, getObjectProperty, setObjectProperty
          return (function(a, d) { //add, divide
              return (function(s, t) { //subtract, ten
                  return (function(r, n) { //roundToTenDigits (fix for negatives), numbers (so you can call numbers as variables)
                      return (function(f) { //makes it so you don't have to re-initialize the functions every time you do math
                          return (f).apply(null, Array(g, h, function(x, y) {
                              return (r(a(x, y))) //modifies addition (rounds results like -2.999999999996)
                          }, function(x, y) {
                              return (r(s(x, y))) //modifies subtraction
                          }, function(x, y) {
                              return (r(m(x, y))) //modifies multiplication
                          }, d, c, function() { //makes a number out of its digits
                              return (Number(Object.keys(arguments).map(function(k) {
                                  return (g(arguments, k))
                              }).join(String())))
                          }).concat(n)) //adds all the numbers to the arguments array
                      })
                  })(function(x) {
                      return (Number(x.toFixed(t)))
                  }, Array(Number(), Math.exp(Number()), Array(Number(), String()).toString().length, Array(Number(), Number()).toString().length, Boolean(Math.exp(Number())).toString().length, Boolean(Number()).toString().length, Array(Boolean(), String()).toString().length, Array(Boolean(), Number()).toString().length, Array(Boolean(), Number(), String()).toString().length, Array(Boolean(), Number(), Number()).toString().length))
              })(function(x, y) {
                  return (Math.log(d(Math.exp(x), Math.exp(y))))
              }, Number(c(String(o), String(Number()))))
          })(function(x, y) {
              return (Math.log(m(Math.exp(x), Math.exp(y))))
          }, function(x, y) {
              return (m(x, i(y)))
          })
      })(function(x, y) {
          return (Math.log(Math.pow(Math.exp(x), y)))
      }, function(x) {
          return (Math.pow(x, Array().indexOf(Number())))
      }, Math.exp(Number()), function(x, y) {
          return (Array(x, y).join(String()))
      }, function(x, y) {
          return (Object.getOwnPropertyDescriptor(x, y).value)
      }, function(x, y, z) {
          Object.defineProperty(x, y, Object.getOwnPropertyDescriptor(Array(z, Number()).slice(Number(), Math.exp(Number())), Number()))
      })
  })())
})()

I don't think I can call this a bug in javascript, given the nature of what I'm trying to accomplish, but it would be good to have documentation on the maximum number of anonymous functions per line if one exists (for minimizing large libraries, for instance).

Has anyone seen anything like this before? Any advice?

Thanks so much.

P.S. Please avoid "your hypothesis is dumb" answers. That'd be nice.

Aucun commentaire:

Enregistrer un commentaire