ExpandCollapsePrev Next Index

+ 11.1 Application and call operators

So far, we've been assuming the syntax is mostly the same as conventional langauges. But Felix is different in this respect, and we should clear up some details.

+ 11.1.1 Operator whitespace

You may have noticed that you can write:

  fflush stdout;

And also

  fflush (stdout);

The two are equivalent.

Parentheses are not required for function application or for procedure calls, just for grouping. What this means is fflush (stdout) is only using whitespace for calling the procedure, and the parameter is just a grouping of one element.

+ 11.1.2 Operator dot

Those with familiarity with object-oriented languages (e.g. Java, C#) may find this more pleasing:

  val name = stdin.readln.strip;

It means exactly the same as before, the dot operator (.) is nothing more than reverse application. Postfix application binds more tightly than prefix application so

It means the same as

  val name = strip(readln(stdin));

You can also mix the dot operator and regular functions.

  f x.g

This means we apply g to x first, then f to the result.

+ 11.1.3 The dollar-sign ($) Operator

Okay. This one should look familiar, and not just because it comes before numbers. We've already been using it, and those with a Haskell background can probably guess what it does here.

  val name = strip $ readln $ stdin;

The {$} is typically used for procedural commands to save writing brackets around arguments: It takes everything that comes after it (up until the semicolon) and wraps it in an imaginary pair of parentheses. That is, the following two lines are equivalent.

  println$ "Hello "+name;
  println ("Hello "+name);

+ 11.1.4 The Pipe Operator

The pipe operator ({|>}) is very similar to the dollar sign ({$}) one, except it works in reverse nesting everything to its left in parentheses.

  val name = stdin |> readln |> strip;

+ 11.1.5 Hash Operator

Finally if a function takes only the unit argument {()}, you can use the very high precedence prefix # operator to call it.

  fun pi() => 22.0/7.0;
  println$ "Pi=" + str #pi;

[See next chapter for explanation of unit type]

+ 11.1.6 Implied procedure call

And there's a special case for procedures with no arguments:

  proc doit() { println "Done"; }
  doit;

allowing you to omit the unit argument.

This is an example of type based syntactic sugar which is used a quite a bit in Felix to provide shortcuts. A statement which is an expression of a type other than void is not normally allowed. In this special case, however, if the type is {unit->void} then the compiler translates it into an application of the expression to {()}.