Scheme as implemented by Racket

Similar documents
Scheme Quick Reference

Scheme Quick Reference

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

SCHEME 8. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. March 23, 2017

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

Administrivia. Simple data types

Essentials of Programming Languages Language

Essentials of Programming Languages Language

Fall 2017 Discussion 7: October 25, 2017 Solutions. 1 Introduction. 2 Primitives

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

CSC 533: Programming Languages. Spring 2015

Spring 2018 Discussion 7: March 21, Introduction. 2 Primitives

LECTURE 16. Functional Programming

CSE 341 Lecture 16. More Scheme: lists; helpers; let/let*; higher-order functions; lambdas

SCHEME The Scheme Interpreter. 2 Primitives COMPUTER SCIENCE 61A. October 29th, 2012

SCHEME AND CALCULATOR 5b

Intro. Scheme Basics. scm> 5 5. scm>

Organization of Programming Languages CS3200/5200N. Lecture 11

Functional Programming. Pure Functional Programming

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

CSE 341 Section Handout #6 Cheat Sheet

Modern Programming Languages. Lecture LISP Programming Language An Introduction

CS450 - Structure of Higher Level Languages

COP4020 Programming Assignment 1 - Spring 2011

How to Design Programs Languages

Scheme Tutorial. Introduction. The Structure of Scheme Programs. Syntax

6.034 Artificial Intelligence February 9, 2007 Recitation # 1. (b) Draw the tree structure corresponding to the following list.

Streams and Evalutation Strategies

CSCC24 Functional Programming Scheme Part 2

Functional Programming - 2. Higher Order Functions

11/6/17. Functional programming. FP Foundations, Scheme (2) LISP Data Types. LISP Data Types. LISP Data Types. Scheme. LISP: John McCarthy 1958 MIT

Scheme: Strings Scheme: I/O

An Introduction to Scheme

Box-and-arrow Diagrams

YOUR NAME PLEASE: *** SOLUTIONS ***

Functional Programming. Pure Functional Languages

University of Massachusetts Lowell

Lecture #24: Programming Languages and Programs

Interpreters and Tail Calls Fall 2017 Discussion 8: November 1, 2017 Solutions. 1 Calculator. calc> (+ 2 2) 4

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

;;; Determines if e is a primitive by looking it up in the primitive environment. ;;; Define indentation and output routines for the output for

Introduction to Scheme

CS 314 Principles of Programming Languages

A Brief Introduction to Scheme (II)

CS61A Summer 2010 George Wang, Jonathan Kotker, Seshadri Mahalingam, Eric Tzeng, Steven Tang

Discussion 4. Data Abstraction and Sequences

Functional abstraction. What is abstraction? Eating apples. Readings: HtDP, sections Language level: Intermediate Student With Lambda

Functional abstraction

CS115 - Module 9 - filter, map, and friends

Documentation for LISP in BASIC

Typed Racket: Racket with Static Types

Announcements. The current topic: Scheme. Review: BST functions. Review: Representing trees in Scheme. Reminder: Lab 2 is due on Monday at 10:30 am.

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

Racket. CSE341: Programming Languages Lecture 14 Introduction to Racket. Getting started. Racket vs. Scheme. Example.

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

Freeing memory is a pain. Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down

The Typed Racket Guide

A brief tour of history

Programming Languages: Application and Interpretation

Project 2: Scheme Interpreter

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

SCHEME 10 COMPUTER SCIENCE 61A. July 26, Warm Up: Conditional Expressions. 1. What does Scheme print? scm> (if (or #t (/ 1 0)) 1 (/ 1 0))

More Scheme CS 331. Quiz. 4. What is the length of the list (()()()())? Which element does (car (cdr (x y z))) extract from the list?

INTRODUCTION TO SCHEME

Module 8: Local and functional abstraction

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

Functional Programming

6.001 SICP. Types. Types compound data. Types simple data. Types. Types procedures

Programming Languages. Function-Closure Idioms. Adapted from Dan Grossman's PL class, U. of Washington

Chapter 11 :: Functional Languages

Introduction to Functional Programming

CONCEPTS OF PROGRAMMING LANGUAGES Solutions for Mid-Term Examination

Functional Programming Languages (FPL)

CS 360 Programming Languages Interpreters

Functional Programming and Haskell

CS61A Discussion Notes: Week 11: The Metacircular Evaluator By Greg Krimer, with slight modifications by Phoebus Chen (using notes from Todd Segal)

Programming Languages

Functional programming with Common Lisp

Functional Languages. Hwansoo Han

CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

Functional Programming Languages (FPL)

Functional Programming. Pure Functional Languages

User-defined Functions. Conditional Expressions in Scheme

Principles of Programming Languages

Common Lisp. Blake McBride

Python I. Some material adapted from Upenn cmpe391 slides and other sources

CS 314 Principles of Programming Languages

Warm-up and Memoization

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

Symbolic Computation and Common Lisp

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

Introduction to Functional Programming in Haskell 1 / 56

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

CSCI337 Organisation of Programming Languages LISP

Principles of Programming Languages COMP251: Functional Programming in Scheme (and LISP)

(Func&onal (Programming (in (Scheme)))) Jianguo Lu

Freeing memory is a pain. Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down

Discussion 11. Streams

Transcription:

Scheme as implemented by Racket (Simple view:) Racket is a version of Scheme. (Full view:) Racket is a platform for implementing and using many languages, and Scheme is one of those that come out of the box. Racket s version of Scheme is somewhat different from the standards, e.g., function names, some features. My slides are right for Racket, but may fail with standard Scheme. But same principles. My slides give you a taste, but there are a lot of useful things I won t cover. 1 / 33

Basic Data Types And Syntax of Their Literals Booleans: #t, #f Numbers: 42 (integers), 1/3 (rational numbers), 42.5 (floating-point numbers), 3+4i (complex numbers) Strings: "hello" Single characters: #\h stands for the letter h. Symbols: User-defined atomic values. You think up a name, put a single-quote in front. Four examples: Firefox Chrome Edge Safari Great for tags, labels, enumerations. Symbols are not strings. You can t append, split, ask for the nth character... 2 / 33

Expressions Literals: Examples on the previous slide. Identifiers: E.g., +, my-angle/time Procedure/Function Applications: (proc param1 param2...) proc and parameters are expressions. proc should evaluate to a procedure. E.g., (sin (/ 0.2 2)) E.g., ((if #t sin cos) (/ 0.2 2)) Special Forms: (keyword expr expr...) For definitions, conditionals, other features... They have their own slides. 3 / 33

Some Boolean Operations (not expr) (and expr expr...) Short-circuits. (and) gives #t. (or expr expr...) Short-circuits. (or) gives #f. (boolean? expr) Tests whether you have a boolean value. 4 / 33

Some Number Operations + - * / max min can take multiple operands. quotient remainder abs sqrt sin cos tan etc. (expt b x) means b x. (exp x) means e x. (log x) means ln x. = < <= > >= can take multiple operands, e.g., (> x y z) means x > y > z. number? tests whether a value is a number. complex?, real?, rational?, integer? test what kind of number. number->string string->number (has ways to indicate parse errors) 5 / 33

Some String Operations (string-length str): length. (string-ref str k): character at position k (start from 0). (substring str i j) like Python s str[i:j]. (substring str i) like str[i:]. (string-append str1 str2...): concatenation. (string-append) gives the empty string. string=? string<? string<=? string>? string>=? Comparisons. Can take multiple operands. There are also case-insensitive versions. string? tests whether a value is a string. 6 / 33

Equality Equality is a mess. Three kinds, each with its intention and but s. eq? Good for booleans and symbols. Pointer equality for most aggregates, e.g., strings, lists. Complicated rules for numbers. Intention: Fast, just compare two machine words. eqv? Good for characters. Complicated rules for numbers, and different from eq?. (Rationale: Choices in treating floating-point s NaN and signed zero.) Most other types: Same as eq?. equal? Structural equality for most aggregates, i.e., comparing contents. 7 / 33

Definitions Give cool names to cool things. Examples: ; A constant. ( define my- width/ height (/ 4 3)) ; A function with 1 parameter. ( define ( greet person) ( string - append " hello " person)) ; A function with 2 parameters. ( define (my- log base x) (/ (log x) (log base))) Recursion is allowed. 8 / 33

Anonymous Functions/Procedures (lambda, λ) (Terminology: procedure expected to be effectful, e.g., I/O; function expected to be effect-free. Not strictly enforced though.) Can write a function without name; procedure expression. (lambda (param1 param2...) body) Example: (lambda (base x) (/ (log x) (log base))) Example usage: ( (lambda (base x) (/ (log x) (log base))) 128 2) Function definition (define (f x y) body) is short-hand for (define f (lambda (x y) body)). May also write λ. 9 / 33

Conditionals If-then-else: (if test then-expr else-expr) Actually test can be non-boolean treated as true. Multiple conditions: (cond [(> x y) (sin x)] [(< x y) (cos y)] [else 0]) If x > y then sin x; else if x < y then cos y; else 0. Test results can be non-boolean treated as true. Furthermore you can obtain and use it: (cond [(+ 4 2) => (lambda (x) (* x x))] [else 0]) This gives 36. 10 / 33

and, or As Conditionals (and expr expr...) Evaluates from left to right, stops as soon as #f happens. Otherwise, the last expr is the answer. Examples: (and 42 #f "hello") gives #f (and 42 hey "hello") gives "hello" (and) gives #t (or expr expr...) Evaluates from left to right, stops as soon as non-#f happens, and that s the answer. Otherwise, the answer is #f. Examples: (or 42 hey "hello") gives 42 (or (and #f) #f) gives #f (or) gives #f 11 / 33

Local Bindings Non-Recursive Local definitions for use in just one expression. (let ([x expr1] [y expr2]) (+ x y (* 2 x y))) Compute x + y + 2xy, where x = expr1 and y = expr2. expr1 and expr2 cannot see the local x or y; they see outer names. (let ([x 3]) (let ([x (* x x)]) ; (* 3 3) x)) gives 9 and is not a recursion. let* allows later bindings to see earlier bindings. (let* ([x 5] [y (+ x 1)]) ; (+ 5 1) (+ x y (* 2 x y))) 12 / 33

Local Bindings Recursive letrec allows recursive bindings (self or mutually). (letrec ([fac (lambda (n) (if (= n 0) 1 (* n (fac (- n 1)))))] [even (lambda (n) (or (= n 0) (not (odd (- n 1)))))] [odd (lambda (n) (not (even (- n 1))))]) (even (fac 5))) 13 / 33

Recommended Code Layout Jokes: Pythonic Scheme inspired by Pythonic Java. Serious: Open parentheses then immediately first word. Procedure definition: Body starts on new line, indented. Long expression: Parts start on new lines, indented. Closing parentheses not on new lines. Most editors have Scheme modes that can do these for you. 14 / 33

Compound Data: Pairs And Lists Cons cell, 2-tuple, pair. Syntax: (cons x y). Can imagine a pair of pointers. Short-hand if both fields are literals: (5. "hello"). What if the 2nd field is (points to) a cons cell again, and its 2nd field is a cons cell again,...? Singly-linked list. Special support for lists: Empty list: () (list x y z) = (cons x (cons y (cons z ()))) List literal: (42 "hi" Chrome) The Chrome means the symbol Chrome. 15 / 33

Some Pair And List Operations Tests: pair?, list?, null? First field of a pair: car Second field of a pair: cdr First item of a list: first, same answer as car, but only for lists. Tail of a list: rest, same answer as cdr, but only for lists. length (list-ref lst i): item at position i. (append lst1 lst2...): concatenation. reverse Higher-order functions: map, filter, foldr, foldl... discussed later. 16 / 33

Compound Data: User-Defined Records (struct dim (width height)) creates a new record type of two fields, with these support utilities: (dim 4 7) constructs a value of this type. dim? tests for this type. dim-width, dim-height: field accessors. struct-copy: Clones a record while replacing some field values. Original record unchanged functional update. (define d1 (dim 4 7)) ( define d2 ( struct - copy dim d1 [ width 5])) Then d2 is (dim 5 7). 17 / 33

Pattern Matching Test for literal, cons cell, or record type, and get the content too. ( struct dim ( width height)) (define (foo x) (match x [ () nada] [(cons b _) b] [(dim w h) (* w h)])) (foo ()) gives nada (foo (1 2 3)) gives 1 (foo (dim 4 7)) gives 28 18 / 33

Input And Output: stdin, stdout, stderr stdout and stdin: (display 5), (display "hello") (newline), (displayln 5), (displayln "hello") (printf "~a = ~a~n" "price" 5) Aside: (format "~a = ~a~n" "price" 5) gives the string rather than outputs it. (read-line) (read-string 10) reads up to the upper bound. If EOF, returns eof, can use eq? or eof-object? to test. stderr: eprintf is like printf but goes to stderr. 19 / 33

Input And Output: Ports Racket has ports, analogous to Java Reader/Writer behind it can be file, string, network connection, message queue, user-defined. (call -with -output -file* "out.txt" #: mode text #: exists replace (lambda (op) ( displayln 6 op) (fprintf op "~a~n" 7))) (let ([s (call -with -input -file* "in.txt" #:mode text (lambda (ip) (read -string 10 ip)))]) (displayln s)) 20 / 33

Sequencing You may want to evaluate multiple expressions (in the order you specify) because the point is their effects. (begin ( displayln " Please enter your name") (read -line)) It returns what the last expression returns. (begin0 expr1 expr2...) returns what expr1 returns. (The other expressions are still evaluated.) (when (> x 0) expr1 expr2...) If true, evaluates the expressions, returns what the last one returns. If false, returns #<void>. 21 / 33

Sequencing Some constructs already support multiple expressions and sequencing, you don t need to wrap with begin: Conditionals and pattern matching: (cond [test expr1 expr2...] [...]...) (match expr [pattern expr1 expr2...] [...]...) Procedure bodies: (define (f x) expr1 expr2...) (lambda (x) expr1 expr2...) Bodies of let etc.: (let ([x 5] [y 42]) expr1 expr2...) Also, and, or already do sequencing. 22 / 33

Mutable Variables (define v 5) (define (f x) (+ v x)) (f 0) ; gives 5 (set! v 6) (f 0) ; gives 6 Mutable pairs, lists, strings, arrays... are also available. Use mutation judiciously. It is much less necessary than most people think. 23 / 33

map (map f (list x y z)) equals (list (f x) (f y) (f z)) Can you write your own version? ( define (my- map f lst) (match lst [ () ()] [(cons hd tl) (cons (f hd) (my-map f tl))])) Remark: Racket s map is more general can take several lists, e.g., (map + (1 2 3) (10 20 30)) equals (11 22 33). 24 / 33

filter (filter number? (9 "4" 0 "1" "6" 5)) equals (9 0 5). Can you write your own version? ( define (my- filter pred lst) (match lst [ () ()] [(cons hd tl) (if (pred hd) ( cons hd (my- filter pred tl)) (my-filter pred tl))])) 25 / 33

foldr Motivation Sum up a list, write your own recursion, first way: ( define (my- sum lst) (match lst [ () 0] [(cons hd tl) (+ hd (my-sum tl))])) Multiply a list, write your own recursion, first way: ( define (my- product lst) (match lst [ () 1] [(cons hd tl) (* hd (my-product tl))])) What is different? What stays the same? Can you factor it out? ( define ( foldr binop z lst) (match lst [ () z] [(cons hd tl) (binop hd (foldr binop z tl))])) 26 / 33

foldr If your function satisfies: (g ()) equals z (g (cons hd tl)) equals (binop hd (g tl)) Then (g lst) equals (foldr binop z lst) Intuitively, they look like a (b (c z)), writing for binop, if the list is (list a b c). Not always obvious. Some refactoring can help. Telltale sign: The recursion is simply on the list tail. Example: Next slide shows why my-map is a foldr. Example: my-filter is also a foldr. 27 / 33

my-map is a foldr = = = (define (my-map f lst) (match lst [ () ()] [(cons hd tl) (cons (f hd) (my-map f tl))])) (define (my-map f lst) (define (g lst) (match lst [ () ()] [(cons hd tl) (cons (f hd) (g tl))])) (g lst)) (define (my-map f lst) (define (binop x r) (cons (f x) r)) (define (g lst) (match lst [ () ()] [(cons hd tl) (binop hd (g tl))])) (g lst)) (define (my-map f lst) (define (binop x r) (cons (f x) r)) (foldr binop () lst)) 28 / 33

foldl Motivation Sum up a list, write your own recursion, second way (accumulator): ( define (my- sum lst) ; ( loop accum lst) computes accum + sum of lst ( define ( loop accum lst) (match lst [ () accum] [(cons hd tl) (loop (+ accum hd) tl)])) (loop 0 lst)) Multiply a list, write your own recursion, first way: ( define (my- product lst) ; ( loop accum lst) computes accum * product of lst ( define ( loop accum lst) (match lst [ () accum] [(cons hd tl) (loop (* accum hd) tl)])) (loop 1 lst)) What is different? What stays the same? Can you factor it out? 29 / 33

foldl ( define ( foldl binop a lst) (match lst [ () a] [(cons hd tl) (foldl binop (binop a hd) tl)])) Intuitively, (foldl binop a (list x y z)) looks like ((a x) y) z, writing for binop. 30 / 33

Procedure-Call Stack (define (f n) (... (f (- n 1))...) (displayln (+ (f 4) (f 1) (f 6))) Control-flow jumps into f; later automagically knows where to return to. Sufficiently elegant solutions are indistiguishable from magic. A stack is used to remember where to return to. Call stack. Benefit: Supports recursion (self and mutual). Price: Each invocation holds up Θ(1) space until it finishes. (Invented by Peter Naur for Algol. Before him, each procedure was given fixed space for return address. Recursion disallowed. People didn t believe Naur when he got this to work.) You will understand this intimately in Part II of the course. 31 / 33

Non-Tail Calls and Tail Calls Non-tail call: There is post-processing after the call returns. ( define (my- sum lst) (match lst [ () 0] [(cons hd tl) (+ hd (my-sum tl))])) Takes Θ(n) space (if n is the list length). Tail call: No post-processing after the call returns. No need to remember return address, just jump. ( define (my- sum lst) ( define ( loop accum lst) (match lst [ () accum] [(cons hd tl) (loop (+ accum hd) tl)])) (loop 0 lst)) Literally a loop. Takes O(1) space. 32 / 33

Nested Lambdas A procedure that returns a procedure. (define map1 (lambda (f) (lambda (lst) (map f lst)))) Sample usage: ((map1 abs) (-1-4)) Real usage: (map (map1 abs) ((-1-4) (-2-5))) Note: (map (map abs)...) doesn t work wrong number of parameters. 33 / 33