{"action":"created","issue":{"url":"https://api.github.com/repos/stylus/stylus/issues/2189","repository_url":"https://api.github.com/repos/stylus/stylus","labels_url":"https://api.github.com/repos/stylus/stylus/issues/2189/labels{/name}","comments_url":"https://api.github.com/repos/stylus/stylus/issues/2189/comments","events_url":"https://api.github.com/repos/stylus/stylus/issues/2189/events","html_url":"https://github.com/stylus/stylus/issues/2189","id":157594668,"number":2189,"title":"while loop","user":{"login":"william-silversmith","id":2517065,"avatar_url":"https://avatars.githubusercontent.com/u/2517065?v=3","gravatar_id":"","url":"https://api.github.com/users/william-silversmith","html_url":"https://github.com/william-silversmith","followers_url":"https://api.github.com/users/william-silversmith/followers","following_url":"https://api.github.com/users/william-silversmith/following{/other_user}","gists_url":"https://api.github.com/users/william-silversmith/gists{/gist_id}","starred_url":"https://api.github.com/users/william-silversmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/william-silversmith/subscriptions","organizations_url":"https://api.github.com/users/william-silversmith/orgs","repos_url":"https://api.github.com/users/william-silversmith/repos","events_url":"https://api.github.com/users/william-silversmith/events{/privacy}","received_events_url":"https://api.github.com/users/william-silversmith/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-05-31T05:50:14Z","updated_at":"2016-05-31T14:30:25Z","closed_at":null,"body":"Feature Request\r\n\r\nI was attempting to write some numerical code, and looping until a condition is met is a typical thing to do for that sort of thing. I can accomplish the same thing with recursion, but the number of parameters I have to pass back and forth is icky.\r\n\r\nI guess having a while loop means that stylus won't necessarily ever halt, which might not be so good for people that aren't developers, but you can still do that with recursion (though it halts by blowing up the stack ;) )."},"comment":{"url":"https://api.github.com/repos/stylus/stylus/issues/comments/222706341","html_url":"https://github.com/stylus/stylus/issues/2189#issuecomment-222706341","issue_url":"https://api.github.com/repos/stylus/stylus/issues/2189","id":222706341,"user":{"login":"william-silversmith","id":2517065,"avatar_url":"https://avatars.githubusercontent.com/u/2517065?v=3","gravatar_id":"","url":"https://api.github.com/users/william-silversmith","html_url":"https://github.com/william-silversmith","followers_url":"https://api.github.com/users/william-silversmith/followers","following_url":"https://api.github.com/users/william-silversmith/following{/other_user}","gists_url":"https://api.github.com/users/william-silversmith/gists{/gist_id}","starred_url":"https://api.github.com/users/william-silversmith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/william-silversmith/subscriptions","organizations_url":"https://api.github.com/users/william-silversmith/orgs","repos_url":"https://api.github.com/users/william-silversmith/repos","events_url":"https://api.github.com/users/william-silversmith/events{/privacy}","received_events_url":"https://api.github.com/users/william-silversmith/received_events","type":"User","site_admin":false},"created_at":"2016-05-31T14:30:25Z","updated_at":"2016-05-31T14:30:25Z","body":"I will admit I'm pushing CSS to the limits here, but I'm attempting to make it easier for designers to use e.g. spring animations in CSS using keyframe animations. I've written up the math and a JS version here: https://medium.com/analytic-animations/the-spring-factory-4c3d988e7129#.d3xdphwx0\r\n\r\nI'm not confident that stylus needs a while loop as I'm a bit of an edge case, but I figured I'd show you guys a use case that maybe you hadn't seen. In Listing 1 below, I use an anonymous function, `bisection`, that passes a reference to itself to simulate a while loop. In my JS version, I made my solution more general by finding the upper and lower bounds before performing a binary search because in part because the code complexity was a little easier to handle with the while loop. In this version, I just chose an unrealistically large range to bisect. \r\n\r\nI could go and rewrite that part again, it's only laziness that's holding me back, but a while loop in this case helps prevent laziness from winning. ;)\r\n\r\nIn Listing 2, you can see a prototype (it's not fully designed yet) of how someone might use the output of my spring function. Listing 3 shows sample output. There might be a few bugs still in the code (e.g. representing pixels as 4.613368e-9px), but I think it should be illustrative.\r\n\r\nThank you for your consideration. :)\r\n\r\n```\r\n// LISTING 1: Performing a while loop for numerical computation\r\n// Resolve recursive definition of omega and B using bisection method\r\nnumericallySolveOmegaAndB(zeta, k, y0 = 1, v0 = 0) {\r\n  \r\n  // See https://en.wikipedia.org/wiki/Damping#Under-damping_.280_.E2.89.A4_.CE.B6_.3C_1.29\r\n  // B and omega are recursively defined in solution. Know omega in terms of B, will numerically\r\n  // solve for B.\r\n\r\n  errorfn = @(B, omega) {\r\n    omega_d = omega * sqrt(1 - zeta * zeta)\r\n    return B - ((zeta * omega * y0) + v0) / omega_d\r\n  }\r\n\r\n  A = y0\r\n  B = zeta // initial guess, no good theoretical reason why\r\n  \r\n  omega = computeOmega(A, B, k, zeta)\r\n  error = errorfn(B, omega)\r\n\r\n  lower = -10000\r\n  upper = 10000\r\n  \r\n  bisection = @(self_fn, ct, error, lower, upper, B, omega) {\r\n    if (abs(error) <= 0.000001) {\r\n      return {\r\n        B: B,\r\n        omega: omega,\r\n      }\r\n    }\r\n    \r\n    ct = ct + 1\r\n\r\n    if (ct > 1000) {\r\n      return {\r\n        B: B,\r\n        omega: omega,\r\n      }\r\n    }\r\n    \r\n    B = (upper + lower) / 2\r\n    \r\n    omega = computeOmega(A, B, k, zeta)\r\n    error = errorfn(B, omega)\r\n    direction = -1 * sign(error)\r\n\r\n    if (direction > 0) {\r\n      lower = B\r\n    } \r\n    else {\r\n      upper = B\r\n    }\r\n\r\n    return self_fn(self_fn, ct, error, lower, upper, B, omega)\r\n  }\r\n\r\n  return bisection(bisection, 0, error, lower, upper, B, omega)\r\n}\r\n```\r\n\r\n```\r\n// LISTING 2: Creating a spring animation\r\nvals = springFactoryVals(damping: 0.15, halfcycles: 5, precision: 5, y0: 1, v0: 10)\r\nct = 0\r\n\r\n@keyframes spring\r\n  for val in vals\r\n    pct = ct / (length(vals) - 1) * 100\r\n    ct = ct + 1\r\n    \r\n    {unit(pct, '%')}\r\n      left unit(val * 100, 'px')\r\n```\r\n\r\n```\r\n// LISTING 3: Sample output\r\n// Note: -moz, -o, -webkit output truncated for clarity\r\n@keyframes spring {\r\n  0% {\r\n    left: 100px;\r\n  }\r\n  20% {\r\n    left: -50.18610410443193px;\r\n  }\r\n  40% {\r\n    left: 23.595075650464086px;\r\n  }\r\n  60% {\r\n    left: -9.853507250727997px;\r\n  }\r\n  80% {\r\n    left: 3.083943137298255px;\r\n  }\r\n  100% {\r\n    left: 4.613368e-9px;\r\n  }\r\n}\r\n```"}}
{"actor":{"display_login":"william-silversmith"}}