Essential LiveScript for ramda-cli

by raine

LiveScript is a language that compiles into JavaScript. It allows for writing code with minimal boilerplate and is especially suitable for functional style.

With ramda-cli, snippets of code are written directly on the command line:

cat people.json | R 'filter (.name is /bob/i)' 'pluck \name'
[ "Bobbie Huel" , "Bobby Ryan", "Dr. Bobby Schiller" ]

For this reason, LiveScript interface makes sense.

In this document I'll quickly go through the most practical features from the perspective of ramda-cli.

Invoking a function

Functions can be called without parentheses if passing arguments.

Nested calls wrap to the end of line as such:

console.log to-upper \fooconsole.log(toUpper('foo'))

Without arguments, use a bang call: do-stuff!

Basic syntactic sugar

Backslash string sugar is ideal for short identifiers:

\foo'foo'

<[ foo bar xyz ]>[ 'foo', 'bar', 'xyz' ]

String interpolation with hash inside double quotes:

"#first #last"first + " " + last

"#{obj.foo} #{obj.bar}"obj.foo + " " + obj.bar

Properties can be accessed without brackets:

arr.0arr[0]

obj.'foo'obj.foo

Objects

Braces are optional.

console.log milk: 1, cheese: 2console.log({ milk: 1, cheese: 2 })

Example

# :: {k: v} → {k: v}
inc-count = evolve count: add 1  # evolve({ count: add(1) })
inc-count count: 1               # => { count: 2 }

evolve :: {k: (v -> v)} -> {k: v} -> {k: v}

Defining a function

identity = (x) -> xvar identity = function(x) { return x }

A function implicitly returns the last statement.

(str) -> str.to-upper-case!function(str) { return str.toUpperCase() }

You can omit the argument list and refer to the first argument as it.

filter -> it % 2 is 0filter(function(it) { return it % 2 === 0 })

Example

add = (x, y) -> x + y  # var add = function(x, y) { return x + y }
add 1 2                # => 3

Access and function call shorthand

(.length)(it) -> it.lengthfunction(it) { return it.length }

Examples

map (.length), <[ expire syncrisis reindicating ]>  # => [ 6, 9, 12 ]
find (.0 is \f), <[ foo bar xyz ]>                  # => 'foo'
echo '{"hello": "world"}' | R '.hello'
"world"

The above works because '.hello' evaluates like this:

  ramda-cli:main '(.hello)' +1ms input code
  ramda-cli:main
(function(it){
  return it.hello;
}); +29ms compiled code

Normally you would need to wrap it into parentheses like (.hello), however, ramda-cli wraps every function argument to parentheses automatically. This is a case where using a LS idiom is superior to using a Ramda function. To get a property value of an object, Ramda provides prop('hello').

Interlude

These all do the same thing, with decreasing level of verbosity.

list = [\foo, \hello, \bar]
list.filter (str) -> str.length is 5
list.filter -> it.length is 5
list.filter (.length is 5)
# => [ 'hello' ]

Sections

You can use operators as functions.

map (+ '!') <[ foo bar ]>       # => [ 'foo!', 'bar!' ]
reduce (+), 0, [1, 2, 3]        # => 6
filter (!= null), [1, null, 2]  # => [ 1, 2 ]

Function composition operators

  • (f << g) x is compose(f, g)(x) is f(g(x))
  • (f >> g) x is pipe(f, g)(x) is g(f(x))
  • The f . g behaves the same way as <<.

Example

fn = map head >> inc  # map(pipe(head, toUpper))
fn [[1, 2], [3, 4]]   # => [ 2, 4 ]

Further reading

There's a lot more to LiveScript, but this will get you started with ramda-cli. For more, check out these articles. You might wonder why settle with transpiling ES6.

See also:

Created 4 years ago | Updated 3 years ago

Comments

GistLog © 2019
Brought to you by the lovely humans at Tighten