Back to Home

Shik language for REPL pipelines

Shik — minimalist language for REPL and task automation in the terminal. Syntax based on Lisp/Haskell with pipes and currying simplifies file and data processing. Comparison with bash, Python, Fish.

Shik: why a new language for terminal scripting
Advertisement 728x90

Shik: Minimalist Language for Terminal Pipelines and REPL

Tasks like searching for strings in files or counting lines in a project often require chaining utilities with inconsistent APIs. Bash forces you to juggle [ -f ] vs [[ -f ]], grep -q vs grep -l, and quotes for spaces in filenames. Python scatters file operations across os, shutil, and pathlib. Shells like Nushell focus on structured data but fall short on concise scripting.

Shik is a Lisp/Haskell-inspired language tailored for REPL and automation. Its syntax revolves around function application via spaces, pipelines with $>, and composition with #>.

Examples: From Bash to Shik

Finding files with "- links" and moving them to topics/:

Google AdInline article slot

Bash: 5 lines riddled with grep flag pitfalls and quoting headaches.

Shik:```

file.glob :./* $>

Google AdInline article slot

list.filter file.is-file $>

list.filter (fn [f] file.read f $> string.has "- links") $>

list.iterate (file.move :topics)

Google AdInline article slot
Four pipeline steps, no imports, no external commands.

Counting lines in `.rs` files:

file.glob :./src/*/.rs $>

list.map (file.read #> string.lines #> list.len) $>

list.sum $>

print

Pipelines flow data left to right, currying simplifies partial application.

## Core Design: Lisp Meets Haskell

Everything is a function. `+ 1 2`, `list.map`, `file.glob` — all invoked the same way. Spaces apply functions; no parens needed for single args.

Four key operators:

1. Space: `f x`
2. `#>`: composition `f #> g` → `fn [x] g (f x)`
3. `$`: low-precedence application `print $ + 1 2`
4. `$>`: pipeline `x $> f`

Automatic currying: `(+ 1)` becomes "add 1" function. Argument order: first arg is the fixed modifier.

let lst [1 2 3 4]

lst $> list.map (+ 1) ; [2 3 4 5]

lst $> list.map (* 2) ; [2 4 6 8]

Uniform arithmetic, no need for `flip`.

## Syntax Cheat Sheet: 5 Minutes to Proficiency

**Literals:**```
42                    ; number
"hello"             ; string
:hello               ; symbol (no spaces)
[1 2 3]              ; list
{:name :Alice}       ; object
fn [arg] body        ; function

Variables:```

let name :Alice

let greet fn [name] "Hello, {name}!"

print $ greet name

set x (+ x 5) ; mutation


String interpolation with `{expr}`. Dots are part of names: `string.+`, `file.read`.

**Built-ins:** `file.`, `list.`, `string.`, `shell.` ready to go. `help list.map` shows docs in REPL.

## Terminal Ergonomics

No statements vs expressions — everything's an expression. Just data and global functions, no classes/methods. Test in plain REPL, no arrow keys needed.

Pipeline `$>` eliminates nesting:

**Without pipeline:** `print (list.sum (list.map ...))` — a mess.

**With pipeline:** data flows left to right, linear readability.

Currying examples with `let`:

let add-one (+ 1)

let files-with-links (fn [dir] file.glob dir $> list.filter (file.read #> string.has "- links"))


## Key Features

- Unified function application minimizes syntax learning.
- Pipeline `$>` and currying for nest-free data chains.
- Built-in `file.`, `list.`, `string.` — no imports.
- REPL-first: `help`, symbols `:`, interpolation `{}`.
- Argument order: first is modifier for easy partials.

— Editorial Team

Advertisement 728x90

Read Next