· tips · 5 min read
Shorten Your Functions: Advanced Techniques in Code Golfing
Learn practical ES6-based techniques-arrow functions, destructuring, default params, optional chaining, and more-to drastically shorten functions without sacrificing clarity.

What you’ll get out of this
You will learn how to make functions significantly shorter using ES6 features - arrow functions, default parameters, destructuring, rest/spread, optional chaining and more - while keeping them understandable. Read fast. Apply faster. Write code that’s compact and still readable.
Guiding principle: brevity with intention
Code golf prizes the smallest byte count possible. But in real projects, brevity should buy you clarity, not confusion. Aim to reduce ceremony (boilerplate, repeated checks, verbose function wrappers) and keep intent visible. Short names are fine in contests; use meaningful terse names when maintaining readability.
1) Arrow functions and implicit return
Arrow functions are the most direct way to shrink function syntax. You can drop the function keyword, curly braces and return for single expressions.
// verbose
const sq = function (x) {
return x * x;
};
// concise
const sq = x => x * x;
// multiple params, implicit return
const avg = (a, b) => (a + b) / 2;Notes:
- Parentheses around a single param are optional.
- Returning an object literal requires parentheses:
x => ({k:x}).
Reference: Arrow functions - MDN
2) Default parameters to collapse guards
Default parameters let you remove guard code that sets fallbacks.
// verbose
function greet(name) {
name = name || 'guest';
return 'hi ' + name;
}
// concise
const greet = (n = 'guest') => 'hi ' + n;For numeric fallbacks where 0 is valid, prefer nullish coalescing (??) (see below).
Reference: Default parameters - MDN
3) Destructure parameters to avoid boilerplate
Destructuring lets you pull values directly from objects/arrays in the parameter list and provide defaults inline.
// verbose
function cfg(opts) {
const t = opts.timeout || 1000;
return t;
}
// concise
const cfg = ({ timeout = 1000 } = {}) => timeout;
// array destructuring
const head = ([h]) => h;This removes repeated opts. access. Provide a default {} for optional object args.
Reference: Destructuring - MDN
4) Rest/spread for variadics and merging
Rest parameters compress varargs. Use them with concise array methods.
const sum = (...a) => a.reduce((s, x) => s + x, 0);
// spread to pass arrays: Math.max(...arr)Reference: Rest parameters - MDN
5) Optional chaining and nullish coalescing - shrink defensive code
Replacing nested checks with ?. and ?? is a huge size win.
// verbose
const city = user && user.address ? user.address.city : 'n/a';
// concise
const city = user?.address?.city ?? 'n/a';|| treats falsy values as missing. Use ?? when 0 or empty string are valid.
References: Optional chaining - MDN, Nullish coalescing - MDN
6) Short-circuiting and logical tricks
Logical operators return values. Use them to replace if/return combos.
// instead of if(x) return f(x)
const maybe = x => x && f(x);
// conditional expression
const abs = n => (n < 0 ? -n : n);Be cautious: && and || return operands, not strictly booleans.
7) Compose and curry concisely
Small helpers can be composed into tiny pipelines.
const comp = (f, g) => x => f(g(x));
const twice = f => x => f(f(x));Compose multiple one-liners with reduce when necessary.
8) Sequence and comma operator (advanced)
The comma operator evaluates expressions left-to-right and returns the last value. It can collapse multiple statements into one expression - useful only in extreme compression.
// forms a single expression that logs then returns
const f = x => (console.log(x), x + 1);This is powerful but reduces readability. Use sparingly.
Reference: Comma operator - MDN
9) Single-expression functions everywhere
If you can express the logic as a single expression, you unlock the arrow implicit return and removal of braces and return.
Before:
function pickPositive(a) {
if (!a) return 0;
let v = 0;
for (let i of a) if (i > 0) v += i;
return v;
}After:
const pickPositive = a =>
(a || []).filter(x => x > 0).reduce((s, x) => s + x, 0);We replaced loops and guards with array combinators - short and declarative.
10) Returning objects concisely
Wrap object returns in parentheses:
const mk = (k, v) => ({ [k]: v });Use shorthand properties where possible: {k} instead of {k:k}.
11) Naming and clarity trade-offs
- Short variable names reduce byte count but can hurt comprehension. Balance them based on audience.
- Keep a few meaningful names rather than many single-letter identifiers.
- Inline comments are usually not allowed in code golf; in real code, prefer clarity.
12) Examples: before & after
Example 1 - deep sum of numbers in nested array:
// verbose
function flattenSum(arr) {
return arr.flat(Infinity).reduce((s, n) => s + n, 0);
}
// concise
const flattenSum = a => a.flat(Infinity).reduce((s, n) => s + n, 0);Example 2 - safe getter with default:
// verbose
function getCity(u) {
if (!u || !u.profile) return 'n/a';
return u.profile.city;
}
// concise
const getCity = u => u?.profile?.city ?? 'n/a';Example 3 - small pipeline:
// verbose
function topSquares(a) {
return a
.filter(n => n > 0)
.map(n => n * n)
.slice(0, 3);
}
// concise
const topSquares = a =>
a
.filter(n => n > 0)
.map(n => n * n)
.slice(0, 3);13) When to stop: maintainability rules
- If a one-liner requires heavy mental unpacking, expand it.
- Avoid tricks that rely on coercion or surprising return values unless context is constrained (golf or code kata).
- Use linters/minifiers for production; coding short for human readers is different than minified output.
14) Tools and mini-patterns
- Minifyers (Terser) will compress for production; use code golf techniques in contests, not always in codebases.
- Small reusable helpers:
id=x=>x,K=x=>()=>xcan reduce repetition in golfing.
Final thought
Shorter functions are not just smaller - they’re often clearer when you remove ceremony and expose intent directly. Use arrow functions, destructuring, defaults, optional chaining and expression-based thinking to say what you mean in fewer characters. Master those building blocks and you won’t just golf code; you’ll craft concise, expressive functions that still make sense.



