SCHEME
Scheme is a minimalist, functional programming language with a simple and consistent syntax. Its design emphasizes simplicity and expressiveness, making it a great language for learning programming concepts. Below is a complete breakdown of Scheme syntax, covering its core components and features.
1. Basic Syntax Rules
- Prefix Notation: All expressions are written in prefix notation, meaning the operator or function comes before the arguments.
(+ 2 3) ; => 5 - Parentheses: Parentheses
()are used to group expressions. Every expression in Scheme is enclosed in parentheses. - Whitespace: Spaces or newlines separate elements within an expression.
2. Data Types
Scheme supports several basic data types:
#### a. Numbers
- Integers: 42, -7
- Floating-point: 3.14, -0.5
- Rationals: 1/2, -3/4
#### b. Booleans
- #t (true)
- #f (false)
#### c. Characters
- Written with a #\ prefix: #\a, #\space, #\newline
#### d. Strings
- Enclosed in double quotes: "Hello, Scheme!"
#### e. Symbols
- Used as identifiers or names: 'symbol, 'x, 'my-var
#### f. Lists
- A fundamental data structure in Scheme: (1 2 3), '(a b c)
#### g. Pairs
- Created with cons: (cons 1 2) => (1 . 2)
3. Expressions
Every Scheme program is made up of expressions. An expression can be:
- A literal value: 42, "hello"
- A variable reference: x, my-var
- A function call: (+ 2 3)
- A special form: (define x 10)
4. Variables and Binding
define: Binds a value to a variable.(define x 10) (define name "Alice")let: Creates local bindings.(let ((x 10) (y 20)) (+ x y)) ; => 30
5. Functions
- Defining Functions:
Use
defineto create a function.(define (square x) (* x x)) (square 5) ; => 25 - Lambda Functions:
Anonymous functions created with
lambda.(define square (lambda (x) (* x x))) (square 5) ; => 25
6. Control Structures
- Conditionals:
if: Evaluates a condition and returns one of two values.(if (> 5 3) "Yes" "No") ; => "Yes"cond: A multi-branch conditional.(cond ((> 5 10) "Greater") ((= 5 5) "Equal") (else "Less")) ; => "Equal"
- Logical Operators:
and: Returns#tif all arguments are true.(and #t #f) ; => #for: Returns#tif any argument is true.(or #t #f) ; => #tnot: Negates a boolean value.(not #t) ; => #f
7. Lists and Pairs
- Creating Lists:
- Use
listor quote notation.(list 1 2 3) ; => (1 2 3) '(1 2 3) ; => (1 2 3)
- Use
- Accessing Elements:
car: Gets the first element of a list.(car '(1 2 3)) ; => 1cdr: Gets the rest of the list.(cdr '(1 2 3)) ; => (2 3)
- Constructing Pairs:
- Use
cons.(cons 1 2) ; => (1 . 2) (cons 1 lst); => adds item to from of list
- Use
8. Recursion
Scheme relies heavily on recursion for iteration. - Example: Factorial
(define (factorial n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
(factorial 5) ; => 120
9. Higher-Order Functions
Functions that take other functions as arguments or return functions.
- map: Applies a function to each element of a list.
(map square '(1 2 3 4)) ; => (1 4 9 16)
filter: Filters a list based on a predicate.
(filter even? '(1 2 3 4 5)) ; => (2 4)
lambda: Creates anonymous functions.
(map (lambda (x) (* x x)) '(1 2 3)) ; => (1 4 9)
### 10. **Input/Output**
display: Prints a value to the output.scheme (display "Hello, Scheme!") ; => Hello, Scheme!newline: Prints a newline.scheme (newline)read: Reads input from the user.scheme (define x (read))
11. Quoting and Quasiquoting
- Quote (
'): Prevents evaluation.'(1 2 3) ; => (1 2 3) - Quasiquote (
`): Allows selective evaluation with,.`(1 ,(+ 2 3) 4) ; => (1 5 4)
12. Macros
Scheme allows defining macros for metaprogramming. - Example: Simple Macro
(define-syntax when
(syntax-rules ()
((_ condition body ...)
(if condition (begin body ...)))))
(when #t (display "Hello")) ; => Hello
13. Modules and Libraries
- Use
define-moduleorimport(depending on the Scheme implementation) to organize code into modules.(define-module (math) (export square) (define (square x) (* x x)))
Summary of Scheme Syntax
| Feature | Example |
|---|---|
| Numbers | 42, 3.14, 1/2 |
| Booleans | #t, #f |
| Strings | "Hello" |
| Lists | (1 2 3), '(a b c) |
| Variables | (define x 10) |
| Functions | (define (square x) (* x x)) |
| Conditionals | (if (> 5 3) "Yes" "No") |
| Recursion | (define (factorial n) ...) |
| Higher-Order | (map square '(1 2 3)) |
| I/O | (display "Hello") |
| Quoting | '(1 2 3), `(1 ,(+ 2 3)) |
This breakdown covers the entirety of Scheme syntax. It’s a simple yet powerful language that forms the foundation for many advanced programming concepts!
not Function
- Syntax:
(not value) - Purpose: Negates a boolean value.
- Returns:
#tifvalueis#f, otherwise#f.
#### Examples:
(not #t) ; => #f
(not #f) ; => #t
(not (= 3 3)) ; => #f (because (= 3 3) is #t)
(not (> 5 10)) ; => #t (because (> 5 10) is #f)
Outputs:
#f
#t
#f
#t
Predicate Functions for Numbers
Predicate functions test conditions on numbers and return #t or #f.
#### a. = (Equal To)
- Syntax: (= num1 num2 ...)
- Purpose: Checks if all numbers are equal.
- Example:
(= 3 3) ; => #t
(= 3 4) ; => #f
(= 3 3.0) ; => #t (exact and inexact numbers can be equal)
#t
#f
#t
#### b. < (Less Than)
- Syntax: (< num1 num2 ...)
- Purpose: Checks if numbers are in increasing order.
- Example:
(< 3 5) ; => #t
(< 5 3) ; => #f
(< 3 3) ; => #f
#t
#f
#f
#### c. > (Greater Than)
- Syntax: (> num1 num2 ...)
- Purpose: Checks if numbers are in decreasing order.
- Example:
(> 5 3) ; => #t
(> 3 5) ; => #f
(> 3 3) ; => #f
#t
#f
#f
#### d. <= (Less Than or Equal To)
- Syntax: (<= num1 num2 ...)
- Purpose: Checks if numbers are in non-decreasing order.
- Example:
(<= 3 5) ; => #t
(<= 5 5) ; => #t
(<= 5 3) ; => #f
#t
#t
#f
#### e. >= (Greater Than or Equal To)
- Syntax: (>= num1 num2 ...)
- Purpose: Checks if numbers are in non-increasing order.
- Example:
(>= 5 3) ; => #t
(>= 5 5) ; => #t
(>= 3 5) ; => #f
#t
#t
#f
#### f. zero?
- Syntax: (zero? num)
- Purpose: Checks if a number is zero.
- Example:
(zero? 0) ; => #t
(zero? 1) ; => #f
#t
#f
#### g. positive?
- Syntax: (positive? num)
- Purpose: Checks if a number is greater than zero.
- Example:
(positive? 5) ; => #t
(positive? -3); => #f
#t
#f
#### h. negative?
- Syntax: (negative? num)
- Purpose: Checks if a number is less than zero.
- Example:
(negative? -3); => #t
(negative? 5) ; => #f
#t
#f
#### i. even?
- Syntax: (even? num)
- Purpose: Checks if a number is even.
- Example:
(even? 4) ; => #t
(even? 5) ; => #f
#t
#f
#### j. odd?
- Syntax: (odd? num)
- Purpose: Checks if a number is odd.
- Example:
(odd? 5) ; => #t
(odd? 4) ; => #f
#t
#f
4. Combining not with Predicates
You can use not to negate the result of a predicate function.
#### Examples:
(not (= 3 4)) ; => #t (because (= 3 4) is #f)
(not (zero? 0)); => #f (because (zero? 0) is #t)
(not (even? 5)); => #t (because (even? 5) is #f)
Outputs:
#t
#f
#t
5. Extended Example: Combining Predicates
Here’s a function that checks if a number is positive and even:
(define (positive-even? n)
(and (positive? n) (even? n)))
(positive-even? 4) ; => #t
(positive-even? -4); => #f
(positive-even? 5) ; => #f
Outputs:
#t
#f
#f
6. Advanced: Using Predicates in Higher-Order Functions
You can use predicates with higher-order functions like filter to process lists.
#### Example:
(define numbers '(1 2 3 4 5 6 7 8 9 10))
(filter even? numbers) ; => (2 4 6 8 10)
(filter positive? numbers) ; => (1 2 3 4 5 6 7 8 9 10)
(filter (lambda (x) (not (zero? x))) numbers) ; => (1 2 3 4 5 6 7 8 9 10)
Outputs:
(2 4 6 8 10)
(1 2 3 4 5 6 7 8 9 10)
(1 2 3 4 5 6 7 8 9 10)
Output
The statement that "Scheme output functions aren't used" might be referring to the fact that Scheme, as a minimalist and functional programming language, often emphasizes computational purity and avoiding side effects (like printing to the console). In functional programming, the focus is on returning values rather than performing actions like input/output (I/O), which are considered side effects.
Here’s a breakdown of what this might mean:
1. Functional Programming Philosophy
- In pure functional programming, functions are designed to take inputs and return outputs without causing side effects (e.g., modifying state or interacting with the outside world).
- Output functions like
display,write, andnewlineare inherently impure because they interact with the outside world (e.g., printing to the console). - Scheme, being a multi-paradigm language, supports functional programming, so some programmers might avoid using output functions to adhere to a more "pure" functional style.
2. Scheme's Minimalism
- Scheme is designed to be a minimal and elegant language. Its standard library is intentionally small, and many tasks (like complex I/O) are left to implementations or libraries.
- Output functions are not the primary focus of the language, and some Scheme programmers might prefer to use them sparingly or only when necessary.
3. Alternative Approaches
- Instead of directly using output functions, Scheme programmers might structure their programs to return values that can be displayed by the REPL (Read-Eval-Print Loop) or another layer of the program.
- For example, in a Scheme REPL, you can simply evaluate an expression, and the result will be printed automatically:
Output:
(+ 2 3)5 - This avoids the need for explicit output functions like
displayorwrite.
4. Educational Context
- If the text you read is from an educational resource, it might be emphasizing the importance of understanding Scheme's core concepts (e.g., recursion, lambda expressions, and higher-order functions) rather than focusing on I/O, which is considered more of a practical concern.
5. When Output Functions Are Used
- Despite the emphasis on purity, output functions are still useful in real-world programming, especially for debugging, logging, or interacting with users.
- For example:
Output:
(define (factorial n) (if (= n 0) 1 (* n (factorial (- n 1))))) (display "The factorial of 5 is: ") (display (factorial 5)) (newline)The factorial of 5 is: 120