DiScO HeAdEr (met video)

Door Gamebuster op zondag 19 oktober 2014 13:49 - Reacties (15)
Categorie: quite useless, Views: 1.901

Speciaal voor OSX 10.10 Safari mensen:

DISCO HEADER

JS to JS compiler

Door Gamebuster op woensdag 08 oktober 2014 23:01 - Reacties (8)
Categorie: if(post.relatedTo("programming")), Views: 881

Na vele to-JS compilers bekeken, ben ik zelf ook gaan experimenteren met de ontwikkeling van een taal die naar Javascript compileert.

Niet omdat Javascript slecht is, maar omdat het schrijven van "nette" javascript er automatisch voor zorgt dat je codebase groter en slecht comprimeerbaar (minify-baar) wordt. Geen Javascript minifier kan object property names "slim" "obfuscaten". Ik zoek dus een manier om dit wel te realiseren.

Lang verhaal zal ik jullie besparen; een voorbeeld zegt meer dan 1000 woorden:

De "Super" Javascript:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// dom.sjs
export namespace dom {
  function ready(fn) {
    extern window.addEventListener("DOMContentReady", ->{ fn(); });
  }
}

// main.sjs
import "dom";
using namespace dom;

ready(->{
  if(extern window.location.pathname == "/")
    extern console.log("You are at the root page!");
});

if(dom::ready == ready)
  extern console.log("namespaced!");



Resulterende Javascript (geannoteerd)

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// The compiled result of the SJS file. Variable names are not obfuscated for the purpose of this
// demonstration, but they might as well have been. If wrapped in (function() { ... })(), any JS
// minifier will obfuscate and minify the code effectively.

// All extern references. Window is used in multiple extern references, so it is wrapped in a
// variable as well. The extern keyword declares external variables to be imported and used in our
// script.
var _Ewindow = window,
    _Ewindow_Elocation_Epathname = _Ewindow.location.pathname,
    _Econsole_Elog = console.log;

//   import "dom";
//   using namespace dom;
// The import and using statements don't produce any code.
// The function defined in the 'dom' namespace is inlined later since it is only used once.


//   ready(->{
//     if(extern window.location.pathname == "/")
//       extern console.log("You are at the root page!");
//   });
// Here, we use the ready-function with a function argument.
// Since the ready-function is only called once, the function is inlined.

// Extern window.addEventListener is only used once, so it is inlined and not declared at the top.
_Ewindow.addEventListener("DOMContentReady", function() {
  if(_Ewindow_Elocation_Epathname == "/")
    _Econsole_Elog("You are at the root page!");
});

//   if(dom::ready == ready)
//     extern console.log("namespaced!");
// since dom::ready and ready are the same thing (ready implicitly namespaced by the 'use namespace'
// statement) and there is no possible conflict for another ready-function, the comparison always
// equals to 'true'. Therefore, the content of the if-statement can be unwrapped and the
// if-statement removed.
// The extern console.log is stored in a variable at the top of the script, because it is referenced
// as external multiple times.
_Econsole_Elog("namespaced!");



Minified resultaat: (beautified)

JavaScript:
1
2
3
4
5
6
7
8
9
var n=window,
  e=n.location.pathname,
  o=console.log;

n.addEventListener("DOMContentReady", function(){
  "/" == e && o("You are at the root page!")
}),

o("namespaced!")



Besef dat dit theoretisch is. Ik heb geen werkende cross-compiler. Ik ben aan het fantaseren hoe mijn eventuele cross-compiler zijn werk zou doen. Het uiteindelijke doel is modulaire javascript die hevig "comprimeerbaar" is voor een zo compact mogelijk resulterend javascript bestand voor de client, zoals je browser.

In een wereld met megabit verbindingen, is dit nog relevant?
Ik vind van wel. Code-bases groeien hard clientside, waarbij sommige sites meer dan een megabyte aan javascript hebben. Dit vertraagt het laden van de site dramatisch en kost alleen maar onnodig bandbreedte voor zowel jou en mij.

Is een eigen taal ontwikkelen niet een idiote taak?
Ik heb ervaring met het gebruik van parser generators voor "eigen talen". Tevens heb ik een grammar file gevonden die 100% ECMA6 compatible is. Mijn plan is om deze grammer file aan te passen met mijn features en daarmee de "super javascript" te tokenizen en parsen.

Vervolgens moeten er diverse optimalisatie tools en andere scripts op los gelaten worden om de code te transformeren naar "normale" ECMA5-compatible javascript.

Het is veel werk, maar zeker niet onmogelijk.

Javascript is een kut taal. Een taal die naar JS compileert kan JS's gebreken hooguit verstoppen, niet weghalen
Javascript kan een geinige taal zijn. Het heeft zijn sterke punten. Het is ook zeker niet mijn intentie Javascript "features"/gebreken te verbergen. Ik wil dat de taal aanvoelt als javascript, inclusief al zijn gebreken en rare features. Ik wil enkel wat extensies voor het makkelijker maken van bepaalde taken, zoals prototype inheritance en property management (defineProperty enz.): Ik wil geen neppe "Class-oriented taal" ervan maken.

G/b/ tries: Terraria

Door Gamebuster op zaterdag 19 juli 2014 22:36 - Reacties (11)
Categorie: Gaming, Views: 3.003



Ik speel Terraria voor het eerst en lever commentaar over de microfoon. Gewoon, omdat het kan.

Ik vind het altijd leuk om gameplay video's te kijken en mijn interesse ligt er ook al een tijd om zelf video's te gaan maken. Dit is 1 van mijn pogingen. De video is niet bewerkt voor uploaden; Ik vond de video wel voldoende om zonder knippen te uploaden.

edit: Titel aangepast zodat gamenaam zichtbaar is in tweakblogs overzicht.

Groeperen op wat het doet of wat het is?

Door Gamebuster op woensdag 28 mei 2014 18:24 - Reacties (14)
Categorie: if(post.relatedTo("programming")), Views: 3.590

Bij grotere software pakketten groepeer je je code. Of je nou in C, Java, Ruby of Haskell werkt: Groeperen van code doen we allemaal. Voor ieder project waar je wat langer aan verwacht te werken, verschijnen al gauw meerdere bestanden. Voor nog grotere projecten verschijnen de mapjes. Bij frameworks wordt de mappen-structuur zelfs voor je afgedwongen of gegenereerd. Maar wat is eigenlijk de “juiste” manier?

Groeperen op wat het is
Is het een model? Een entity? Een controller? Een view? Bij frameworks als Rails zie je vaak een mappen-structuur waarbij alle modellen onder de “models” map vallen, alle controllers onder de “controllers” map vallen en alle views onder “views”.

Zo heb je alles netjes bij elkaar. Wil je een view wijzigen? Prima, open de views map en leef je uit. Wil je je model wijzigen? Prima, open de models map. Klinkt niet verkeerd toch?

Stel, ik heb een Twitter applicatie gebouwd in een MVC framework als Rails. De modellen User en Tweet zitten in de models map, de controllers hiervoor in de controllers map en de views voor alle acties voor de controllers hiervoor zitten in de views map.

Nu wil je een veld toevoegen aan User. Je wil op iedere profielpagina een link toevoegen naar de website van de gebruiker; deze link kan de gebruiker zelf toevoegen.

Om dit te doen, moet je eerst de User model aanpassen: Je moet een homepage veld toevoegen. Je opent de models-map en voegt het veld toe. Nu moet je toevoegen dat de gebruiker dit veld kan invullen en bewerken. Je hebt al een gebruiker bewerken controller actie en view, dus je hoeft deze 2 alleen nog aan te passen. Je opent de controllers map en past de controller aan met een default value en een assignment van de input params naar het model. Verder open je de views map en pas je de view aan zodat er een veld zichtbaar wordt.

Nou is dit een vrij simpel voorbeeld. Complexer voorbeeld is een test driven applicatie. Al gauw heb je vele mapjes open in je file drawer. Je wijzigingen in de applicatie zijn verspreid over een wijd arsenaal aan mappen.

Groeperen op waarvoor het is
Stel nou dat je alles groepeert op wat het is. Je hebt een users-map met daarin de user-model, de users controller en alle views voor users. In dezelfde map zitten zelfs je tests, want we schrijven natuurlijk wel tests voor de software die we maken, toch?

Voor de bovenstaande aanpassing, hoeven we maar 1 map te openen: users. Daaronder zitten alle bestanden die we moeten wijzigen. De tests, de controller, het model en de views.

Alle wijzigingen zijn gegroepeerd onder 1 map. Je hebt niet hoeven zoeken naar alle bestanden die je nodig hebt. In dit is het direct duidelijk dat je alleen dingen hebt veranderd onder /users.

Wat vind jij?
Tot nu toe heb ik altijd gegroepeerd op wat het is, simpelweg omdat dat “the way to go” is bij frameworks als Rails, maar mijn recente loskoppeling van Rails heeft me aan het denken gezet of dat wel de meest efficiŽnte manier is voor mij.

Ik denk dat het gezond is je primaire mappen-structuur meer te focussen op wat de applicatie inhoudt (tweets, users) en niet wat er allemaal in zit (models, controllers, views)

Dus... Groeperen op wat het is, of waarvoor het is?

KERST

Door Gamebuster op woensdag 28 mei 2014 11:05 - Reacties (12)
Categorie: quite useless, Views: 2.642

Hebben jullie de kerstboom al staan?