Thursday, July 30, 2015

Javascript backend: Static Type Syntax


Every fucking time i see this error message in my chrome js console, Uncaught TypeError: Cannot read property `position` of undefined makes me want to walk into Google's head office and beat every mother fucker down. It is time for Lars Bak and Kasper Lund at Google to give up on Dart, and provide a real debugger for Chrome.

Programmers can get into heated debates about syntax and static typing. Sure, it is nice to have a compiler check the types of every variable at compile time, and then throw errors for any typing mistakes you have made, and this works well for native apps written in a statically typed language, but not in the web browser.

Dart and TypeScript compile to JavaScript, and try to offer the same safety that static types provide. However, this is not actually useful because JavaScript is itself not typed, and the type of a variable can change at anytime.

The reality is that in any real web application, you are going to be interfacing with many external JavaScript libraries, and most of your type errors are going to happen at runtime when using those libraries. So you really need a good runtime type checker that will provide useful errors so you can debug your code quickly. JavaScript without runtime type checking, is very hard to debug, because many types of errors are silent, and often this causes later code to break with confusing error messages about something being undefined, forcing you to manually trace the logic back to the original thing that was wrong and caused the whole chain of problems.

Runtime Type Checking Syntax

example source code

def setup_camera_untyped( c ):
 c.position.z = 60
 c.position.x = 5

The function above expects the argument c to be an instance of THREE.PerspectiveCamera. However, if you make a mistake and call the function and pass undefined or some other type, it will fail at runtime with this error message which is almost completely useless.

typed version

def setup_camera( c:THREE.PerspectiveCamera ):
 c.position.z = 60
 c.position.x = 5

Above is the same function with c typed as THREE.PerspectiveCamera, this instructs the transpiler to inject runtime type checking code, that when fails, throws and error message you can actually use to fix the problem, like what is the function and variable name.

For more info see the wiki page, here.

Monday, July 27, 2015

Javascript Backend: NodeJS Tornado Web


NodeJS allows you easily move code back and forth from the client to server, and use the same libraries client-side and server-side. Python3 offers nothing new: still GIL locked, no JIT, and no new syntax worth even mentioning. The only thing Python3 is good for is wasting CPU cycles, and increasing the rate of climate change.

Its nice to have the option to move your server code to NodeJS without having to manually rewrite it. Rusthon now includes a fake Tornado web module, that emulates the basic features of Tornado by wrapping the NodeJS modules: http, url, and ws. The wrapper source code is in nodejs_tornado.py. You load this with from nodejs.tornado import *.

example

example source code
#backend:javascript
from runtime import *
from nodejs import *
from nodejs.tornado import *

PORT = 8000

class MainHandler( tornado.web.RequestHandler ):

 def get(self, path=None):
  print('path', path)
  if path == 'favicon.ico' or path.endswith('.map'):
   self.write('')
  else:
   self.write( open('index.html').read() )


Handlers = [
 ('/', MainHandler),
]

def main():
 print('')
 app = new(tornado.web.Application( Handlers ))
 app.listen( PORT )
 tornado.ioloop.IOLoop.instance().start()

## start main ##
main()

Saturday, July 4, 2015

Javascript Backend: timeout syntax


Performance critical games and web applications often need to maintain consistent and high frame rates. In this situation it is better to drop some of the logic update rather than dropping render frames. This way the rendering frame rate can maintain some target like 60fps, while the logic updates at a variable rate.

Ian Webster has an article about a technique he calls Timed Array Processing, which is able to drop logic and maintain consistent a frame rate regardless of the number of objects in the scene. It works by taking the current time, and when looping over the scene objects, it only updates objects while under the time limit. This automatically spreads the logic computation load over multiple frames. This highly useful feature should actually be abstracted to the language syntax level, so it can be used in a clear and consistent way.

Rusthon has a smallish code base written in Python, maintained entirely by me, so it only takes me a few days to add a feature like Timed Processing. The new syntax to mark a block of code for timed processing is: with timeout(ms):, where ms is the time to finish in milliseconds. The Rusthon JavaScript transpiler will insert time checking code after each function-calling-expression and inside for/while-loops within that indented block. Runtime execution of the code block will then suspend if the time limit is reached. This allows the programmer to write scaleable code, and not scrafice readabity or maintainablity.

Rusthon Input

 q = []
 with timeout( 10 ):
  i = 0
  while True:
   q.append( CalcFib(i) )
   i += 1

JavaScript Output

 q = [];
 var __clk__ = (new Date()).getTime();
 while (true) {  /* timeout: 10 */
  i = 0;
  while (true)
  {
   if ( (new Date()).getTime() - __clk__ >= 10 )  { break; }
   q.append(CalcFib(i));
   i ++;
  }
  break; 
 }

The example above computes the Fibonaci series for up to 10 milliseconds, on my laptop it reaches the 28th place in that time, example source code. Timed processing is useful when used together with the sleep builtin and the select statement, see this example for more.