From Swym Wiki
Jump to: navigation, search

Swym's syntax is designed to be consistent (as far as possible, each symbol has only one meaning - not different meanings in different contexts); terse (within reason); and above all, as readable and intuitive as possible.

Since "intuitive" often means something extremely like "familiar", Swym attempts to be familiar to the average programmer in two ways - it mimics both C, and English.

forEach[1..100] 'n'->
    'line' = select
        n.divisibleBy(15): "fizzbuzz",
        n.divisibleBy(3): "fizz",
        n.divisibleBy(5): "buzz",
        else: "$n"

[edit] Function calls

The syntax for a function call in Swym is extremely flexible, allowing you to write your code in whatever arrangement makes it clearest. (As you'll see, Swym has a LOT of syntactic sugar rules, but the underlying semantics are really quite simple.)

A function can be passed arguments in five different ways, all semantically equivalent:

  • fn(x) - a nice traditional function call with positional arguments.
  • fn{foo} - If the argument is a literal expression in square brackets [...] or braces {...}, you can omit the parentheses around it.
  • fn~x - The tilde operator removes the need for a close bracket. Great for nested function calls.
  • x.fn - The dot operator feels like accessing properties of an object.
  • fn@(argName=x) - you can also provide explicit argument names, if that helps to clarify your intent.

You can also mix and match these function call styles within a single expression. Just use whatever arrangement works best for your particular expression. So these lines are all equivalent:

  • print(sqrt(length(each(X)))); - traditional function calls
  • X.each.length.sqrt.print; - dot operator
  • print~sqrt~of~length~of~each~X; // - tilde calls. Note that the 'of' function does nothing - its job is to make these expressions a bit prettier.
  • sqrt~length(X.each).print; - When mixing operators, the precedence order is () first, then ~, then the . operator.

As previously mentioned, when a function call takes an argument that's surrounded by curly brackets {} or square brackets [], the usual function parentheses can be omitted. For example, the min function finds the minimal element of an array, but you can use it find the minimal element of a pair of numbers without needing any more typing:

'x' = 10
'y' = 4
print( max[x,y] )

You can even combine these methods to pass multiple arguments into a single function call, such as:

  fn(a, b, c, namedArg=d, namedArg=e)
  a.fn(b, c, arg1=e, arg2=g)

See also: Dot operator, Tilde operator, else keyword, and Numeric functions.

[edit] Blocks

In Swym it's incredibly easy to create anonymous functions, known as "blocks". Just write any expression between curly brackets! When you evaluate the block, it will run that expression and return the result.

'helloblock' = {"Hello"}
    println( helloblock ) // prints: {"Hello"}
    println( do(helloblock) ) // prints: Hello

Notice that to evaluate the block, we have to call the 'do' function. In Swym, like Lisp, functions are in a different namespace from local variables, so you can't just write helloblock(). Swym will complain "Function 'helloblock' is unknown".

By default, every block implicitly takes one argument, called it. The caller provides that argument by calling the two-argument version of 'do':{ print(it+1) }

Because the two-argument version of 'do' gets called so often, you can actually omit the word 'do' here.

3.{ print(it+1) }

Blocks are most commonly used as arguments to another function. Recall my point earlier about being able to omit round brackets from a function call when writing {} or []:

["Hello", "Bonjour", "Hola"].sortBy{.length}

Maybe it's unclear what's going on there... if you left out all the syntactic sugar from that expression, you'd have:sortBy( this=["Hello", "Bonjour", "Hola"], property='it'->{it.length} )

Personal tools