13

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.

EDIT: Just an update on the conversation so far:

To clarify, I DO NOT want it to output function anonymous() function anonymous(). I want it to output function anonymous(x, y) function anonymous(x, y, z).

  • Chrome v43 doesn't work on Windows 8.1, Windows 7 or Mac OS X 10.

  • Firefox 39 doesn't work.

  • Chrome Canary v45 works perfectly. Another user says v44 also works.

  • I'm hoping to have cross-browser compatibility if possible.

  • I am the author of this code.

  • If you think my code is written in a weird way, you clearly have not read this whole question.

NobodyNada
  • 7,529
  • 6
  • 44
  • 51
Scelesto
  • 775
  • 6
  • 13
  • It might have something to do with an implicit `;` on newlines. http://stackoverflow.com/q/6252067/47589 –  Jul 24 '15 at 19:30
  • I don't think so, because the newline is between arguments. Calling `function(a,;b)` definitely does not work. – Scelesto Jul 24 '15 at 19:30
  • 2
    Version 1 works just fine for me. Chrome 44.0.2403.89 (64-bit), OS X 10.10. – Siguza Jul 24 '15 at 19:31
  • 1
    Muhammad please read the whole thing. Siguza, are you using a console, jsfiddle, raw HTML, what? – Scelesto Jul 24 '15 at 19:32
  • So am I, but I'm in Chrome 43. Let me try 44 and see what happens. (I'd prefer for this to work cross-browser, but that'd be good for testing) – Scelesto Jul 24 '15 at 19:33
  • Yes, Canary (45) works perfectly. Could this be an issue with V8? – Scelesto Jul 24 '15 at 19:35
  • Muhammad, that's exactly the version It failed in for me. It's possible that this is a problem with my computer. Let me try a reboot and see where that gets me. – Scelesto Jul 24 '15 at 19:37
  • Lightness Races in Orbit not particularly helpful, thanks – Scelesto Jul 24 '15 at 19:40
  • when i write version 1 in `console.debug()` then it works. But it's worse when i write it in `console.log()`. I'm narrowing down it. i'm using chrome Version 43.0.2357.132 m – Muhammad Imran Jul 24 '15 at 19:45
  • When I run `console.debug()`, I get `function anonymous(eturn) function anonymous(eturn)`. The reboot didn't do anything. I'm in the same version of Chrome as you. What operating system are you on? I'm Windows 8.1. – Scelesto Jul 24 '15 at 19:51
  • Interesting. Maybe it's the operating system's way of running the C in the javascript engine. – Scelesto Jul 24 '15 at 19:57
  • For what its worth, I got the same result using Chrome 43.0.2357.134 m on Windows 7. I get the same result in Chrome 43.0.2357.134 on Mac OS X 10. –  Jul 24 '15 at 19:57
  • Amy, to clarify, you got my result or Muhammad's? – Scelesto Jul 24 '15 at 19:58
  • Sorry, yours, Scelesto. –  Jul 24 '15 at 20:01
  • Thanks. Does anyone know anything about how V8 or another javascript engine is compiled? That might provide information about what is causing Muhammad's system to work differently. – Scelesto Jul 24 '15 at 20:03
  • @Scelesto i need to share a long string which i can't paste here. can you come one chat – Muhammad Imran Jul 24 '15 at 20:04
  • Sure, but I don't know how. – Scelesto Jul 24 '15 at 20:06
  • or i'm pasting in the answer section, i will update the answer later that why it's happening... – Muhammad Imran Jul 24 '15 at 20:06
  • Still doesn't work, although it doesn't do the weird "urn" or "eturn" things now. This also wouldn't be a solution anyway because my parameters say not to use spaces or newlines. – Scelesto Jul 24 '15 at 20:09
  • no no, i want you to notice something – Muhammad Imran Jul 24 '15 at 20:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/84219/discussion-between-muhammad-imran-and-scelesto). – Muhammad Imran Jul 24 '15 at 20:10
  • @Scelesto can u plz come on chat by clicking the link – Muhammad Imran Jul 24 '15 at 20:12
  • I didn't experience any viewing pleasure even in your beautified version. Shakes head. How do people work like this. – bhspencer Jul 24 '15 at 20:21
  • It's not supposed to be beautiful. It's supposed to prove my hypothesis. You try writing code that follows those parameters and looks good. `alert()` is probably about as far is you're going to get. – Scelesto Jul 24 '15 at 20:23
  • This has nothing to do with anonymous functions. You would get the same result if those were named. – Sebastian Nette Jul 24 '15 at 20:26
  • Sebastian please explain. – Scelesto Jul 24 '15 at 20:26
  • By the way @Amy it seems that Muhammad's system might not be working differently from mine. I think there was a miscommunication. – Scelesto Jul 24 '15 at 20:31
  • 2
    It's just a displaying issue on the console. `function anonymous(urn)` the `urn` is part of a `return`statement from your code. Chrome just messes displaying the correct arguments up for whatever reason. That doesn't mean that the code doesn't work the same. Just name all anonymous functions and look up their code in the VM and you will see that the functions and their arguments are perfectly fine. – Sebastian Nette Jul 24 '15 at 20:36
  • Sebastian, it DOESN'T work the same. It (the real function) runs properly in Canary, and not in regular Chrome. It runs properly with the newline, and not without it. I've tested this to no end. The reason why I posted it with the console.log is because that's much more interactive for users trying to figure out what I'm doing. – Scelesto Jul 24 '15 at 20:38
  • Actually, I'm sorry Sebastian, I think they're separate problems. When I externalize the functions (even when logging doesn't work) everything runs perfectly. Internally they're still having trouble, but I think you're right that the logging is mostly just a problem with the log function. – Scelesto Jul 24 '15 at 20:53
  • All 3 versions work exactly the same for me regardless of what the console shows and if the functions are named or not. What kind of error do you receive when using the getprop and setprop methods? – Sebastian Nette Jul 24 '15 at 20:53
  • It doesn't throw an error in that function (the errors occur later when referencing occurs); the function thinks its parameters are undefined. (Although this also seems to depend on the browser). – Scelesto Jul 24 '15 at 20:57
  • I'm going to try and rewrite the function to make the functionality work (forget about logging for the moment, nobody seems to have a good answer.) – Scelesto Jul 24 '15 at 20:57
  • Rewriting seems to be working. Thanks @SebastianNette. – Scelesto Jul 24 '15 at 21:03
  • On a sidenote: `console.log(arguments);` or `console.log([getprop, setprop]);` would have probably shown the correct arguments for your functions. Or even `console.log(getprop.toString(),setprop.toString())` – Sebastian Nette Jul 24 '15 at 21:16
  • Actually, I tried all three of those, and none worked... :/ Not sure why. – Scelesto Jul 24 '15 at 21:18
  • I'm voting to close this question as off-topic because it was a bug which has already been reported and resolved –  Jun 14 '17 at 08:27
  • Has that been confirmed with Firefox? – Scelesto Jun 29 '17 at 21:53
  • I just checked myself with Firefox and this seems to have been "fixed," as in all three lines of code produce the same result, but none of the three of them produce the original intended result. However, because this was clearly an intentional choice of the developers, it's no reason to keep this open. Opera and Safari are working nominally. I'll check Edge, and then close. – Scelesto Jun 29 '17 at 22:03
  • Edge is working nominally. I'll edit the question in case anyone stumbles upon it, and then close. – Scelesto Jun 29 '17 at 22:10
  • Oh, I guess I don't have the power to do that. I suppose it could still remain open for continuing Firefox development. – Scelesto Jun 29 '17 at 22:14
  • Please don't put a solution in your question; post it as an answer instead. [Will Kunkel](https://stackoverflow.com/users/453273/will-kunkel) has already provided [a CW answer](https://stackoverflow.com/a/38065476/3476191); you may [edit](https://stackoverflow.com/posts/38065476/edit) that answer as needed. Thanks! – NobodyNada Jun 29 '17 at 22:15

1 Answers1

0

Modern versions of Chrome, Opera, Safari, and Edge are working nominally.

Firefox still logs functions with no arguments, but since it now does so uniformly between all three versions of the code, it seems the bug has been addressed. I take it that this display choice is a conscious choice on the part of the developers.

It would still be nice to see further documentation on this issue from Mozilla, or even nicer if Firefox would join Chrome, Opera, Safari, and Edge by displaying function arguments correctly.

Scelesto
  • 775
  • 6
  • 13
Rose Kunkel
  • 3,102
  • 2
  • 27
  • 53