Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AnastasiaDunbar/b87aa100af309c3eba23a27f7ae0d617 to your computer and use it in GitHub Desktop.
Save AnastasiaDunbar/b87aa100af309c3eba23a27f7ae0d617 to your computer and use it in GitHub Desktop.

Ideas for new JavaScript language features.

These are some of my syntactic sugar ideas for JavaScript.

The #define macro 😐

#define add(a,b) a+b
console.log(add(4,7)); //Will output 11.
#define array [2,3]
console.log(array.pop()+array[1]); //Will output 6.

Useful for code golfing.

But its biggest purpose is for debugging like in this example:

#define DEBUG
for(var i=0;i<iterations;i++){
	#ifdef DEBUG
	debugFunction(param1,param2,param3);
	#else
	normalFunction(param1,param2,param3);
	#endif
}

Instead of:

const DEBUG=true;
for(var i=0;i<iterations;i++){
	if(DEBUG){
		debugFunction(param1,param2,param3);
	}else{
		normalFunction(param1,param2,param3);
	}
}

So you could keep parts of your code without ruining your performance with if-statements, comments do exist of course but I get tired of uncommenting and commenting especially if they're spread separately in different areas.

Loops πŸ™‚

Looping without using any variables.

loop{ //You could do `for(;;){`.
	//Infinite loop.
}

loop(7){
	//Loop 7 times.
}

Multiple keys with associated value πŸ˜ƒ

Instead of:

var object={
	a:"Hello",
	get b(){return this.a;},
	set b(value){this.a=value;}
};

Do this:

var object={
	["a","b"]:"Hello"
};
object.a="Test";
console.log(object.a); //Will output "Test".
console.log(object.b); //Will output "Test".

This can sometimes be useful for dictionaries (e.g. the array can consist of synonyms and the value can be a definition). This can also be useful for GLSL-like vectors (e.g. ({[..."xrs0"]:0,[..."ygt1"]:0,[..."zbp2"]:0,[..."waq3"]:0})).

Access array with an array πŸ™‚

Instead of:

var array=[0,1];
console.log(array.reduce((t,e)=>t[e],[[6,3],6])); //Will output 3.

Do this:

var array=[0,1];
console.log([[6,3],6]array); //Same as `[[6,3],6][0][1]` and will output 3.

The self variable πŸ˜ƒ

Where self's value is the variable itself:

var incrediblyLongVariableName="llo";
incrediblyLongVariableName="He"+self+", world!";
console.log(incrediblyLongVariableName); //Will output "Hello, world!".

var object={a:3,b:7,c:self.a+self.b};
//`object.c=object.a+object.b;` would've been here without `self`.
console.log(object.c); //Will output 10.

Can be used for negating booleans (e.g. boolean=!self;) and recursive anonymous functions such as:

console.log((x=>x>1?Math.log(x)**self(x-1):x)(6));

It can also be used for polyfills:

globalObject.prototype.method=self|function method(...arguments){
	//...
};

Afterthought: What about this? itself which is the value of the current local object (scope) it's being inside of? From this:

var temp0={
	y:5,
	get x(){return this.y;},
	set x(v){this.y=v;}
};
temp0.z=[0,undefined];
temp0.z[1]=temp0.z;
var temp1=n=>n<2?n:temp1(n-1)+temp1(n-2);
var result=(o=>temp1(o.x))(temp0);

To this:

var result=(o=>(n=>n<2?n:itself(n-1)+itself(n-2))(o.x))({x:itself.y,y:5,z:[0,itself]});

Another afterthought: Why can't we use temporary "variables", like this:

x:longVariableName=(6/x)+x;

Which becomes:

longVariableName=(6/longVariableName)+longVariableName;

Similar to this feature:

#define x longVariableName
x=(6/x)+x;

Instead of:

(
	var x=longVariableName;
	longVariableName=(6/x)+x;
)(); //Wrapped in an anonymous function so that `x` isn't defined.

Instructions within conditional statements πŸ˜ƒ

Instead of:

var a="foo";
if(a=="foo"){
	console.log('Got "foo".');
}else if((()=>{a+="bar";return a=="bazbar";})()){
	console.log('Got "baz".');
}
while((()=>{a+="bar";return a.length<20;})()){
	console.log(a);
}

Do this:

var a="foo";
if(a=="foo"){
	console.log('Got "foo".');
}else if(a+="bar";a=="bazbar"){
	console.log('Got "baz".');
}
while(a+="bar";a.length<20){
	console.log(a);
}

Actually, with commas you can achieve the same effect:

var a="foo";
if(a=="foo"){
	console.log('Got "foo".');
}else if(a+="bar",a=="bazbar"){
	console.log('Got "baz".');
}
while(a+="bar",a.length<20){
	console.log(a);
}

Sleep function πŸ™‚

Instead of:

(async()=>{
	console.log("Sleeping for two seconds.");
	await new Promise(resolve=>setTimeout(resolve,2000));
	console.log("Done.");
})();

Do this:

console.log("Sleeping for two seconds.");
sleep(2000);
console.log("Done.");

goto statement and labels 😐

Instead of:

var string="";
function A(){string+="Hello ";B();};
function B(){string+="there! ";C();};
function C(){string+="How are you?";};
A();
console.log(string); //Will output "Hello there! How are you?".

Do this:

var string="";
goto A;
B:string+="there! ";goto C;
A:string+="Hello ";goto B;
C:string+="How are you?";
console.log(string); //Will output "Hello there! How are you?".

Linked variables 😐

var x=4;
link y,x;
y++;
console.log(x); //Will output 5.

Which in C would be like:

int x=4;
int*y=&x;
(*y)++;
printf("%d",x);

Can be used for variables with long names but I'd recommend this instead in some cases.

Operator overloading πŸ˜ƒ

class vec2{
	constructor(x,y){
		this.x=x;
		this.y=y;
	}
	__plus(left){
		return{x:left.x+this.x,y:left.y+this.y};
	}
	__minus(left){
		return{x:left.x-this.x,y:left.y-this.y};
	}
}
console.log(new vec2(6,4)+new vec2(3,9)); //Will output {x:9,y:13}.

or

overload # (left:Number,right:Number){
	return left+right;
}
console.log(5#8); //Will output 13.

Replace multiple strings πŸ™‚

Instead of:

console.log("foo bar baz".replace(/a/g,"e").replace(/o/g,"u")); //Output will be "fuu ber bez".

Do this:

console.log("foo bar baz".replace([/a/g,/o/g],["e","u"])); //Output will be "fuu ber bez".

Or even this, so you can easily comprehend the correlations:

console.log("foo bar baz".replace([[/a/g,"e"],[/o/g,"u"]])); //Output will be "fuu ber bez".

Perl's Regular Expression features πŸ˜ƒ

Such as named capturing groups, if-then-else conditionals (e.g. (?(?=condition)then|else)), lookbehinds (e.g. (?=condition)match) and etc..

Nested multiline comments 😐

I've seen Wren doing this, useful for debugging or describing a metalanguage. Example:

/*
breaksStuff(x);
/*
	Some text here.
	Another line.
*/
ignored();
*/
doThis();

Better timers πŸ˜ƒ

A getTimeouts() function to return all timeoutIDs and more information about their elapsed time, functions and additional parameters, don't forget about getIntervals() for intervalIDs. Also allow the delay to be greater than 2147483647 milliseconds.

Labels and loops in switch statements πŸ˜•

Where this:

var x=2;
switch(x){
	case 2:
	case 5:
	console.log("First.");
	break 5;
	console.log("Second.");
}

Becomes this:

var x=2;
switch(x){
	case 2:
	case 5:
	console.log("First.");
	if(x===5){break;}
	console.log("Second.");
}

And this:

var x=0;
switch(x){
	case 6:
	console.log("Done!");
	break;
	default:
	console.log(x);
	x++;
	continue;
}

Becomes this:

var x=0;
while(true){
	if(x===6){
		console.log("Done!");
		break;
	}else{
		console.log(x);
		x++;
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment