Monday, August 10, 2015

Elm Frontend


Today I implemented a front-end for Elm, a language that touts itself as "the best of functional programming in your browser". Integration is simple, you just include Elm code in its own fenced code block inside your markdown file, see this example hello_elm.md. This works the same way as the other JS transpiler frontends, Rusthon calls the other transpiler in a subprocess, and inserting its output into the final html. Checkout the other frontends in Rusthon for: CoffeeScript and Rapydscript.

Elm first impressions

My first try with Elm was a big disappointment. Things look bad starting with the install page, there it lists packages for "OSX", "Windows" and "Anywhere". First off I dont give a fuck if you have packages for OSX and Windows, support the NPM "Anywhere" package and make it work well. Next problem, the NPM package, at the bottom of the page it says, "Also, set the ELM_HOME environment variable to /usr/local/lib/node_modules/elm/share or the corresponding directory created on your machine." What the fuck is your problem Kevin MÃ¥rtensson? Do you really think i am going to play around with my environment variables just try out a transpiler.

Next problem, i run elm-make on my test and it asks me if i want to download some extra bullshit, it then drops this bullshit into the current directory i am running the command in! What the fuck, cache that in ~/.elm or something, do not just start junking up my file system.

first test code fails

import Text
myfunc a =
  Text.plainText a

I was pretty sure that was going to work, i took it pretty much right from chapter1 of the Elm guide here. Searching around i found that Text.plainText is deprecated, and this pisses me off. The problem with Elm and some other transpiled languages (like Dart) is they try to define a standard library of modules and functions, often this grows into some huge mess, which then gets refactored and parts deprecated. A language that transpiles to JavaScript does not need to reinvent all these things, there are plenty of JS libraries out there already. So why did Elm go down the wrong path? Probably because it has such shitty JS interop using ports, and so needs its own fat standard library because it is such a pain for the user to simply call a JavaScript function.

Wednesday, August 5, 2015

JavaScript backend: Debugger


This first reason why people give up when trying to learn JavaScript and HTML, they load up their test page in Google Chrome, and then see this fucking bullshit. It can be a blank white page, or your page half drawn with missing elements...

This second reason why people give up on JavaScript and HTML, they have to press Ctrl+Alt+J to open the god forsaken Google Chrome Developer Tools window. They see some error message in red and then have to click to the far right of it to jump to that point in the code.

Then the user sees the interface above and runs outside to puke. The line that caused the error is highlighted in yellow, for a split second, and then fades out so fast your eye can easily miss it. What the fuck?

Maybe then they give the FireFox debugger and try and see something even more hideous. Then they decide it is time to give up on JavaScript and HTML forever.


A Real JavaScript Debugger

This is the new debugger that is built into the JavaScript backend of Rusthon. When you transpile your project without using the --release command line option, it will insert runtime code to catch any uncaught errors, it parses the trace-back, and generates an HTML interface, with human readable error messages, and editable code that updates without recompile or reload.

note: if you do not include Ace.js in your HTML, then the debugger falls back to using a regular HTML TextArea, which looks like this.

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.