Skip to content
Ilya Sher edited this page Sep 23, 2018 · 9 revisions

Introduction to NGS hands-on workshop

( This document is a work in progress )

This document includes talk points and workshop tasks for the "Introduction to NGS hands-on workshop".

Scratchpad section (skip this)

TODO:

  • define a function
  • boolean expressions
  • string concatenation / +
  • methods
  • string indexing
  • string substitution "xx $yy zz"
  • array indexing

Why NGS

  • Covers the modern ops domain-specific niche.
    • bash is not modern
    • python, ruby, go are not ops domain-specific
  • Typical tasks:
    • Running external programs, pipes, redirects
    • Data manipulation
    • Both in one go: run external program and parse output

Intro to NGS

Online documentation is at https://ngs-lang.org/doc/0.2.5/index.html

Installing NGS

If you want to try NGS without installing, issue the command: docker run --rm -it ngslang/ngs:v0.2.5 . It will take you to a shell prompt from which you can run the ngs binary.

TODO: installation, verification

Running and exiting NGS

NGS has several mechanisms for integration with the environment. Running and exiting NGS are the prominent ones.

  • Switches: -e, -p, -pl, -pj, -pjl
    • ngs -e 'echo("Hello!")'
    • ngs -p '"Hello!"'
    • ngs -pl '[1,"aha",2]'
    • ngs -pl '0..5'
    • ngs -pj '["a", "b", "c"] * 2'
    • ngs -pjl '["a", "b", "c"] * 2'
  • Exit codes - all objects are converted to exit codes using ExitCode.
    • Of a process
      • ngs -e '$(true)'; echo $?
      • ngs -e '$(false)'; echo $?
      • ngs -e '$(bash -c "exit 10")'; echo $?
      • ngs -e '$(ok: bash -c "exit 10")'; echo $?
    • Of an NGS object
      • ngs -e true; echo $?
      • ngs -e false; echo $?
      • ngs -e 10; echo $?
      • ngs -e '"abc" ~ /^a/'; echo $?
      • ngs -e '"abc" ~ /^x/'; echo $?
  • die()
    • ngs -e 'die("mymessage")'; echo $?
    • ngs -e 'die("mymessage", 10)'; echo $?
  • exit()
    • ngs -e 'exit()'; echo $?
    • ngs -e 'exit(10)'; echo $?
    • ngs -e 'exit("mymessage")'; echo $?
    • ngs -e 'exit("mymessage", 10)'; echo $?

Interactive: Please try some of the above.

Syntax basics

NGS has two syntaxes: commands syntax and expressions syntax.

The reasoning behind two syntaxes: common ops tasks include running external programs, with i/o redirection and pipes and deserve their own syntax.

  • The two syntaxes and switching between them
    • Commands syntax (in a file)
      • This is the top level syntax in a file, similar to other shells
      • ls
      • ls >ls.txt
      • Switching to expressions syntax
        • Code block: { "aaa".echo() }
        • RHS of assignment: =, +=, -=, *=, /=, .=
        • Function definition: F f(x) x*10
        • Function call: echo(...) (but not func.method(...) yet)
        • Namespace declaration: ns { ... }
        • Control structures: if, while, switch, for
        • echo ${1+2}
    • Expressions syntax
      • This is the syntax in:
        • (A) command line switches
        • (B) after switch from commands syntax via one of the syntax constructs above
      • All the things that worked in commands syntax work, except for running external commands
      • Things that are exclusive to expressions syntax
        • 1 + 2
        • [1,2,3].each(echo)
      • Switching to commands syntax
        • ngs -e '$(ls)'
        • ngs -e '$(top_level:: ls)'
        • ngs -p '$(ls)'
        • ngs -pi '$(ls)' (-pi is explained in next section)
        • ngs -pi '$(ls | wc -l)'

Interactive:

cd Intro-handson
cat 01-syntax.ngs
./check.ngs 01-syntax.ngs

You will see that first test succeeds and the second test fails. Near the end of the file, before TEST lines, using expressions syntax, add an array which contains elements "abc" and "def". Use each and echo combination analogous to one that you see in the file to output the elements of the array. The new section that you add to the file should look similar to the few lines just below # switch to "expressions" syntax:.

Inspecting NGS objects

  • -pi switch
    • ngs -pi Str
    • ngs -pi Str.constructors
    • ngs -pi ExitCode
  • inspect()
    • ngs -e '["a", "b", "c" ].inspect().echo()'
      • data.method() and method(data) syntax
    • ngs -e '["a", "b", "c" ].inspect().each(echo)'
      • each() - one of the basic components of functional programming

A bit about data manipulation and functional programming

  • What is functional programming?
  • Why functional programming is good for data manipulation?
  • Function definition in NGS
    • Named: ngs -p 'F f(x) x*2; f(10)'
    • Anonymous:
      • ngs -p 'f = F(x) x*2; f(10)'
      • ngs -p '(F(x) x*2)(10)'
  • Basic higher order functions: each, map, filter, reject, Pred
    • ngs -e '[1,2,3].each(echo)'
    • ngs -e '[1,2,3].map(F(x) x*2).each(echo)'
    • ngs -e '[1,2,3,4].filter(F(x) x>2).each(echo)'
    • ngs -e '[1,2,3,4].reject(F(x) x>2).each(echo)'
    • ngs -e '[1,2,"abc","def"].filter(Int).each(echo)'
    • ngs -e '[1,2,"abc","def"].filter(Str).each(echo)'

Workshop - Hackernews tail

The workshop will be primarily focused on ops-specific aspects of NGS

Phase 1 - fetch and display the data

  • Comments
    • # HackerNews API documentation: https://github.com/HackerNews/API
  • Assignment
    • BASE_API_URL = 'https://hacker-news.firebaseio.com/v0'
  • Get items (stories) list
    • newstories = ``curl -s "${BASE_API_URL}/newstories.json"``
      • Quick points about sibling commands
        • $(run syntax)
        • `run-and-capture syntax`
      • Exit codes when NGS is running external programs and related exceptions
    • Limit items number:
      • newstories = newstories.limit(10)
      • newstories .= limit(10) (same as x += 1)
  • Get information about each item and display it
for i in reverse(newstories) {
	item = ``curl -s "${BASE_API_URL}/item/${i}.json"``
	# Sometimes "item" is null
	not(item) continues
	echo("-" * 80)
	echo("${Time(item.time)} [${item.by}] [${item.score}] ${item.title}")
	for k in %[url text] {
		# Display item's .url / .text if exist
		if k in item {
			echo(item[k])
		}
	}
}

Phase 2 - track state

  • Accessing environment variables using ENV
  • ENV.HOME / '.hn_state.json'
  • try
    • try fetch(STATE_FILE)
    • Mention try EXPR catch(e:Exception) HANDLER
  • fetch(filename:Str)
  • store(filename:Str, data:Any)
  • filter()

Phase 3 - polling

  • while CONDITION EXPR
  • $(sleep ...)

Phase 4 - wrap in main and parametrize

  • main() and arguments matching
    • main() is not required
    • Command line arguments are matched automatically
    • Parametrize interval
    • Add once option