

Show HN: I built an extension of JavaScript in a day - chmod775
https://github.com/binlain/designtojs

======
dmitrig01
1\. Instead of implementing it in vanilla JavaScript, consider creating a
Sweet.js macros (or series of macros), so it can be used with other flavors of
JS as well (e.g. JSX, etc)

2\. On the async functions – what happens if you put an async function inside
a conditional? This is effectively solved by ES6's yield + co or an
equivalent.

3\. A nitpick, but, is there a way to create static functions on classes? E.g.
Car.x instead of Car.prototype.x?

~~~
chmod775
1\. uh... oh

2\. I'm not sure if I understand your correctly, but it should work if you
wrap it in (). I actually have that very same example in 'broken.js' [0]

3\. Sure. As you can write normal JavaScript, just use:

    
    
       Car.x = (arg){
           //etc
       }

The ':' operator is supposed to be a shortcut for X.prototype.Y

[0]:
[https://github.com/binlain/designtojs/blob/master/test/broke...](https://github.com/binlain/designtojs/blob/master/test/broken.djs)

~~~
dmitrig01
Sorry, should have clarified on 2. As an expansion of one of the examples
given:

    
    
        loadAndPrintFile: (contents) {
           if (!contents) {
             fs.readFile() -> (error!, contents)
           }
           console.log(contents);
        }
    

i.e., expected behavior would be as if readFile was not an async function.

I'm asking because I built something similar (though it only worked with
promises, not general async functions), and I'm curious to compare approaches
:-) - mine is a sweet.js macro:
[http://pastie.org/9410315](http://pastie.org/9410315) (uses
[https://github.com/petkaantonov/bluebird](https://github.com/petkaantonov/bluebird)
and [https://github.com/BranchMetrics/promise-
accum](https://github.com/BranchMetrics/promise-accum)). The basic syntax
would be:

    
    
        task {
          item1 <- LoadItem(1);
          item2 <- LoadItem(item1.foreign_key);
          ret <- DoSomethingWithItems(item1, item2);
        }

~~~
chmod775
The JavaScript result of your example looks like this:

(again, beautified because DesignToJS crams everything in one line to preserve
the line numbers of your actual code):

    
    
      function loadAndPrintFile(contents) {
        if (!contents) {
          fs.readFile(function(error, contents){
            if(error !== null && error !== undefined){
              return error;
            }
          });
        }
        console.log(contents);
      }
    

If you omit the function body, it will only expand to the end of the current
logical 'context' (or whatever it's called)

I'd suggest writing it like this in DesignToJS:

    
    
      loadAndPrintFile: (contents! console.log) {
        fs.readFile() -> (error!, contents! console.log)
      }
    

Result looks like this:

    
    
      function loadAndPrintFile(contents) {
          if(contents !== null && contents !== undefined){
              return console.log(contents);
          }
          fs.readFile(function(error, contents){
              if(error !== null && error !== undefined){
                  return error;
              }
              if(contents !== null && contents !== undefined){
                  return console.log(contents);
              }
          });
      }
    
    

_Edit_ : I just submitted a patch that avoids unnecessary binding of 'this' if
'this' is not actually used.

~~~
asynchrony
In Javascript (contents !== null && contents !== undefined) is equivalent to
(contents != null).

~~~
chmod775
Now that is good to know, thank you. I'll make that change asap.

------
m90
You'll have a hard time fighting GitHub classifying `.djs` as DogeScript....

Nevertheless, good luck with the project and everything.

------
arknave
Looks like the readme example doesn't work. I didn't compile the djs sayHello
function to verify it matches the given javascript, but running
sayHello("nyc") spits out

    
    
      Hello to undefined, nyc
      You didn't tell me your age
    

When I'd assume you wanted

    
    
      Hello to nyc, Tim
      You didn't tell me your age

~~~
chmod775
The first argument is the name, the second is city.

If you give a third, the second will be your age and the third your city.

Example:

    
    
       sayHello('Andreas', 'Berlin')
       sayHello('Andreas', 21, 'Berlin')

------
pearknob
Firstly, congratulations on making something useful in one day. Great job. I
skimmed over the documentation/examples and this is excellent.

------
tshadwell
By the way, `typeof X === 'undefined'` doesn't need to be used for variable
names that exist such as arguments, you can use X == undefined without
opportunity for failure.

~~~
woogley
Technically, all edge cases considered, `typeof` is the only fool-proof check,
since you can't override the string constant `'undefined'` but the `undefined`
identifier is fair game.

Here is one such edge case:

    
    
        (function () {
          var undefined = true;
          return (function foo(x) {
            return x === undefined;
          }());
        }()); // false
    

Language pedantry aside, browsers these days will freeze `window.undefined` so
you'd have to shoot yourself in your own scope ;)

~~~
tshadwell
if you're that determined to shoot yourself in the foot you might as well
rebind valueOf

------
phpnode
This looks cool but I think your syntax clashes with JS's standard
LabeledStatement

~~~
chmod775
Good thinking, but I already do detect and handle that case correctly.

There's a test case in 'test/namedThings.(d)js'

