CSC302 2006S, Class 34: Haskell (1): The Basics Admin: * More Prolog? * No reading for Wednesday * Presentation proposals due Wednesday. * Desired form for final? * Take-home portion of final distributed Monday of 14th week, due Tuesday of finals week at 9 a.m. * Missing: Alex (sick) * Late: Dimitar, Mark Overview: * An Introduction to Haskell. * Haskell Syntax. * Types in Haskell. * Patterns in Haskell. Haskell: * Haskell is a functional language * Typeful * Compile-time typing * Type checking of expressions * User typing * User-declared types * Lazy - Only evaluates "needed" subexpressions * Pure - No side effects ; If you apply the same function to the same argument, you get the same value (random 5) ; (read) * Patterned - You can define functions with patterns * Syntactic issues * Which provides multiple mechanisms for function definition * And multiple syntaxes for other things * Nested comments * Haskell is a committee-designed lazy functional language * Response to: * lots of different languages, few common designs * need a language to "sell" to the broader world * response to commercial nature of most popular lazy func. language * Like many committee-designed languages, somewhat kitchen-sink-ish * Haskell is traditionally compiled, but may be interepreted * MathLAN: ghci /Syntax/ * Generally, uses prefix notation function op1 op2 op3 ... opn - Means apply function to operands * Supports infix notation when 'appropriate' * Arithmetic operations * List operations * (Your own operations) * Capitalization significant * Uppercase: Types, Constructors ; distinguish by context * Lowercase: variables, functions ; distinguish by context * Multiple forms for function definition * Simple name op1 op2 op3 ... opn = body e.g. fact n = if (n == 0) 1 (n * (fact (n-1))) * Lambda based name = \op1 op2 op3 ... opn -> body fact = \n -> if (n == 0) 1 (n * (fact (n-1))) * Pattern based (using constants in the lhs) name op1 op2 op3 ... opn = body fact 0 = 1 fact n = n * (fact (n - 1)) * Typing: * Programmer can declare types * System can infer types /How do we determine need?/ * For simple and lambda-based: You don't need the params, so just replace by rhs (substituting as appropriate) * For built-in operations: Depends on the operation * IF "needs" its first parameter * + "needs" both parameters (I think) * cons "needs" neither parameter * Pattern-based: Use the first constant in the first definition * Use of patterns plus laziness iif True x y = x iif False x y = y silly True x = x silly x False = False Pure logic: Order of evaluation should be "whatever is right" Haskell: Since the first def'n of silly uses True in the arg 1, we valuate the first argument first In "pure" logic, silly nonterminating False = False In Haskell, silly nonterminating False does not terminate nonterminating = nonterminating Does this permit ambiguous definitions? silly True x = x silly x False = True * Yes, if we treat the equations logically * No, if we admit the sequencing