gofront 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  ## About
2
2
 
3
- I love Go for the backend — simple, type-safe, no nonsense. I like JavaScript for the
4
- frontend — runs everywhere, no setup. What I don't like is JavaScript's loose typing. And
5
- I don't like TypeScript either. I know, controversial. It's fine, I just don't enjoy it.
3
+ Go for the backend: simple, type-safe, no nonsense. JavaScript for the frontend: runs
4
+ everywhere, no setup. The problem is JavaScript's loose typing — and TypeScript never
5
+ quite felt like home either.
6
6
 
7
- So I built GoFront. Go syntax, type safety, compiles to plain ES modules. Same language
7
+ So I built GoFront. Go syntax and type safety, compiling to plain ES modules. One language
8
8
  front and back, no runtime, no framework, no tsconfig.json.
9
9
 
10
- Is this useful? Probably not, but it was fun to build:D
10
+ Probably not useful. Definitely fun to build.
11
11
 
12
12
  ```go
13
13
  package main
@@ -100,8 +100,9 @@ operation on it is silently permitted, preventing cascading errors.
100
100
  Walks the typed AST and emits clean, readable JavaScript. No intermediate representation
101
101
  — the codegen writes directly to an output buffer with indentation tracking.
102
102
 
103
- Runtime helpers (`__len`, `__append`, `__s`, `__sprintf`) are tree-shaken: only emitted
104
- when actually used. Optional inline source maps are supported via VLQ-encoded mappings.
103
+ Runtime helpers (`__len`, `__append`, `__s`, `__sprintf`, `__cmul`, `__cdiv`, `__error`,
104
+ `__errorIs`) are tree-shaken: only emitted when actually used. Optional inline source
105
+ maps are supported via VLQ-encoded mappings.
105
106
 
106
107
  ---
107
108
 
@@ -120,7 +121,7 @@ readable and debuggable — no name mangling, no opaque wrappers.
120
121
  | `[]T` (slice) | `Array` | `append` → spread, `len` → `.length` |
121
122
  | `map[K]V` | Plain object `{}` | Key access via `[]`, iteration via `Object.entries()` |
122
123
  | `nil` | `null` | |
123
- | `error` | `string` | `error("msg")` → `"msg"`, `.Error()` → the string itself |
124
+ | `error` | `__error` object | `error("msg")` → `__error("msg")`, `.Error()` → real method call. `toString()` for string context compat |
124
125
  | Pointers (`*T`) | `{ value: T }` | `new(T)` allocates a boxed zero value |
125
126
 
126
127
  ### Functions
@@ -164,24 +165,20 @@ readable and debuggable — no name mangling, no opaque wrappers.
164
165
  | `make(map[K]V)` | `{}` |
165
166
  | `delete(m, k)` | `delete m[k]` |
166
167
  | `new(T)` | `{ value: zeroOf(T) }` |
167
- | `min(a, b, ...)` | `Math.min(a, b, ...)` |
168
- | `max(a, b, ...)` | `Math.max(a, b, ...)` |
168
+ | `min` / `max` | `Math.min` / `Math.max` |
169
169
  | `clear(x)` | `.length = 0` (slice) or delete-loop (map) |
170
170
  | `print` / `println` | `console.log` |
171
+ | `complex(r, i)` | `{ re: r, im: i }` |
172
+ | `real(z)` / `imag(z)` | `z.re` / `z.im` |
171
173
  | `fmt.Sprintf` | `__sprintf` tree-shaken helper |
172
- | `strings.*` | JS string methods (`.includes`, `.startsWith`, `.split`, etc.) |
173
- | `strconv.*` | `String()`, `parseInt()`, `Number()` |
174
- | `sort.Slice` | `Array.prototype.sort()` with comparator wrapping |
175
- | `math.*` | `Math.*` methods and constants |
176
- | `errors.New` | Identity (returns string) |
177
- | `time.Now()` | `Date.now()` |
178
174
 
179
175
  ### Type system at runtime
180
176
 
181
177
  All type checking happens at compile time. At runtime, types are erased — there are no
182
178
  type tags, no reflection, no runtime overhead. Sized integers (`int8`–`int64`,
183
- `uint8`–`uint64`) are all `number` at runtime. `float32` is `number`. The type checker
184
- enforces correctness; JavaScript doesn't need to know.
179
+ `uint8`–`uint64`) are all `number` at runtime. `float32` is `number`. Generic type
180
+ parameters are erased completely — `func Map[T, U any](...)` compiles to `function Map(...)`.
181
+ The type checker enforces correctness; JavaScript doesn't need to know.
185
182
 
186
183
  ---
187
184
 
@@ -205,7 +202,7 @@ example/simple/
205
202
  styles.go ← injectStyles() creates <style> element with all CSS
206
203
  main.go ← createApp() builds DOM shell · setupEvents() · event delegation
207
204
  utils/
208
- utils.go ← Plural() — cross-package import demo
205
+ utils.go ← Plural() · generic Filter/Map — cross-package import demo
209
206
  browser.d.ts ← minimal external type declarations (sleep)
210
207
  index.html ← bare HTML shell, loads app.js as ES module
211
208
  app.js ← generated output
@@ -228,7 +225,7 @@ example/reactive/
228
225
  styles.go ← injectStyles()
229
226
  main.go ← wires everything together
230
227
  utils/
231
- utils.go ← Plural()
228
+ utils.go ← Plural() · generic Filter/Map
232
229
  browser.d.ts ← Signal interface · Signals/Reactive/ComponentContext namespaces
233
230
  reactive.js ← signals framework (from microtastic)
234
231
  index.html ← loads reactive.js + app.js
@@ -239,7 +236,8 @@ example/reactive/
239
236
 
240
237
  Both apps cover: structs & methods, iota constants, named return values, closures,
241
238
  slices, `for range`, `switch`, cross-package imports, multi-file same-package compilation,
242
- `async`/`await`, `defer`/`recover`, localStorage persistence, and DOM APIs.
239
+ `async`/`await`, `defer`/`recover`, localStorage persistence, DOM APIs, and generic
240
+ utility functions (`Filter[T]`, `Map[T, U]`).
243
241
 
244
242
  The reactive example additionally demonstrates: external `.d.ts` type imports,
245
243
  `declare namespace` patterns for typing JS libraries, and reactive UI updates via signals.
@@ -260,15 +258,18 @@ npm run build:reactive # → example/reactive/app.js
260
258
  gofront <file.go> compile single file → stdout
261
259
  gofront <dir> compile all *.go in directory → stdout
262
260
  gofront <input> -o out.js write output to file (prints elapsed compile time e.g. "15ms")
263
- gofront <input> --check type-check only
264
- gofront <input> --watch watch for changes and recompile
265
- gofront <input> --source-map append inline source map to output
266
- gofront <input> --minify minify output with terser
267
- gofront <file.go> --ast dump AST (debug)
268
- gofront <file.go> --tokens dump tokens (debug)
269
- gofront init [dir] scaffold a new project
270
- gofront --version / -v print version
271
- gofront --help / -h print this help
261
+ gofront <input> --check type-check only
262
+ gofront <input> --watch watch for changes and recompile
263
+ gofront <input> -o out.js --serve watch + serve with live reload (default port 3000)
264
+ gofront <input> -o out.js --serve --port 8080 use a custom port
265
+ gofront <input> --source-map append inline source map (single file or directory; multi-file packages emit per-file mappings)
266
+ gofront <input> --minify minify output (built-in minifier)
267
+ gofront <input> --minify --mangle minify and rename local identifiers
268
+ gofront <file.go> --ast dump AST (debug)
269
+ gofront <file.go> --tokens dump tokens (debug)
270
+ gofront init [dir] scaffold a new project
271
+ gofront --version / -v print version
272
+ gofront --help / -h print this help
272
273
  ```
273
274
 
274
275
  ---
@@ -337,85 +338,100 @@ signatures into GoFront's internal type representation.
337
338
 
338
339
  ## Language features
339
340
 
341
+ ### Core language
342
+
340
343
  | Feature | Status |
341
344
  |---|---|
342
345
  | Variables (`var`, `:=` short re-declaration) | ✓ |
343
- | Constants (`const`, `iota`) | ✓ |
344
- | `if` / `else if` / `else` | ✓ |
345
- | `if` with init statement (`if err := f(); err != nil`) | ✓ |
346
- | Type definitions (`type MyType ...`) | ✓ |
347
- | Functions, multiple returns | ✓ |
348
- | Named return values | ✓ |
349
- | Variadic parameters | ✓ |
346
+ | Constants (`const`, `iota`, untyped constants) | ✓ |
347
+ | Functions, multiple returns, named returns, variadic | ✓ |
350
348
  | `init()` functions | ✓ |
351
- | Structs + methods | ✓ |
352
- | Anonymous struct types (`struct { Name string }`) | ✓ — compile to plain JS objects (no class emitted) |
353
- | Embedded structs | ✓ |
354
- | Pointer receivers | ✓ |
355
- | Interfaces | ✓ |
356
- | Interface embedding | ✓ |
357
- | Closures | ✓ |
349
+ | Closures / function literals | ✓ |
350
+ | `async func` / `await` expressions | ✓ |
351
+ | `defer`, `panic()` / `recover()` | ✓ |
352
+ | `print` / `println` builtins | ✓ — compile to `console.log` |
353
+
354
+ ### Types & data structures
355
+
356
+ | Feature | Status |
357
+ |---|---|
358
+ | Structs + methods (value & pointer receivers) | ✓ |
359
+ | Embedded structs (flattened fields + promoted methods) | ✓ |
360
+ | Anonymous struct types | ✓ — compile to plain JS objects |
361
+ | Interfaces (with embedding) | ✓ |
358
362
  | Slices (`append`, `len`, `make`) | ✓ |
359
- | Maps (`make`, `delete`, comma-ok) | ✓ — note: iteration order is insertion-order (JS), not randomised (Go) |
360
- | `for`, `for range`, `for {}` | ✓ |
361
- | `range` over string | ✓ |
362
- | `switch` / `fallthrough` | ✓ |
363
- | `switch` with init statement (`switch x := f(); x {}`) | ✓ |
364
- | `new(T)` | ✓ |
365
- | Type conversions | ✓ |
366
- | Type assertions (`x.(T)`) | ✓ |
367
- | Type switch (`switch x.(type)`, `switch v := x.(type)`) | ✓ — compiles to `if/else if` with `typeof` / `instanceof` checks |
368
- | Slice expressions (`s[lo:hi]`, `s[lo:hi:max]`) | ✓ — three-index form is parsed; `max` is ignored at runtime (JS has no capacity) |
369
- | `break` / `continue` / labeled `break` / labeled `continue` | ✓ |
370
- | `cap()`, `copy()`, `panic()` | ✓ |
363
+ | Maps (`make`, `delete`, comma-ok) | ✓ |
364
+ | Arrays with compile-time enforcement | ✓ — reject `append`, bounds checking, size matching, `[...]T` inference, compile-time `len()` |
365
+ | Slice → array conversion (`[N]T(slice)`) | ✓ — Go 1.20 |
366
+ | Pointers (`&x`, `*p`, `new(T)`) | ✓ — scalar locals boxed as `{ value: T }` for shared mutation |
367
+ | `error` type | ✓ — interface `{ Error() string }`; custom error types, `errors.Is`/`Unwrap`, `%w` wrapping |
368
+ | Complex numbers (`complex64`, `complex128`, `3i`) | ✓ — `complex()`, `real()`, `imag()` builtins; `__cmul`/`__cdiv` helpers |
369
+ | Type definitions, type aliases (`type A = B`) | ✓ |
370
+ | Type conversions, type assertions (plain & comma-ok) | ✓ |
371
+ | Type switch (`switch v := x.(type)`) | ✓ — compiles to `if/else if` with `typeof` / `instanceof` |
372
+ | Sized integers (`int8`–`int64`, `uint8`–`uint64`, `float32`) | ✓ — mapped to `number` at runtime |
373
+ | Generics (`func F[T any]`, `type S[T any] struct`) | ✓ — type erasure to JS; generic functions, structs, constraints (`any`, `comparable`, interfaces, unions), type inference |
374
+ | Struct field tags | ✓ — parsed and ignored (no reflection) |
375
+ | Struct and array equality (`a == b`) | ✓ — deep comparison via `__equal` helper |
376
+
377
+ ### Control flow
378
+
379
+ | Feature | Status |
380
+ |---|---|
381
+ | `if` / `else if` / `else` (with init statement) | ✓ |
382
+ | `for` (C-style, condition-only, infinite, `range`) | ✓ |
383
+ | `range` over slice, map, string, integer | ✓ |
384
+ | Range over iterator functions (Go 1.23) | ✓ — `func(yield func(K, V) bool)` protocol; break/continue/return propagation |
385
+ | `switch` / `fallthrough` (with init statement) | ✓ |
386
+ | `break` / `continue` / labeled variants | ✓ |
387
+ | Terminating statement analysis | ✓ — missing `return` in non-void functions is a type error |
388
+
389
+ ### Expressions & literals
390
+
391
+ | Feature | Status |
392
+ |---|---|
393
+ | Arithmetic, comparison, logical, bitwise operators | ✓ — includes `&^` (bit clear) |
394
+ | Compound assignment, increment / decrement | ✓ |
395
+ | Slice expressions (`s[lo:hi]`, `s[lo:hi:max]`) | ✓ |
371
396
  | Variadic spread (`f(slice...)`, `append(a, b...)`) | ✓ |
372
- | Bitwise operators (`&`, `\|`, `^`, `&^`, `<<`, `>>`) | ✓ — `&^` (bit clear) compiles to `& ~` |
373
- | Compound assignment (`+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `\|=`, `^=`, `<<=`, `>>=`) | ✓ |
374
- | Increment / decrement (`i++`, `i--`) | ✓ |
375
- | Raw string literals (backticks) | ✓ |
376
- | Rune / char literals (`'a'`, `'\n'`) | ✓ — compiled to integer char codes |
377
- | `defer` | ✓ |
378
- | `panic()` / `recover()` | ✓ |
379
- | `print` / `println` builtins | ✓ — compile to `console.log` |
380
- | Pointer operators (`&`, `*`) | ✓ |
381
- | `error` type / `error("msg")` / `.Error()` | ✓ |
382
- | `async func` / `await` expressions | ✓ |
383
- | `fmt.Sprintf` / `fmt.Printf` / `fmt.Println` / `fmt.Print` / `fmt.Errorf` | ✓ — expanded: `%t`, `%x`, `%X`, `%o`, `%b`, `%q`, `%e`, `%g`, width/precision |
384
- | `strings` package | ✓ — 20 functions: `Contains`, `HasPrefix`, `Split`, `Join`, `ToUpper`, `ToLower`, `TrimSpace`, etc. |
385
- | `strconv` package | ✓ — `Itoa`, `Atoi`, `FormatBool`, `FormatInt`, `ParseFloat`, `ParseInt`, `ParseBool` |
386
- | `sort` package | ✓ — `Ints`, `Float64s`, `Strings`, `Slice`, `SliceStable`, `SliceIsSorted` |
387
- | `math` package | ✓ — `Sqrt`, `Pow`, `Abs`, `Floor`, `Ceil`, `Round`, `Log`, trig functions + `Pi`, `E`, `MaxInt` constants |
388
- | `errors` package | ✓ — `errors.New` (returns plain string) |
389
- | `time` package (partial) | ✓ — `Now`, `Since`, `Sleep` + `Millisecond`, `Second`, `Minute`, `Hour` constants |
390
- | `unicode` package | ✓ — `IsLetter`, `IsDigit`, `IsSpace`, `IsUpper`, `IsLower`, `IsPunct`, `IsControl`, `IsPrint`, `IsGraphic`, `ToUpper`, `ToLower` |
391
- | `os` package (partial) | ✓ — `Exit`, `Args`, `Getenv` |
392
- | External `.d.ts` types | ✓ |
393
- | npm package types | ✓ |
397
+ | Positional struct literals (`Point{1, 2}`) | ✓ |
398
+ | Method expressions (`T.Method`) / method values (`x.Method`) | ✓ |
399
+ | Multi-value function forwarding (`f(g())`) | ✓ |
400
+ | Raw string literals (backticks), rune literals | ✓ |
401
+ | Numeric separators (`1_000_000`), binary/octal/hex literals | ✓ |
402
+ | `[]byte(s)` / `[]rune(s)` conversions | ✓ |
403
+
404
+ ### Standard library shims
405
+
406
+ | Package | Functions |
407
+ |---|---|
408
+ | `fmt` | `Sprintf`, `Printf`, `Println`, `Print`, `Errorf`, `Fprintf`, `Fprintln`, `Fprint` — format verbs: `%v`, `%d`, `%s`, `%t`, `%x`, `%o`, `%b`, `%q`, `%e`, `%g`, `%w`, width/precision |
409
+ | `strings` | `Contains`, `HasPrefix`, `HasSuffix`, `Index`, `LastIndex`, `Count`, `Repeat`, `Replace`, `ReplaceAll`, `ToUpper`, `ToLower`, `TrimSpace`, `Trim`, `TrimPrefix`, `TrimSuffix`, `TrimLeft`, `TrimRight`, `Split`, `Join`, `EqualFold`; **`Builder`** type (`WriteString`, `WriteByte`, `WriteRune`, `Write`, `String`, `Len`, `Reset`, `Grow`) |
410
+ | `bytes` | `Contains`, `HasPrefix`, `HasSuffix`, `Index`, `Join`, `Split`, `Replace`, `ToUpper`, `ToLower`, `TrimSpace`, `Equal`, `Count`, `Repeat`; **`Buffer`** type (`WriteString`, `WriteByte`, `Write`, `String`, `Bytes`, `Len`, `Reset`) |
411
+ | `strconv` | `Itoa`, `Atoi`, `FormatBool`, `FormatInt`, `FormatFloat`, `ParseFloat`, `ParseInt`, `ParseBool` |
412
+ | `sort` | `Ints`, `Float64s`, `Strings`, `Slice`, `SliceStable`, `SliceIsSorted` |
413
+ | `math` | `Abs`, `Floor`, `Ceil`, `Round`, `Sqrt`, `Cbrt`, `Pow`, `Log`, `Log2`, `Log10`, trig functions + `Pi`, `E`, `MaxFloat64`, `MaxInt`, `MinInt` |
414
+ | `errors` | `New`, `Is`, `Unwrap` — custom error types via interface satisfaction |
415
+ | `time` | `Now`, `Since`, `Sleep` + `Millisecond`, `Second`, `Minute`, `Hour` constants |
416
+ | `html` | `EscapeString`, `UnescapeString` |
417
+ | `maps` | `Keys`, `Values`, `Clone`, `Copy`, `Equal`, `EqualFunc`, `Delete`, `DeleteFunc` |
418
+ | `slices` | `Contains`, `Index`, `Equal`, `Compare`, `Sort`, `SortFunc`, `SortStableFunc`, `IsSorted`, `IsSortedFunc`, `Reverse`, `Max`, `Min`, `MaxFunc`, `MinFunc`, `Clone`, `Compact`, `CompactFunc`, `Concat`, `Delete`, `DeleteFunc`, `Insert`, `Replace`, `Grow`, `Clip` |
419
+ | `regexp` | `MustCompile`, `Compile`, `MatchString`, `QuoteMeta`; **`*Regexp`** methods: `MatchString`, `FindString`, `FindStringIndex`, `FindAllString`, `FindStringSubmatch`, `FindAllStringSubmatch`, `ReplaceAllString`, `ReplaceAllLiteralString`, `Split`, `String`. Inline flags (`(?i)`, `(?m)`, `(?s)`) are extracted automatically into the JS `RegExp` constructor. |
420
+ | `unicode` | `IsLetter`, `IsDigit`, `IsSpace`, `IsUpper`, `IsLower`, `IsPunct`, `IsControl`, `IsPrint`, `IsGraphic`, `ToUpper`, `ToLower` |
421
+ | `os` | `Exit`, `Args`, `Getenv` |
422
+
423
+ ### Packages & imports
424
+
425
+ | Feature | Status |
426
+ |---|---|
394
427
  | Multi-file packages | ✓ |
395
428
  | Cross-package imports | ✓ |
396
429
  | Import aliases (`import m "./pkg"`) | ✓ |
397
- | Sized integer types (`uint`, `int8`–`int64`, `uint8`–`uint64`, `float32`) | ✓ — mapped to `int` / `float64` at runtime |
398
- | Struct field tags (`` `json:"name"` ``) | ✓ — parsed and ignored (no reflection) |
399
- | `[]byte(s)` conversion | ✓ — produces UTF-8 byte values via `TextEncoder` |
400
- | `[]rune(s)` conversion | ✓ — produces Unicode code points via `Array.from` |
401
- | `[...]T{...}` array length inference | ✓ |
402
- | Side-effect imports (`import _ "pkg"`) | ✓ — dependency code is bundled; package namespace is not exposed |
403
- | Dot imports (`import . "pkg"`) | ✓ — merges package exports into the current scope (no qualifier needed) |
404
- | Unused local import detection | ✓ — unused cross-package imports are type errors (matching Go); `import _` exempt |
405
- | `min()` / `max()` builtins | ✓ — compiles to `Math.min` / `Math.max` |
406
- | `clear()` builtin | ✓ — zeroes slice length or deletes all map keys |
407
- | `range` over integer (`for i := range n`) | ✓ — Go 1.22; also supports `for range n` |
408
- | Type aliases (`type A = B`) | ✓ — transparent alias; no conversion needed between alias and original |
409
- | Numeric literal separators (`1_000_000`) | ✓ — underscores stripped at lex time |
410
- | Binary / octal literals (`0b1010`, `0o777`) | ✓ — passed through to JS which supports them natively |
411
- | Hex float literals (`0x1.8p1`) | ✓ — evaluated at lex time to a decimal value |
412
- | Untyped constants | ✓ — `const x = 5` produces an untyped int that coerces to `int` or `float64` on use (Go spec §Constants) |
413
- | Positional (unkeyed) struct literals (`Point{1, 2}`) | ✓ |
414
- | Method expressions (`T.Method`) | ✓ — compiles to `(recv, ...args) => recv.Method(...args)` |
415
- | Method values (`x.Method`) | ✓ — compiles to `x.Method.bind(x)` |
416
- | Struct and array equality (`a == b`) | ✓ — deep comparison via tree-shaken `__equal` helper |
417
- | Multi-value function forwarding (`f(g())`) | ✓ — single multi-return call forwarded as spread |
418
- | Terminating statement analysis | ✓ — missing `return` in non-void functions is a type error |
430
+ | Side-effect imports (`import _ "pkg"`) | ✓ |
431
+ | Dot imports (`import . "pkg"`) | ✓ |
432
+ | Unused import detection | ✓ |
433
+ | External `.d.ts` types | ✓ |
434
+ | npm package type resolution | ✓ |
419
435
 
420
436
  ---
421
437
 
@@ -423,37 +439,7 @@ signatures into GoFront's internal type representation.
423
439
 
424
440
  GoFront implements a practical subset of the
425
441
  [Go Language Specification](https://go.dev/ref/spec) (go1.26). It is not aiming for
426
- byte-level parity — it is a Go-inspired language for the JavaScript platform. This
427
- section explains exactly where GoFront matches Go, where it intentionally diverges, and
428
- where JS fundamentally prevents matching Go semantics.
429
-
430
- ### What matches Go
431
-
432
- The core language surface is well covered. All of these compile and behave as a Go
433
- developer would expect:
434
-
435
- - **Declarations**: `var`, `:=` (with re-declaration), `const` (with `iota`), `type`,
436
- `func`, methods, `init()`.
437
- - **Control flow**: `if`/`else` (with init statement), `for` (classic, condition-only,
438
- infinite, `range`), `switch`/`case`/`default`/`fallthrough`, type switches, labeled
439
- `break`/`continue`, `defer`, `panic`/`recover`.
440
- - **Types**: `int`, `float64`, `string`, `bool`, sized integers (`int8`–`int64`,
441
- `uint8`–`uint64`), `float32`, `byte`, `rune`, `error`, slices, maps, arrays, structs,
442
- interfaces (with embedding), pointers (`*T`, `&x`), type aliases, function types.
443
- - **Expressions**: all arithmetic, comparison, logical, and bitwise operators (including
444
- `&^`), compound assignment, increment/decrement, type conversions, type assertions
445
- (plain and comma-ok), slice expressions (`a[lo:hi]`, `a[lo:hi:max]`), composite
446
- literals (keyed and positional), `[...]T{...}` inference, rune literals, raw string
447
- literals, variadic spread, blank identifier `_`, method expressions (`T.Method`),
448
- method values (`x.Method`), struct/array equality, multi-value function forwarding.
449
- - **Builtins**: `len`, `cap`, `append`, `copy`, `make`, `delete`, `new`, `clear`, `min`,
450
- `max`, `print`, `println`, `panic`, `recover`, `fmt.Sprintf`/`Printf`/`Println`/`Errorf`.
451
- - **Standard library shims**: `strings` (20 functions), `strconv` (8 functions),
452
- `sort` (6 functions), `math` (20 functions + 6 constants), `errors.New`,
453
- `time.Now`/`Since`/`Sleep` + duration constants, `unicode` (11 functions),
454
- `os.Exit`/`Args`/`Getenv`.
455
- - **Packages**: multi-file packages, cross-package imports, import aliases,
456
- dot imports, blank imports, unused import detection.
442
+ byte-level parity — it is a Go-inspired language for the JavaScript platform.
457
443
 
458
444
  ### GoFront extensions (not in Go)
459
445
 
@@ -470,9 +456,6 @@ These features are intentional additions for the JavaScript platform:
470
456
 
471
457
  | Feature | Reason | Prospect |
472
458
  |---|---|---|
473
- | Generics (`[T any]`) | Touches every compiler stage. Large effort, limited runtime payoff on a JS target. | Feasible — highest-priority future feature. |
474
- | Range over iterator functions (Go 1.23) | `func(yield func(K, V) bool)` protocol. | Feasible. |
475
- | Complex numbers (`complex64`, `complex128`, `3i`) | Would need a runtime complex type. Rarely used in frontend. | Feasible but low priority. |
476
459
  | `goto` | No clean JS translation. Rare in idiomatic Go. | Not planned. |
477
460
  | Goroutines / channels / `select` | Go's concurrency model has no JS equivalent. A userland scheduler defeats the "no runtime" goal. | Out of scope. |
478
461
  | `unsafe`, `reflect`, `cgo` | Require memory model or runtime type metadata that JS cannot provide. | Out of scope. |
@@ -489,15 +472,15 @@ you know exactly what to expect.
489
472
  | Integer overflow | IEEE 754 float64 semantics | Wraps at type boundary (e.g. `int32`) | All JS numbers are float64. |
490
473
  | Integer precision | Safe up to 2⁵³ | Full width per type (`int64` = 64 bits) | JS `number` limitation. |
491
474
  | `cap()` | Always equals `len()` | May exceed `len()` | JS arrays have no separate capacity. |
492
- | Fixed-size arrays (`[n]T`) | Plain JS arrays (no length enforcement) | Fixed at compile time | Runtime enforcement adds overhead for no JS benefit. |
475
+ | Fixed-size arrays (`[n]T`) | Compile-time enforcement (bounds, append rejected, size matching); plain JS arrays at runtime | Fixed at compile time, value-type copy semantics | Runtime enforcement adds overhead; compile-time checks catch most errors. |
493
476
  | `nil` | Maps to `null` | Typed nil (distinct per type) | JS has no typed nil concept. |
494
477
  | `rune` / `byte` | Treated as `int` | Distinct types with UTF-8 encoding | JS strings are UTF-16. |
495
478
  | `range` over string | Rune integers via `.codePointAt()` | Runes (UTF-8 code points) | Close match — indices are byte-sequential, values are code points. |
496
479
  | `len()` on strings | JS `.length` (UTF-16 code units) | Byte count (UTF-8) | Matching Go would require `TextEncoder` on every call. |
497
- | `error` type | Plain string | Interface `{ Error() string }` | Practical simplification for JS. |
480
+ | `error` type | Interface `{ Error() string }` with `__error` runtime objects | Interface `{ Error() string }` | Close match. Custom error types, `errors.Is`/`Unwrap`, `%w` wrapping all work. `toString()` added for JS string context compat. |
498
481
  | `defer` | `try`/`finally` with a defer stack | Runtime stack unwinding | Covers most cases but not identical to Go internals. |
499
482
  | Struct field tags | Parsed, silently discarded | Available via `reflect` | No reflection = no use for tag values. |
500
- | Pointers (`&x`, `*p`) | Syntax accepted, semantically transparent | True memory indirection | JS has no pointer model. |
483
+ | Pointers (`&x`, `*p`) | Address-taken scalars boxed as `{ value: T }`; structs/slices/maps are reference types (no boxing) | True memory indirection | Shared mutation works for scalars; struct fields and slice elements not yet addressable. |
501
484
  | Three-index slice (`a[lo:hi:max]`) | `max` is parsed but ignored | Sets result capacity | JS arrays have no capacity. |
502
485
  | Exported / unexported | Enforced for GoFront packages; external `.d.ts`/npm namespaces are exempt | Access enforced uniformly | External JS APIs use lowercase names by convention. |
503
486
 
@@ -517,7 +500,8 @@ Design documents for planned features are organised by release under `docs/v*/`
517
500
  npm test
518
501
  ```
519
502
 
520
- 655 tests covering language features, type errors, edge cases, DOM (jsdom), external
503
+ 940 tests covering language features, type errors, edge cases, DOM (jsdom), external
521
504
  `.d.ts`, npm resolver, multi-file compilation, embedded structs, string formatting, map
522
505
  iteration order, integer overflow semantics, unused variable detection, unused import
523
- detection, semantic difference verification, stdlib shim packages, and both example apps.
506
+ detection, semantic difference verification, stdlib shim packages, generics (type params,
507
+ inference, constraints), and both example apps.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gofront",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "author": "Luuk van Venrooij",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,7 +39,6 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@biomejs/biome": "^2.4.11",
42
- "jsdom": "^29.0.2",
43
- "terser": "^5.46.1"
42
+ "jsdom": "^29.0.2"
44
43
  }
45
44
  }