=pod

=encoding utf8

=head1 NAME

YAMLScript - Programming in YAML

=head2 SYNOPSIS

A YAMLScript program C<99-bottles.ys>:

    #!/usr/bin/env yamlscript

    main(number=99):
      map:
      - println
      - map(paragraph, range(number, 0, -1))

    paragraph(num): |
      $(bottles, num) of beer on the wall,
      $(bottles, num) of beer.
      Take one down, pass it around.
      $(bottles, (num - 1)) of beer on the wall.

    bottles(n):
      cond: [
        (n == 0), "No more bottles",
        (n == 1), "1 bottle",
        :else,    "$n bottles" ]

Run: C<yamlscript 99-bottles.ys 3>

    3 bottles of beer on the wall,
    3 bottles of beer.
    Take one down, pass it around.
    2 bottles of beer on the wall.

    2 bottles of beer on the wall,
    2 bottles of beer.
    Take one down, pass it around.
    1 bottle of beer on the wall.

    1 bottle of beer on the wall,
    1 bottle of beer.
    Take one down, pass it around.
    No more bottles of beer on the wall.

Use the YAMLScript REPL:

    $ yamlscript
    Welcome to YAMLScript [perl]

    user=> nums =: range(1 4)
    user/nums
    user=> nums
    (1 2 3)
    user=> map: [ println, nums ]
    1
    2
    3
    (nil nil nil)
    user=> <ctrl-D>         # to exit
    $

=head2 STATUS

This is very ALPHA software. Expect things to change.

=head2 DESCRIPTION

YAMLScript is a programming language that uses YAML as a base syntax. It feels like a YAML encoded Lisp, but with fewer parentheses.

In fact YAMLScript I<is> a Lisp. It's a YAML-based specialized syntax reader for the L<Lingy|https://metacpan.org/dist/Lingy/view/lib/Lingy.pod> programming language. B<Lingy> is a port of the B<Clojure> language to other languages (like Perl). Clojure is a Lisp hosted by the Java JVM.

=head2 INSTALLATION

YAMLScript is currently only available as a Perl CPAN module. You install it like so:

    $ cpanm YAMLScript

Once installed you will have access to the C<yamlscript> CLI command. You will also have library support to invoke YAMLScript directly from Perl.

=head2 YAMLSCRIPT LANGUAGE CAPABILITIES

=over

=item * Variable binding

    name =: 'world'

Variable names use lowercase letters C<a-z>, digits C<0-9> and must start with a letter. Name parts may be separated by a dash C<->.

=item * Variable dereferencing

    the-value =: name

Unquoted words are treated as Lingy symbols.

=item * Lingy Expressions

Plain (unquoted) scalars are treated as Lingy syntax. Scalars starting with C<(> are Lingy expressions.

    answer =: (2 * 3 * 7)

You can use a backslash to indicate turn YAML syntax into a Lingy syntax:

    my-vector =: \[1 2 3]

Without the C<\> it would be read by YAML as C<[ "1 2 3" ]>.

=item * String interpolation

YAMLScript strings need to be quoted, since plain (unquoted) strings are seen as Lingy symbols (variables) or syntax.

Lingy symbols or expressions preceded by a C<$> are interpolated into double quoted and literal style YAML scalars.

    # Double quoted strings are interpolated
    - greeting =: "Hello, $name!"
    # Multiline literal scalars are interpolated
    - hi-bye =: |
      Hello, $name.
      Goodbye, $name.
    # Single quoted strings are NOT interpolated
    - string =: 'Hello, $name!'

=item * Fixity:

In Lingy (a Lisp) you say things like:

    (println (* 3 7))

YAMLScript lets you say:

    println(3 * 7)

That is function symbols can be placed before the opening paren. And prefix math operations can be made infix.

=item * Function calls

    say:
      join: [' ', "Hello", "world!"]

or

    say(join(' ' ["Hello" "world!"]))

=item * Define functions

    square-and-add(x,y):
      ((x ^ 2) + y)

=item * Define multiple arity functions

    sum:
      (): 0
      (x): x
      (x, y): (x + y)
      (x, y, z*): (x + (y + (sum z*)))

=item * Conditionals

    if:
    - (x > 50)            # condition
    - say("$x wins :)")   # then
    - say("$x loses :(")  # else

=item * Try / Catch

    - try: (42 / 0)
      catch(e):
        say: "Caught error '$e'"

=item * Iteration

    for (name):
    - [Alice, Bob, Curly]
    - say: Hello, $name!

=item * Namespacing and Importing Modules

    ns My::Package:
      use:
      - Foo::Bar
      - Another::Module: [this, that]

YAMLScript modules may be written in YAMLScript, Lingy or Perl.

=back

=head2 AUTHORS

=over

=item * Ingy döt Net L<ingy@ingy.net|mailto:ingy@ingy.net>

=back

=head2 COPYRIGHT AND LICENSE

Copyright 2022-2023 by Ingy döt Net

This is free software, licensed under:

The MIT (X11) License

=cut
