Shik: minimalny język dla terminalowych pipeline'ów i REPL
Zadania terminalowe, takie jak wyszukiwanie ciągów w plikach lub liczenie linii w projekcie, wymagają pipeline'ów z narzędziami o różnych API. Bash oferuje [ -f ] vs [[ -f ]], grep -q vs grep -l, cudzysłowy dla spacji w nazwach. Python rozprasza operacje na plikach między os, shutil, pathlib. Powłoki typu Nushell skupiają się na danych strukturalnych, ale nie rozwiązują problemu zwięzłych skryptów.
Shik to język podobny do Lisp/Haskell, stworzony dla REPL i automatyzacji. Składnia opiera się na aplikacji funkcji przez spacje, pipe $> i kompozycję #>.
Przykłady zadań: od bash do Shik
Wyszukiwanie plików z "- links" i przenoszenie do topics/:
Bash: 5 linii z pułapkami flag grep i cudzysłowów.
Shik:```
file.glob :./* $>
list.filter file.is-file $>
list.filter (fn [f] file.read f $> string.has "- links") $>
list.iterate (file.move :topics)
Cztery kroki pipeline'u, bez importów, bez zewnętrznych komend.
Liczenie linii w plikach `.rs`:
file.glob :./src/*/.rs $>
list.map (file.read #> string.lines #> list.len) $>
list.sum $>
Pipe przekazuje dane od lewej do prawej, kariowanie upraszcza częściowe zastosowanie.
## Podstawy designu: Lisp + Haskell
Wszystko to funkcja. `+ 1 2`, `list.map`, `file.glob` — wywołania według jednej zasady. Spacja — aplikacja, bez nawiasów dla jednego argumentu.
Cztery operatory:
1. Spacja: `f x`
2. `#>`: kompozycja `f #> g` → `fn [x] g (f x)`
3. `$`: aplikacja niskiego priorytetu `print $ + 1 2`
4. `$>`: pipe `x $> f`
Automatyczne kariowanie: `(+ 1)` — funkcja "dodać 1". Kolejność argumentów: pierwszy — stały modyfikator.
let lst [1 2 3 4]
lst $> list.map (+ 1) ; [2 3 4 5]
lst $> list.map (* 2) ; [2 4 6 8]
Jednolitość dla arytmetyki, bez `flip`.
## Składnia: przewodnik w 5 minut
**Literały:**```
42 ; liczba
"hello" ; ciąg znaków
:hello ; symbol (bez spacji)
[1 2 3] ; lista
{:name :Alice} ; obiekt
fn [arg] body ; funkcja
Zmienne:```
let name :Alice
let greet fn [name] "Hello, {name}!"
print $ greet name
set x (+ x 5) ; mutacja
Interpolacja `{wyrażenie}` w ciągach. Kropka — część nazwy: `string.+`, `file.read`.
**Wbudowane moduły:** `file.`, `list.`, `string.`, `shell.` dostępne od razu. `help list.map` — dokumentacja w REPL.
## Ergonometria dla terminala
Nie ma statementów vs expressions — wszystko to wyrażenia. Tylko dane i globalne funkcje, bez klas/metod. Testowanie w podstawowym REPL bez strzałek.
Pipe `$>` rozwiązuje zagnieżdżenie:
**Bez pipe'a:** `print (list.sum (list.map ...))` — chaos.
**Z pipe'em:** dane płyną od lewej do prawej, czytelność liniowa.
Przykłady kariowania z `let`:
let add-one (+ 1)
let files-with-links (fn [dir] file.glob dir $> list.filter (file.read #> string.has "- links"))
## Co jest ważne
- Jeden mechanizm aplikacji funkcji minimalizuje naukę składni.
- Pipe `$>` i kariowanie dla łańcuchów przetwarzania danych bez zagnieżdżenia.
- Wbudowane `file.`, `list.`, `string.` bez importów.
- REPL-first design: `help`, symbole `:`, interpolacja `{}`.
- Kolejność argumentów: pierwszy — modyfikator do częściowego zastosowania.
— Editorial Team
Brak komentarzy.