1.3 Using Built-in Functions

Plait includes some of the usual functions on numbers, like floor and max. To call a function, start with an open parenthesis, then use the function name, then the argument, and finally a closing parenthesis:

> (floor 1.2)

- Number

1.0

> (max 3 5)

- Number

5

The parenthesis must be before the function, not after. Don’t use commas between arguments. Also, extra parentheses are not allowed. If you include extra parentheses around 3, for example, then Plait will complain that 3 is not a function, since the parentheses mean a function call:

> (max (3) 5)

eval:24.0: typecheck failed: call of a non-function

  possible reason: extra parentheses create a function call

  type mismatch: (-> '_a) vs. Number

  sources:

   3

The same error happens if you add parentheses around the call to max, since the result of max is a number:

> ((max 3 5))

eval:25.0: typecheck failed: call of a non-function

  possible reason: extra parentheses create a function call

  type mismatch: (-> '_a) vs. Number

  sources:

   (max 3 5)

   max

The type of a function is written with -> in parentheses. The function’s argument types appear before the arrow, and the function’s result type is after the arrow. A function is a value, so if you evaluate just max without calling it, then Plait will show the type and print that the result is a procedure (which is synonymous with “function” in Plait):

> max

- (Number Number -> Number)

#<procedure:max>

Unlike most languages, arithmetic operations such as + and * in Plait are just functions, and they are called the same way as other functions—just after an open parenthesis, and grouped with their arguments by a closing parenthesis:

> (+ 3 5)

- Number

8

> (* 3 5)

- Number

15

> +

- (Number Number -> Number)

#<procedure:+>

Note that + is allowed as a function name in fundamentally the same way that + is allowed in the symbol '+.

If you try to put the operator-as-function in the middle of its arguments, Plait will complain that the first argument isn’t a function, because the opening parenthesis means that first thing in the parenthesis should be a function to call:

> (3 + 5)

eval:30.0: typecheck failed: call of a non-function

  possible reason: extra parentheses create a function call

  type mismatch: ((Number Number -> Number) Number -> '_a)

vs. Number

  sources:

   3

If you omit then parentheses, then Plait see three separate expressions:

> + 3 5
- (Number Number -> Number)
#<procedure:+>
- Number
3
- Number
5

The style of syntax that puts a function/operation name up front and grouped with its arguments in parentheses is called parenthesized prefix notation.

Treating + like any other function makes Plait simpler, as does using parenthesized prefix notation. Since you didn’t have to create Plait, you may not care that Plait is simpler this way. But if you’re building your own interpreter in a class that’s about programming languages, then Plait’s regularity turns out to be a convenient design to imitate; you can spend more time studying the meaning of programming constructs and less time worrying about the syntax of those constructs.

Here are some example uses of other built-in functions, and you can click on any of the function names her eto jump to the documentation:

> (not #t)

- Boolean

#f

> (not #f)

- Boolean

#t

> (+ 1 2)

- Number

3

> (- 1 2)

- Number

-1

> (* 1 2)

- Number

2

> (< 1 2)

- Boolean

#t

> (> 1 2)

- Boolean

#f

> (= 1 2)

- Boolean

#f

> (<= 1 2)

- Boolean

#t

> (>= 1 2)

- Boolean

#f

> (string-append "a" "b")

- String

"ab"

> (string=? "a" "b")

- Boolean

#f

> (string-ref "a" 0)

- Char

#\a

> (string=? "apple" (string-append "a" "pple"))

- Boolean

#t

> (equal? "apple" (string-append "a" "pple"))

- Boolean

#t

> (eq? 'apple 'apple)

- Boolean

#t

> (eq? 'apple 'orange)

- Boolean

#f

Note that some operations work on multiple types. For example, equal? works on any two values, as long as the two values have the same type. That flexibility and constraint is reflected in the type of equal? by a symbol placeholder 'a, which you can read as “a type to be picked later.” A specific type is picked for every individual use of equal?:

> (equal? 1 1)

- Boolean

#t

> (equal? "one" "one")

- Boolean

#t

> equal?

- ('a 'a -> Boolean)

#<procedure:equal?>

> (equal? 1 "one")

eval:51.0: typecheck failed: Number vs. String

  sources:

   equal?

   "one"

   1