Skip to content

Commit 0065f70

Browse files
committed
Cursed JavaScript
1 parent 4387594 commit 0065f70

File tree

4 files changed

+347
-0
lines changed

4 files changed

+347
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
description: A JavaScript snippet to make a function that can only be called once, without using any mutable variables.
3+
---
4+
5+
# Functions that can only be called once — for immutable lovers
6+
7+
```js
8+
function createOnceFunction(f) {
9+
return new (class extends class {} {
10+
constructor() {
11+
return (...args) => {
12+
super();
13+
return f(...args);
14+
};
15+
}
16+
})();
17+
}
18+
```
19+
20+
Usage:
21+
22+
```js
23+
const f = createOnceFunction(() => console.log("Hello"));
24+
f(); // Hello
25+
f();
26+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
description: How to execute code in a top-down fashion (entry module first) in a module graph instead of bottom-up (leaf modules first).
3+
---
4+
5+
# Executing code in a module graph top-down
6+
7+
[Source](https://x.com/NicoloRibaudo/status/1579863078761803777)
8+
9+
```js
10+
import "data:text/javascript,console.log('Hi!')";
11+
```
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
description: A JavaScript snippet to use index access for number ranges.
3+
---
4+
5+
# Number range syntax
6+
7+
```js
8+
class RangeIterator extends Iterator {
9+
#cur;
10+
#end;
11+
#dir;
12+
static {
13+
Object.defineProperties(RangeIterator.prototype, {
14+
[Symbol.toStringTag]: {
15+
value: "Range Iterator",
16+
writable: false,
17+
enumerable: false,
18+
configurable: true,
19+
},
20+
});
21+
}
22+
constructor(start, end) {
23+
super();
24+
this.#cur = typeof start === "bigint" ? start : Number(start);
25+
this.#end = typeof end === "bigint" ? end : Number(end);
26+
this.#dir =
27+
typeof start === "bigint"
28+
? start > end
29+
? -1n
30+
: 1n
31+
: start > end
32+
? -1
33+
: 1;
34+
}
35+
next() {
36+
if (
37+
(this.#dir > 0 && this.#cur >= this.#end) ||
38+
(this.#dir < 0 && this.#cur <= this.#end)
39+
) {
40+
return { done: true, value: undefined };
41+
}
42+
const value = this.#cur;
43+
this.#cur += this.#dir;
44+
return { done: false, value };
45+
}
46+
}
47+
48+
Object.setPrototypeOf(
49+
Number.prototype,
50+
new Proxy(Object.prototype, {
51+
get(t, p, r) {
52+
if (typeof p === "string") {
53+
const np = Number(p);
54+
if (!Number.isNaN(np)) {
55+
const n = Number(r);
56+
if (Number.isFinite(n)) {
57+
return new RangeIterator(n, np);
58+
}
59+
}
60+
}
61+
return Reflect.get(t, p, r);
62+
},
63+
}),
64+
);
65+
Object.setPrototypeOf(
66+
BigInt.prototype,
67+
new Proxy(Object.prototype, {
68+
get(t, p, r) {
69+
if (typeof p === "string") {
70+
try {
71+
const np = BigInt(p);
72+
const n = BigInt(r);
73+
return new RangeIterator(n, np);
74+
} catch {}
75+
}
76+
return Reflect.get(t, p, r);
77+
},
78+
}),
79+
);
80+
```
81+
82+
Usage:
83+
84+
```js
85+
console.log([...(10)[-3]]);
86+
console.log([...1n[5n]]);
87+
```
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
---
2+
description: A JavaScript snippet to implement overloaded functions using type predicates.
3+
---
4+
5+
# Overloaded functions
6+
7+
```ts
8+
declare class OverloadedFunction extends Function {
9+
constructor(overloads: Iterable<OverloadSignature>);
10+
[Symbol.iterator](): IterableIterator<Function>;
11+
[Symbol.toStringTag]: "OverloadedFunction";
12+
overloads(): IterableIterator<Function>;
13+
toString(): string;
14+
}
15+
16+
type Func = (...args: never) => unknown;
17+
type Type =
18+
| "string"
19+
| "number"
20+
| "bigint"
21+
| "boolean"
22+
| "symbol"
23+
| "undefined"
24+
| "object"
25+
| "function";
26+
27+
type OverloadSignature =
28+
| Func
29+
| [func: Func, numArgs: number]
30+
| [func: Func, minArgs: number, maxArgs: number]
31+
| [func: Func, argTypes: Type[]]
32+
| [func: Func, tester: (args: unknown[]) => boolean];
33+
34+
type OverloadType =
35+
| { type: "numArgs"; func: Func; numArgs: number }
36+
| { type: "minMaxArgs"; func: Func; minArgs: number; maxArgs: number }
37+
| { type: "argTypes"; func: Func; argTypes: Type[] }
38+
| { type: "tester"; func: Func; tester: (args: unknown[]) => boolean };
39+
40+
const overloadRegistry = new WeakMap<OverloadedFunction, OverloadType[]>();
41+
42+
function OverloadedFunction(overloads: Iterable<OverloadSignature>) {
43+
const f = function () {
44+
const overloads = overloadRegistry.get(f)!;
45+
const overload = overloads.find((overload) => {
46+
switch (overload.type) {
47+
case "tester":
48+
return overload.tester([...arguments]);
49+
case "numArgs":
50+
return overload.numArgs === arguments.length;
51+
case "minMaxArgs":
52+
return (
53+
overload.minArgs <= arguments.length &&
54+
overload.maxArgs >= arguments.length
55+
);
56+
case "argTypes":
57+
return (
58+
overload.argTypes.length === arguments.length &&
59+
overload.argTypes.every((type, i) => typeof arguments[i] === type)
60+
);
61+
}
62+
});
63+
if (!overload)
64+
throw new TypeError(
65+
`No overload found for arguments ${Array.from(
66+
arguments,
67+
)} among overloads ${JSON.stringify(overloads)}`,
68+
);
69+
if (new.target === undefined)
70+
return Reflect.apply(overload.func, this, arguments);
71+
return Reflect.construct(overload.func, arguments, new.target);
72+
} as unknown as OverloadedFunction;
73+
Object.setPrototypeOf(f, OverloadedFunction.prototype);
74+
const o: OverloadType[] = [];
75+
for (const overload of overloads) {
76+
if (typeof overload === "function") {
77+
o.push({ type: "numArgs", func: overload, numArgs: overload.length });
78+
} else {
79+
const func = overload[0];
80+
if (typeof func !== "function") {
81+
throw new TypeError("Overload must be a function");
82+
}
83+
if ("2" in overload) {
84+
o.push({
85+
type: "minMaxArgs",
86+
func,
87+
minArgs: +overload[1],
88+
maxArgs: +overload[2]!,
89+
});
90+
} else {
91+
const argTypes = overload[1];
92+
if (typeof argTypes === "function") {
93+
o.push({ type: "tester", func, tester: argTypes });
94+
} else if (Array.isArray(argTypes)) {
95+
o.push({ type: "argTypes", func, argTypes });
96+
} else {
97+
o.push({ type: "numArgs", func, numArgs: +argTypes });
98+
}
99+
}
100+
}
101+
}
102+
overloadRegistry.set(f, o);
103+
return f;
104+
}
105+
106+
function* createOverloadIterator(f: OverloadedFunction) {
107+
if (!overloadRegistry.has(f)) {
108+
throw new TypeError(
109+
"Method OverloadedFunction.prototype.overloads called on incompatible receiver",
110+
);
111+
}
112+
const o = overloadRegistry.get(f)!;
113+
for (let i = 0; i < o.length; i++) {
114+
yield o[i].func;
115+
}
116+
}
117+
118+
function overloads() {
119+
const iterator = createOverloadIterator(this);
120+
return iterator;
121+
}
122+
123+
Object.setPrototypeOf(
124+
Object.getPrototypeOf(createOverloadIterator.prototype),
125+
Object.getPrototypeOf(Object.getPrototypeOf([].keys())),
126+
);
127+
Object.defineProperties(createOverloadIterator.prototype, {
128+
[Symbol.toStringTag]: {
129+
value: "Overload Iterator",
130+
writable: false,
131+
enumerable: false,
132+
configurable: true,
133+
},
134+
});
135+
Object.defineProperties(createOverloadIterator, {
136+
name: { value: "OverloadIterator" },
137+
});
138+
139+
Object.setPrototypeOf(OverloadedFunction, Function);
140+
Object.setPrototypeOf(OverloadedFunction.prototype, Function.prototype);
141+
Object.defineProperties(OverloadedFunction.prototype, {
142+
[Symbol.toStringTag]: {
143+
value: "OverloadedFunction",
144+
writable: false,
145+
enumerable: false,
146+
configurable: true,
147+
},
148+
[Symbol.iterator]: {
149+
value: overloads,
150+
writable: true,
151+
enumerable: false,
152+
configurable: true,
153+
},
154+
toString: {
155+
value: function () {
156+
return overloadRegistry
157+
.get(this)!
158+
.map((o) => o.func.toString())
159+
.join("\n");
160+
},
161+
writable: true,
162+
enumerable: false,
163+
configurable: true,
164+
},
165+
overloads: {
166+
value: overloads,
167+
writable: true,
168+
enumerable: false,
169+
configurable: true,
170+
},
171+
});
172+
```
173+
174+
Usage:
175+
176+
```js
177+
const f = new OverloadedFunction([
178+
(a) => a + 100,
179+
(a, b) => a * b,
180+
(a, b, c) => a + b + c,
181+
]);
182+
183+
console.log([...f].map((f) => f.toString()));
184+
console.log(f.toString());
185+
console.log(f(1));
186+
console.log(f(2, 3));
187+
console.log(f(4, 5, 6));
188+
console.log(f.bind(null, 2)());
189+
console.log(f.bind(null, 2)(6, 7));
190+
191+
const c = new OverloadedFunction([
192+
function (a) {
193+
return { a };
194+
},
195+
function (a, b) {
196+
return { a, b };
197+
},
198+
function (a, b, c) {
199+
return { a, b, c };
200+
},
201+
]);
202+
203+
console.log(new c(1));
204+
console.log(new c(1, 2, 3));
205+
206+
const g = new OverloadedFunction([
207+
[(a) => a + 100, ["number"]],
208+
[(a) => "Hello" + a, ["string"]],
209+
[(a) => !a, ["boolean"]],
210+
]);
211+
212+
console.log(g(1));
213+
console.log(g(" world"));
214+
console.log(g(true));
215+
216+
const h = new OverloadedFunction([
217+
[(a) => a + 100, (args) => typeof args[0] !== "bigint"],
218+
[(a) => a + 100n, (args) => typeof args[0] === "bigint"],
219+
]);
220+
221+
console.log(h(1));
222+
console.log(h(1n));
223+
```

0 commit comments

Comments
 (0)