Discovering Elvish
Last year the youtube algorithm suggested I watch this video, a brief explanation of the vision behind a new shell. The video itself was a few years old, so I was pleased to discover a busy Github repo and active community. I installed elvish and went about my business, pridefully thinking that my familiarity with bash would act as a stalwart defense against any noob mistakes. A couple of noob mistakes made in quick succession convinced me I had better read the docs anyway.
This wasn't as bad as expected. The Elvish docs were expertly organized and easy to read. For maybe the first time ever I felt inspired to write a decent amount of code in a shell scripting language.
Elvish offers first-class support for a number of features that are interesting to find in a shell scripting language, but they are seamlessly integrated and never feel out of place.
- lexical scopes
- types/kinds
- sensible math operators
- proper function signature with var-args
- plus optional named params with default values
- higher-level functions
- persistent, immutable lists & maps
- parallel execution
- namespaces
- package manager!!!
- so much more...
One feature I have not yet taken advantage of in my own projects are the styling builtins. I am eager to see how they simplify some extant parts of my project.
Goofing around
The first thing I did was to implement some of the core library functions from Clojure. 2
fn partial [f @supplied]{
put [@args]{
@args = (base:check-pipe $args)
$f $@supplied $@args
}
}
fn juxt [@fns]{
put [@args]{
@args = (base:check-pipe $args)
for f $fns {
$f $@args
}
}
}
fn reduce [f acc @arr]{
for a $arr {
acc = ($f $acc $a)
}
put $acc
}
This gives you currying, juxtaposition, and (ofc) folding.
# all of this available in the 'fun' and 'base' namespaces
# except in the float64 type signature, '()' is output capture in elvish eg '$()' or '``'
# $<fn>~ is a function handle/reference
~> (fun:juxt $base:dec~ $base:inc~) 10
(float64 9)
(float64 11)
~> (fun:partial $+~ 2) 10
(float64 12)
~> fun:reduce $+~ (range 10)
(float64 45)
In the next entry I may write about my approach to lazy iterators(!!) in Elvish, or how seamless the Elvish package manager has made the development process.
Top comments (0)