• Mindscape ๐Ÿ”ฅ
    • Playlist ๐ŸŽง
  • Algorithm

    • 1018๋ฒˆ: ์ฒด์ŠคํŒ ๋‹ค์‹œ ์น ํ•˜๊ธฐ
    • 1966๋ฒˆ: ํ”„๋ฆฐํ„ฐ ํ
    • Python ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ํŒ
    • C++ std::vector ์‚ฌ์šฉ๋ฒ• ์ •๋ฆฌ
    • Vim ์‚ฌ์šฉ ๋งค๋‰ด์–ผ
  • Ubuntu

    • ๋ฆฌ๋ˆ…์Šค ์šฐ๋ถ„ํˆฌ GRUB ํฐํŠธ ๋ณ€๊ฒฝ
    • ์šฐ๋ถ„ํˆฌ ์ด๋ฏธ์ง€ ๋น„๋””์˜ค ์ธ๋„ค์ผ(๋ฏธ๋ฆฌ๋ณด๊ธฐ) ์•ˆ ๋ณด์ž„ ๋ฌธ์ œ ํ•ด๊ฒฐ
    • Wine ํ™˜๊ฒฝ์—์„œ ์นด์นด์˜คํ†ก ์‹คํ–‰ ์‹œ explorer.exe ๋œจ์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ๋ฒ•
    • ์šฐ๋ถ„ํˆฌ Wine ์นด์นด์˜คํ†ก ์‚ฌ์ง„ ์ด๋ฏธ์ง€ ์Šคํฌ๋ฆฐ์ƒท ๋ถ™์—ฌ๋„ฃ๊ธฐ
    • Wine ์นด์นด์˜คํ†ก ์ด๋ชจ์ง€ ๊นจ์ง ๋ฌธ์ œ ํ•ด๊ฒฐ
    • Ubuntu ์œˆ๋„์šฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋„๊ธฐ
  • Wellness

    • ์ฐจ์ „์žํ”ผ (Psyllium Husk)
    • ์—‘์ŠคํŠธ๋ผ ๋ฒ„์ง„ ์˜ฌ๋ฆฌ๋ธŒ์œ  (Extra Virgin Olive Oil)
    • ์ž๊ฐ€๋น„๊ฐ•์„ธ์ฒ™ (Nasal Irrigation)
    • QCY HT08 (MeloBuds Pro Plus)
    • ์ฝ˜์„œํƒ€ (Concerta)
    • ์ธ๋ฐ๋†€ (Inderal)
    • ์„คํŠธ๋ž„๋ฆฐ (Sertraline)
    • ๋ฉœ๋ผํ† ๋‹Œ (Melatonin)
    • ์น˜๊ฒฝ๋ถ€ ๋งˆ๋ชจ์ฆ
    • ๋ฐ”๋ฒจ ์Šค์ฟผํŠธ (Barbell Squat)
  • Humanities

    • Nordvik, Russia
    • North Sentinel Island
    • ๋กฑ๊ณ ๋กฑ๊ณ (Rongorongo)
    • ๋ฐ”๋กœํฌ ์Œ์•… (Baroque Music)
  • Design

    • ๊ตฌ๊ธ€์˜ ์•„์ด์ฝ˜ ๋Œ€๊ฐœํŽธ โ€” 6๋…„ ๋งŒ์˜ ์‹ค์ˆ˜ ์ธ์ •
    • ์ œ๋Ÿด๋“œ ์  ํƒ€ โ€” ๋Ÿญ์…”๋ฆฌ ์Šคํฌ์ธ  ์›Œ์น˜์˜ ์ฐฝ์‹œ์ž
    • ๋ฐ”์šฐํ•˜์šฐ์Šค โ€” ํ˜„๋Œ€ ๋””์ž์ธ์˜ ์›์ 
  • Brands

    • NOMOS Glashรผtte
    • Frรฉdรฉrique Constant
    • KZ (Knowledge Zenith)
    • ์—์ŠคํŠธ๋ผ (AESTURA)
    • JINHAO (้‡‘่ฑช)
    • Herman Miller
    • ๋ฐ์Šค์ปค (DESKER)
    • ๋ฌด์‹ ์‚ฌ ์Šคํƒ ๋‹ค๋“œ (Musinsa Standard)
  • Finance

    • ํ˜„๋Œ€์นด๋“œ ZERO โ€” Edition2 vs Edition3 ๋น„๊ต
    • ์‹ ํ•œ์นด๋“œ ์ฒ˜์Œ
    • S&P 500 ETF ํˆฌ์ž ๊ฐ€์ด๋“œ
    • ํŒŒํ‚นํ†ต์žฅ vs CMA ํ†ต์žฅ
    • ๋ฒ„ํฌ์…” ํ•ด์„œ์›จ์ด (Berkshire Hathaway)
    • ๋น„ํŠธ์ฝ”์ธ(Bitcoin)
  • Products

    • ์˜ค๋””์˜ค ์ธํ„ฐํŽ˜์ด์Šค (Audio Interface)
    • ์ฟ ๋ฃจํ† ๊ฐ€ (KURUTOGA)
    • CX31993 DAC ๋™๊ธ€
    • ํด๋ Œ์ง• ๋ฐ€ํฌ (Cleansing Milk)
    • ํ”ผ์ ฏ ํ† ์ด (Fidget Toy)
    • ThinkPad
  • Programming Languages

    • 8.0. Statement Level Control Structures
    • 8. Subprogram
    • 9. Implementing Subprogram
    • 10.1. Abstract Data Types and Encapsulation Constructs
    • 10.2. Support for Object Oriented Programming
    • 11. Concurrency
    • 12. FPL (1)
    • 13. FPL (2)
    • 14. Exception Handling and Event Handling
    • Final Exam

12. FPL (1)

์ž‘์„ฑ 2026. 6. 12.ยท์ˆ˜์ • 2026. 6. 12.

Functional Programming Languages

What do we study in this chapter?

  • Introduction
  • Mathematical Functions
  • Fundamentals of Functional Programming Languages
  • The First Functional Programming Language: Lisp Introduction to Scheme
  • Common Lisp
  • ML
  • Haskell
  • F#
  • Support for Functional Programming in Primarily Imperative Languages
  • Comparison of Functional and Imperative Languages

Introduction

The design of imperative language

  • Based on von Neumann architecture
  • ์ด ๊ตฌ์กฐ์—์„œ๋Š” ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜๊ณ , ํ”„๋กœ์„ธ์„œ๊ฐ€ ๋ช…๋ น์–ด๋ฅผ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•จ
  • Primary concern: efficiency (rather than suitability for SW development)
  • ์ดˆ๊ธฐ ๋ช…๋ นํ˜• ์–ธ์–ด์˜ ๋ชฉ์ ์€ ๊ฐœ๋ฐœ์ž์˜ ํŽธ์˜์„ฑ๋ณด๋‹ค ์‹คํ–‰ ํšจ์œจ์„ฑ์„ ์šฐ์„ ์‹œ
  • ํ•˜๋“œ์›จ์–ด ์ž์›์„ ์ตœ๋Œ€ํ•œ ํšจ์œจ์ ์œผ๋กœ ์“ฐ๋Š” ๊ฒƒ์ด ์ค‘์š”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ง๊ด€์ ์ด์ง€ ์•Š์€ ์ €์ˆ˜์ค€ ์—ฐ์‚ฐ์ด ๋งŽ๊ณ , ์—๋Ÿฌ ์œ ๋ฐœ ๊ฐ€๋Šฅ์„ฑ๋„ ๋†’์Œ
  • Reliance on the underlying architecture is thought by some to be an unnecessary restriction
  • Uses of variables are important
  • How program's state change
  • ๋ณ€์ˆ˜ ๊ฐ’์ด ๋ฐ”๋€Œ๋ฉด์„œ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜๋ฏ€๋กœ, ํฐ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์ƒํƒœ์˜ ํ๋ฆ„์„ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์–ด๋ ต๊ณ  ๋ณต์žกํ•ด์ง
  • โ†’ This is a daunting task for a large program

The design of functional language

  • Based on mathematical functions
  • ์ž…๋ ฅ โ†’ ํ•จ์ˆ˜ โ†’ ์ถœ๋ ฅ์˜ ๊ด€๊ณ„๋กœ, ์ƒํƒœ ๋ณ€๊ฒฝ ์—†์ด ๊ฒฐ๊ณผ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ
  • Solid theoretical basis (oriented more to particular programming paradigms or methodologies than to efficiency)
  • ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋Š” ๋žŒ๋‹ค ๊ณ„์‚ฐ๋ฒ•(ฮป\lambdaฮป-calculus) ๊ฐ™์€ ์ด๋ก ์  ๊ธฐ๋ฐ˜์ด ํŠผํŠผ
  • ํšจ์œจ์„ฑ๋ณด๋‹ค ๋ช…ํ™•ํ•œ ํŒจ๋Ÿฌ๋‹ค์ž„(๋ชจ๋“ˆ์„ฑ, ๋ถˆ๋ณ€์„ฑ, ์žฌ๊ท€ ๋“ฑ)์— ์ดˆ์ ์„ ๋‘ 
  • Closer to user (relatively less concerned with machine architecture)
  • ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋Š” ๊ธฐ๊ณ„์˜ ์ž‘๋™ ๋ฐฉ์‹์— ๋œ ์˜์กดํ•˜๊ณ , ๊ฐœ๋ฐœ์ž์˜ ์‚ฌ๊ณ  ํ๋ฆ„์— ๋” ๊ฐ€๊นŒ์›€
  • ๋ช…๋ นํ˜• ์–ธ์–ด์ฒ˜๋Ÿผ ์ƒํƒœ(state)๋ฅผ ์ถ”์ ํ•˜์ง€ ์•Š์•„๋„ ๋จ
  • LISP: began as pure functional language (1950๋…„๋Œ€ ๊ฐœ๋ฐœ)
  • But, acquired some important imperative features
  • ๋ช…๋ นํ˜• ํŠน์„ฑ(๋ฃจํ”„, ๋ณ€์ˆ˜ ํ• ๋‹น ๋“ฑ, (ex.) set!, loop, progn)
  • Used in knowledge representation, machine learning, intelligent training systems, and the modeling of speech
  • Common LISP is a dialects of LISP (๋‹ค์–‘ํ•œ LISP ๋ฐฉ์–ธ์„ ํ†ตํ•ฉํ•œ ํ‘œ์ค€ํ™”๋œ ๋ฒ„์ „)
  • Scheme is a small, static-scoped dialect of LISP
  • ML, Haskell, OCaml, and F#: typed functional programming languages

Mathematical Functions

Mapping member of domain(์ •์˜์—ญ) set to range(์น˜์—ญ) set

  • Function definition specifies domain and range sets
  • Along with mapping described by expression or table
  • Functions are applied to elements of domain set to yield elements of range set
  • Fundamental characteristics of mathematical functions
  • Evaluation order is controlled by recursion and conditional expressions
  • Rather than sequencing and iterative repetition
  • ๋ช…๋ นํ˜• ์–ธ์–ด์ฒ˜๋Ÿผ for, while ๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ์— ์˜์กดํ•˜์ง€ ์•Š์Œ
  • No side effects and cannot depend on any external values
  • ๊ฐ™์€ ์ž…๋ ฅ์— ๋Œ€ํ•ด ํ•ญ์ƒ ๊ฐ™์€ ์ถœ๋ ฅ โ†’ ์ฐธ์กฐ ํˆฌ๋ช…์„ฑ(referential transparency) ๋ณด์žฅ
  • No concept of stage of function
  • ๋ช…๋ นํ˜• ์–ธ์–ด์ฒ˜๋Ÿผ ํ•จ์ˆ˜๊ฐ€ ์ค‘๊ฐ„ ์ƒํƒœ(stage)๋ฅผ ๊ฐ–์ง€ ์•Š์Œ
  • ํ•จ์ˆ˜๋Š” ๊ทธ ์ž์ฒด๋กœ ์™„๊ฒฐ๋œ ๊ณ„์‚ฐ ๋‹จ์œ„์ด๋ฉฐ, ์ด์ „ ์ƒํƒœ๋ฅผ ๊ธฐ์–ตํ•˜์ง€ ์•Š์Œ

Function definitions are written

  • Name, list of parameters in parentheses and mapping expression
  • โ€œํ•จ์ˆ˜ ์ด๋ฆ„ + ๊ด„ํ˜ธ ์† ๋งค๊ฐœ๋ณ€์ˆ˜ + ์ •์˜ ์ˆ˜์‹โ€์˜ ํ˜•ํƒœ๋กœ ์ •์˜๋จ
  • [EX] cube(x) โ‰ก x * x * x
  • โ‰ก: โ€œis defined asโ€ (cube๋Š” ํ•จ์ˆ˜ ์ด๋ฆ„, x๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜(parameter), x * x * x๋Š” ํ•จ์ˆ˜๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ณ„์‚ฐ์„ ๋‚˜ํƒ€๋ƒ„) (์ˆ˜ํ•™์ ์œผ๋กœ "โ€ฆ๋กœ ์ •์˜๋œ๋‹ค"๋ฅผ ์˜๋ฏธํ•จ)
  • Parameter x can be any member of domain set but fixed during evaluation
  • ํ‰๊ฐ€ ๊ณผ์ •์—์„œ๋Š” ๊ณ ์ •๋จ โ†’ ํŠน์ • ๊ฐ’์œผ๋กœ ๋ฐ”์ธ๋”ฉ(binding) ๋จ
  • [EX] cube(2.0) = 2.0 * 2.0 * 2.0 = 8
  • x is bound to 2.0 during the evaluation and there are no unbound parameters
  • ํ‰๊ฐ€ ์ค‘์—๋Š” ๋ชจ๋“  ๋ณ€์ˆ˜๋“ค์ด ๊ฐ’์— ๋ฌถ์—ฌ ์žˆ์œผ๋ฉฐ, ๋”ฐ๋ผ์„œ ๋ช…ํ™•ํ•˜๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅํ•จ

Early theoretical work on functions separated the task of defining a function from that of naming the function โ†’ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ผญ ์ด๋ฆ„์„ ๋ถ™์ผ ํ•„์š”๋Š” ์—†๋‹ค๋Š” ๊ฐœ๋…์ด ์ƒ๊น€ โ†’ nameless function

  • Lambda expression specifies parameter(s) and mapping functions
  • [EX] ฮป(x)xโˆ—xโˆ—x\lambda(x) x * x * xฮป(x)xโˆ—xโˆ—x (ฮป\lambdaฮป(๋ณ€์ˆ˜) ์‹) vs cube(x) โ‰ก x * x * x (์ด๋ฆ„ ์žˆ์Œ)
  • ์ž ๊น ์“ธ ํ•จ์ˆ˜์ธ๋ฐ ๊ตณ์ด ์ด๋ฆ„ ๋ถ™์ด๊ธฐ ์‹ซ์„ ๋•Œ
  • numbers = [1, 2, 3]
  • doubled = map(lambda x: x * 2, numbers) # ํ•จ์ˆ˜ ์ด๋ฆ„ ์—†์ด ์‚ฌ์šฉ
  • ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ๋•Œ
  • ์ด๋ฆ„ ์—†์ด ํ•จ์ˆ˜๋ฅผ ๋ฐ”๋กœ ์ •์˜ํ•ด์„œ ์ „๋‹ฌ ๊ฐ€๋Šฅ
  • ํ•จ์ˆ˜๊ฐ€ ์ผํšŒ์„ฑ์ผ ๋•Œ ๋งค์šฐ ์œ ์šฉ

Formal computation model using lambda expressions โ†’ lambda calculus

  • โ€œ๊ณ„์‚ฐ์„ ํ•จ์ˆ˜๋กœ๋งŒ ํ‘œํ˜„ํ•˜์žโ€๋Š” ์ˆ˜ํ•™์  ๋ชจ๋ธ
  • ๋ชจ๋“  ๊ณ„์‚ฐ์„ ํ•จ์ˆ˜ ์ •์˜์™€ ์ ์šฉ์œผ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ก ์  ๊ธฐ์ดˆ ์ œ๊ณต
  • โ†’ "๊ณ„์‚ฐ์ด๋ผ๋Š” ๊ฑด ๊ฒฐ๊ตญ, ์–ด๋–ค ๊ฐ’์„ ํ•จ์ˆ˜์— ๋„ฃ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ์–ป๋Š” ๊ณผ์ •์ผ ๋ฟ์ด๋‹ค."
  • ๋ชจ๋“  ๊ณ„์‚ฐ์„ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€๋งŒ์œผ๋กœ ์„ค๋ช…ํ•˜๋ ค๊ณ  ํ•จ
  • ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ธฐ
  • ๊ทธ ํ•จ์ˆ˜์— ๊ฐ’์„ ์ ์šฉํ•˜๊ธฐ
  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ์ด๋ก ์  ๋ฟŒ๋ฆฌ
  • Can be typed or untyped
  • Untyped lambda calculus: ๋ชจ๋“  ํ‘œํ˜„์„ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉ
  • Typed lambda calculus: ํƒ€์ž… ์ œ์•ฝ ์กด์žฌ (โ†’ Haskell, ML ๋“ฑ ํ•จ์ˆ˜ํ˜• ์–ธ์–ด๋กœ ๋ฐœ์ „)

Are applied to parameter(s) by placing the parameter(s) after the expression

  • [EX] (ฮป(x)xโˆ—xโˆ—x)(2)(\lambda(x) x * x * x) (2)(ฮป(x)xโˆ—xโˆ—x)(2)
  • = 8
  • ฮป(x)xโˆ—xโˆ—x\lambda(x) x * x * xฮป(x)xโˆ—xโˆ—x๋Š” ์ต๋ช… ํ•จ์ˆ˜
  • (2)๋Š” ์ธ์ž ์ ์šฉ(application)

Functional forms

A higher-order function, or functional form

  • ํ•จ์ˆ˜๋„ ์ˆซ์ž์ฒ˜๋Ÿผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค๋ฉดโ€ฆ ๊ณ ์ฐจํ•จ์ˆ˜
  • Takes functions as parameters
  • Yields a function as its result
  • Or both above
  • ๊ณ ์ฐจ ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ ๋„๊ตฌ
  • ์ฝ”๋“œ๋ฅผ ๋” ์œ ์—ฐํ•˜๊ณ  ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ฆ

Functional composition

  • A functional form that takes two functions as parameters
  • Yields a function whose value is the first actual parameter function
  • applied to the application of the second
  • [EX] Form: h โ‰ก f หš g (หš is operator for function composition)
  • means h(x) โ‰ก f(g(x))
  • for f(x) โ‰ก x + 2, g(x) โ‰ก 3*x, h โ‰ก f หš g yields (3*x) + 2
def compose(f, g):
    return lambda x: f(g(x))

def square(x): return x * x
def add_one(x): return x + 1

new_func = compose(square, add_one)
print(new_func(3)) # ๊ฒฐ๊ณผ: square(add_one(3)) โ†’ square(4) = 16

Apply-to-all

  • A functional form that takes a single function as a parameter
  • Yields a list of values obtained by applying the given function to each element of a list of parameters
  • Form: ฮฑ\alphaฮฑ
  • For h(x) โ‰ก x * x
  • ฮฑ(h,(2,3,4))\alpha(h, (2, 3, 4))ฮฑ(h,(2,3,4)) yields (4, 9, 16)
def h(x):
    return x * x

numbers = [2, 3, 4]
result = list(map(h, numbers))
print(result) # [4, 9, 16]

# with ๋žŒ๋‹ค ํ‘œํ˜„์‹
result = list(map(lambda x: x * x, [2, 3, 4]))

Fundamentals of Functional Programming Languages

Objective of design of FPL

  • Mimic mathematical functions
  • ์ž…๋ ฅ์ด ์ฃผ์–ด์ง€๋ฉด ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ค‘๊ฐ„ ์ƒํƒœ๋‚˜ ๋ณ€์ˆ˜ ์—†์ด ๊ณ„์‚ฐ์ด ์ด๋ค„์ง โ†’ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ณ  ์•ˆ์ „ํ•œ ๊ณ„์‚ฐ
  • The basic process of computation is fundamentally different from imperative language
  • In imperative
  • ์ปดํ“จํ„ฐ์—๊ฒŒ "์–ด๋–ป๊ฒŒ(how)" ๊ณ„์‚ฐํ• ์ง€ ๋ช…๋ น์„ ๋‚ด๋ฆฌ๋Š” ๋ฐฉ์‹
  • Operations are done โ†’ results are stored in variables
  • Management of variable is concern and course of complexity
  • [EX] (x+y)/(a-b)
  • Value of (x+y) is computed and stored while (a-b) is evaluated
  • In FPL
  • "๋ฌด์—‡์„(what)" ๊ณ„์‚ฐํ• ์ง€๋ฅผ ์„ ์–ธ(declare)ํ•˜๋Š” ๋ฐฉ์‹
  • ๊ณ„์‚ฐ ์ˆœ์„œ๋‚˜ ์ค‘๊ฐ„ ๋ณ€์ˆ˜์— ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๊ณ , ๋ชจ๋“  ๊ฒƒ์ด ํ‘œํ˜„์‹(expression)์œผ๋กœ ๊ตฌ์„ฑ๋จ
  • [EX] (x+y)/(a-b)
  • ๋ณ€์ˆ˜ ๊ฐ’์ด ์ฃผ์–ด์ง€๋ฉด, ๋‚ด๋ถ€์ ์œผ๋กœ ๊ณ„์‚ฐ์ด ์ž๋™์œผ๋กœ ์ง„ํ–‰๋จ ์ค‘๊ฐ„ ์ƒํƒœ ์—†์ด, ๊ฒฐ๊ณผ๋งŒ ๋ฐ˜ํ™˜๋จ
  • Variables and assignments are not necessary (as in math)
  • ์ˆ˜ํ•™์—์„œ x = 3๋ผ๊ณ  ํ•˜๋ฉด, x๋Š” ์ ˆ๋Œ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ๊ฐ’
  • ๋ฐ˜๋ฉด ๋ช…๋ นํ˜• ์–ธ์–ด์—์„  x = x + 1 ๊ฐ™์€ ๋ฌธ์žฅ์ด ๊ฐ€๋Šฅ
  • ํ•จ์ˆ˜ํ˜• ์–ธ์–ด์—์„  ๊ฐ’์ด ํ•œ ๋ฒˆ ์ •ํ•ด์ง€๋ฉด ์ ˆ๋Œ€ ๋ฐ”๋€Œ์ง€ ์•Š์Œ โ†’ ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ ์ƒ์ˆ˜์— ๊ฐ€๊นŒ์›€
  • โ†’ Freeing programmer from concerns of memory cells
  • Iterative construct โ†’ recursion
  • ์ƒํƒœ(state)๋ฅผ ๋ฐ”๊พธ๋Š” ๋ฐ˜๋ณต ๋Œ€์‹  ์ˆœ์ˆ˜ํ•œ ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ ํ•ด๊ฒฐ
  • Referential Transparency - Evaluation of a function always produces the same result given the same parameters
  • ๊ฐ™์€ ์ž…๋ ฅ โ†’ ํ•ญ์ƒ ๊ฐ™์€ ์ถœ๋ ฅ
  • ์™ธ๋ถ€ ์ƒํƒœ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์Œ = ์ˆœ์ˆ˜ ํ•จ์ˆ˜
  • ์ด๋Ÿฐ ์„ฑ์งˆ์ด ์žˆ์œผ๋ฉด ๋””๋ฒ„๊น…์ด ํ›จ์”ฌ ์‰ฝ๊ณ , ํ…Œ์ŠคํŠธ๋„ ๊ฐ„๋‹จํ•จ
  • Makes semantics of FPL far simpler than imperative
  • ๋ณ€์ˆ˜ ๋ณ€ํ™” ์—†์Œ, ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋งŒ ์กด์žฌ, ์ƒํƒœ๋„ ์—†์Œ
  • A set of primitive functions are provided (smaller number is good)
  • FPL์€ ๋ณดํ†ต ์ ์€ ์ˆ˜์˜ ๊ธฐ๋ณธ ํ•จ์ˆ˜๋งŒ ์ œ๊ณตํ•˜๊ณ , ๊ทธ๊ฑธ ์กฐํ•ฉํ•ด์„œ ๋ณต์žกํ•œ ๋™์ž‘์„ ๋งŒ๋“ค๊ฒŒ ์œ ๋„ํ•จ.

Original Lisp

The first functional language

  • LISt Processing์˜ ์ค„์ž„๋ง โ†’ ๋ฆฌ์ŠคํŠธ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์•„์ฃผ ์ข‹์Œ
  • No longer represents the latest design concepts for functional languages
  • Represent well the fundamental concepts of functional programming
  • LISP๋Š” ๋žŒ๋‹ค ํ‘œํ˜„์‹, ์žฌ๊ท€, ํ•จ์ˆ˜ ์ž์ฒด๋ฅผ ๊ฐ’์ฒ˜๋Ÿผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ์‹ ๋“ฑ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ ๊ฐœ๋…์„ ๋‹ด๊ณ  ์žˆ์Œ
  • Therefore worthy of study
  • All LISP dialects include imperative-language features
  • Imperative-style variables, assignment statements, and iteration

Lisp Data Types and Structures

Data object types: originally only atoms and lists

  • (1) Atom (์›์ž): ์ชผ๊ฐค ์ˆ˜ ์—†๋Š” ๋‹จ์ผ ๊ฐ’
  • ์ˆซ์ž, ๊ธฐํ˜ธ(symbol), ๋ฌธ์ž ๋“ฑ์ด ํฌํ•จ
  • ์˜ˆ: A, 42, 'helloโ€
  • (2) List (๋ฆฌ์ŠคํŠธ)
  • ๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ์›์ž์™€ ๋ฆฌ์ŠคํŠธ์˜ ์ง‘ํ•ฉ
  • ๋ฆฌ์ŠคํŠธ ์•ˆ์—๋Š” ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ๋„ ํฌํ•จ๋  ์ˆ˜ ์žˆ์–ด (์ค‘์ฒฉ ๊ฐ€๋Šฅ)
  • List form: parenthesized collections of sublists and/or atoms
  • [EX] (A (B C) D (E (F G)))
  • ์ฒซ ๋ฒˆ์งธ ์›์†Œ: A (atom)
  • ๋‘ ๋ฒˆ์งธ: (B C) (sublist)
  • ์„ธ ๋ฒˆ์งธ: D (atom)
  • ๋„ค ๋ฒˆ์งธ: (E (F G)) (sublist ์•ˆ์— ๋˜ sublist)

Originally, Lisp was a typeless language

  • ์ดˆ๊ธฐ Lisp์—์„œ๋Š” ๋ชจ๋“  ๊ฐ’์ด ๋ฆฌ์ŠคํŠธ ๋˜๋Š” atom์œผ๋กœ ํ‘œํ˜„๋จ
  • ์ •์ˆ˜, ๋ฌธ์ž์—ด, ๋ถˆ๋ฆฌ์–ธ ๊ฐ™์€ ํƒ€์ž… ๊ตฌ๋ถ„์ด ๋ช…ํ™•ํ•˜์ง€ ์•Š์•˜์Œ
  • ๋‚˜์ค‘์— Common Lisp ๋“ฑ์—์„œ ๋‹ค์–‘ํ•œ ํƒ€์ž…์ด ์ถ”๊ฐ€๋จ (์˜ˆ: integer, float, string ๋“ฑ)
  • Lisp lists are stored internally as singlelinked lists
  • (A B C)
  • [A] โ†’ [B] โ†’ [C] โ†’ NIL

Lisp Interpretation

The first requirement for the universal LISP function

  • The first Lisp interpreter appeared only as a demonstration of the universality of the computational capabilities of the notation
  • Lisp์˜ ํ•ต์‹ฌ ์ฒ ํ•™ ์ค‘ ํ•˜๋‚˜์ธ ์ฝ”๋“œ์™€ ๋ฐ์ดํ„ฐ์˜ ๋™์ผํ•œ ํ‘œํ˜„ (Code-as-Data)
  • Notation allowing functions to be expressed in the same way data expressed
  • [EX] (A B C) , [ex] (+ 2 3) ; โ†’ 5
  • [1] ๋ฐ์ดํ„ฐ๋กœ ํ•ด์„: Can be interpreted as a simple list of three atoms
  • ์›์ž A, B, C๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ
  • [2] ์ฝ”๋“œ๋กœ ํ•ด์„: Can be interpreted as if function named A is applied to two parameters
  • ํ•จ์ˆ˜ A๊ฐ€ B์™€ C๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ
  • ์ฝ”๋“œ๋„ ๋ฐ์ดํ„ฐ์ฒ˜๋Ÿผ
  • ํ”„๋กœ๊ทธ๋žจ์ด ์ž๊ธฐ ์ž์‹ ์„ ๋ถ„์„ํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Œ โ†’ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ€๋Šฅ
  • (eval '(+ 1 2))
  • ์ปดํŒŒ์ผ๋Ÿฌ, ์ธํ„ฐํ”„๋ฆฌํ„ฐ, ๋งคํฌ๋กœ ์‹œ์Šคํ…œ ๋“ฑ์„ ์–ธ์–ด ๋‚ด๋ถ€์—์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ

Specified in a prefix list form (Cambridge Polish or Cambridge prefix)

  • ์ˆ˜์‹์ด๋‚˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ•ญ์ƒ ์•ž์—์„œ๋ถ€ํ„ฐ ์ฝ์Œ
  • (function_name argument1 โ€ฆ argumentn)
  • ์•ž์— ํ•จ์ˆ˜ ์ด๋ฆ„์ด ์˜ค๋Š” ํ˜•์‹(prefix)์„ ์”€
  • (+ 5 7)
  • (+ 3 4 7 6)
  • Lambda notation is used to specify functions and function definitions
  • ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ๋•Œ LAMBDA๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉ
  • (function_name (LAMBDA (arg1 ... argn) expression))
  • ์ด๊ฑด "์ด๋ฆ„์ด ์žˆ๋Š” ํ•จ์ˆ˜"๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ์‹
  • (define square (lambda (x) (* x x)))
  • square๋ผ๋Š” ์ด๋ฆ„์˜ ํ•จ์ˆ˜ ์ •์˜
  • (lambda (x) (* x x)) โ†’ x๋ฅผ ๋ฐ›์•„์„œ x * x๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜
  • ((lambda (x) (* x x)) 5) ; โ†’ 25
  • ์ด๋ฆ„ ์—†๋Š” ํ•จ์ˆ˜๋„ ๊ฐ€๋Šฅ
  • ํ•จ์ˆ˜์— ์ด๋ฆ„ ์—†์ด ๋ฐ”๋กœ ์ •์˜ํ•˜๊ณ , 5๋ฅผ ๋„ฃ์–ด ์‹คํ–‰ํ•จ

All LISP structures, both data and code, were called S-expression

  • S-expressions became LISPโ€™s only notation
  • ๊ด„ํ˜ธ๋กœ ๋‘˜๋Ÿฌ์‹ธ์ธ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ
  • ์ด ์•ˆ์— ๋ฐ์ดํ„ฐ๋“  ํ•จ์ˆ˜ ํ˜ธ์ถœ์ด๋“  ๋‹ค ํ‘œํ˜„
  • (+ 2 3) ; ํ•จ์ˆ˜ ํ˜ธ์ถœ, ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜ ํ˜ธ์ถœ
  • (A (B C) D) ; ๋ฐ์ดํ„ฐ ๋ฆฌ์ŠคํŠธ, ๋‹จ์ˆœํ•œ ๋ฆฌ์ŠคํŠธ ๋ฐ์ดํ„ฐ

McCarthy successfully developed a universal function (EVAL) that could evaluate any other function

  • ์–ด๋–ค ์ฝ”๋“œ๋“  ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜
  • Implementation of EVAL could serve as a LISP interpreter
  • EVAL์€ S-expression์„ ๋ฐ›์•„์„œ ์‹ค์ œ๋กœ ์‹คํ–‰์‹œํ‚ด
  • Lisp ์ฝ”๋“œ ์ž์ฒด๋ฅผ ์ž…๋ ฅ๊ฐ’์œผ๋กœ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•จ
  • (eval '(+ 2 3)) ; โ†’ 5
  • ์กด ๋งค์นด์‹œ(John McCarthy)๋Š” ์ด EVAL ํ•จ์ˆ˜ ํ•˜๋‚˜๋กœ ๋ชจ๋“  Lisp ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ฆ โ†’ Lisp ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ž์ฒด๋ฅผ Lisp๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ
  • Before 1975, dialects of LISP are dynamic scoping
  • Contemporary dialects use static scoping or can choose static or dynamic.

Origins of Scheme

A mid-1970s dialect of Lisp, designed to be a cleaner, more modern, and simpler version than the contemporary dialects of Lisp

  • Uses only static scoping (์ด์ „ Lisp์€ ๋™์  ์Šค์ฝ”ํ•‘ ์‚ฌ์šฉ)
  • Functions are first-class entities
  • A first-class object refers to an object that supports all operations that are generally applicable to other objects
  • They can be the values of expressions and elements of lists
  • They can be assigned to variables, passed as parameters, and returned from functions

The Scheme Interpreter

Scheme์˜ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋™์ž‘ ๋ฐฉ์‹

  • In interactive mode, the Scheme interpreter is an infinite read-evaluate-print loop (REPL)
  • โ†’ Read (์ฝ๊ธฐ) โ†’ Eval (ํ‰๊ฐ€) โ†’ Print (์ถœ๋ ฅ) โ†’ ๋ฐ˜๋ณต
  • โ†’ ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์‹(expression)์„ ์ฝ๊ณ , ํ‰๊ฐ€ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œ ๋’ค ๋‹ค์‹œ ๋Œ€๊ธฐ
  • This form of interpreter is also used by Python and Ruby (ํ˜„๋Œ€ ์Šคํฌ๋ฆฝํŠธ ์–ธ์–ด)
  • Expressions are interpreted by the function EVAL (์ฃผ์–ด์ง„ ์‹์„ ํ•ด์„ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ)
  • Literals evaluate to themselves
  • If typing a number to interpreter โ†’ simply display the number
  • EVAL์€ Scheme ๋‚ด๋ถ€์—์„œ ํ‘œํ˜„์‹์„ ๋ฐ›์•„ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
  • Scheme์—์„œ๋Š” ์ฝ”๋“œ๋„ ์ผ์ข…์˜ ๋ฆฌ์ŠคํŠธ ๊ตฌ์กฐ(S-expression)์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋ฆฌ์ŠคํŠธ๋กœ ํ‘œํ˜„๋œ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
  • > (eval '(+ 2 3))
  • 5
  • ๋ณดํ†ต์€ ์ง์ ‘ eval์„ ์ž์ฃผ ์“ฐ์ง„ ์•Š์ง€๋งŒ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ์œ ์šฉ
  • ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž์—ด์„ ์ฝ”๋“œ๋กœ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์„ ๋•Œ
  • ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ (์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์ฝ”๋“œ)์„ ๊ตฌํ˜„ํ•  ๋•Œ
  • REPL์„ ๊ตฌํ˜„ํ•  ๋•Œ (eval์ด ํ•ต์‹ฌ ํ•จ์ˆ˜)

Primitive Function Evaluation

Primitive Function Evaluation์˜ ๊ณผ์ •

  • [์ธ์žํ‰๊ฐ€] Parameters are evaluated, in no particular order
  • โ†’ ์ธ์ž ๊ฐ„ ๋ถ€์ž‘์šฉ(side effect)์ด ์žˆ๋‹ค๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Œ
  • โ†’ ์ˆœ์ˆ˜ ํ•จ์ˆ˜ ์‚ฌ์šฉ์ด ๊ถŒ์žฅ๋จ
  • [์ „๋‹ฌ] The values of the parameters are passed into the function body
  • ์ „๋‹ฌ๋œ ์ธ์ž ๊ฐ’์„ ์ด์šฉํ•ด ํ•จ์ˆ˜ ๋กœ์ง ์ˆ˜ํ–‰
  • [๋ถ„๋ฌธ ์‹คํ–‰] The function body is evaluated
  • [๋ฐ˜ํ™˜] The value of the last expression in the body is the value of the function
  • Scheme์—์„œ๋Š” ๋งˆ์ง€๋ง‰ ์‹์˜ ๊ฒฐ๊ณผ๊ฐ’์ด ์ „์ฒด ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’

Primitive Functions & LAMBDA Expressions

Primitive Arithmetic Functions: +, -, * , /, MODULO, ROUND, MAX, MIN, LOG, SIN, and SQRT

  • ์ ‘๋‘(prefix) ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉ
  • If no parameters are given for *, 1 is returned (๊ณฑ์…‰์˜ ํ•ญ๋“ฑ์›)
  • If no parameters are given to +, 0 is returned (๋ง์…ˆ์˜ ํ•ญ๋“ฑ์›)
  • Use uppercase letters for all reserved words and predefined functions
ExpressionValueExpressionValue
4242(SQRT 9)3.0
(* 3 7)21(MODULO 17 5)2
(+ 5 7 8)20(ROUND 3.6)4
(โˆ’ 5 6)โˆ’1(MAX 3 8 2 9 1)9
(โˆ’ 15 7 2)6(MIN 3 8 2 9 1)1
(โˆ’ 24 (* 4 3))12(SIN (/ PI 2))1.0

Lambda Expressions

  • Nameless function actually includes the word LAMBDA
  • Form is based on ฮป\lambdaฮป notation
  • [EX] (LAMBDA (x) (* x x))
  • ์ด ์‹ ์ž์ฒด๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด(function object)๋ฅผ ๋ฐ˜ํ™˜
  • Lambda expressions can be applied to parameters
  • [EX] ((LAMBDA (x) (* x x)) 7)
  • x is called a bound variable (never change after being bound)
  • Lambda expressions can have any number of parameters
  • [EX] (LAMBDA (a b x) (+ (* a x x) (* b x)))

Special Form Function: DEFINE

DEFINE - Two forms:

  • The evaluation process (interpreted by EVAL) for DEFINE is different!
  • [1] To bind a symbol to an expression (์–ด๋–ค ์ด๋ฆ„์— ๊ฐ’์„ "์ •์˜"ํ•˜๋Š” ๋ฐฉ์‹)
  • [EX] (DEFINE pi 3.141593)
  • pi๋Š” 3.141593์— ๋ฐ”์ธ๋”ฉ๋จ
  • [EX of use] (DEFINE two_pi (* 2 pi))
  • two_pi๋Š” (* 2 pi)์˜ ํ‰๊ฐ€ ๊ฒฐ๊ณผ์ธ 6.283186์— ๋ฐ”์ธ๋”ฉ๋จ
  • These symbols are not variables โ€“ they are like the names bound by Javaโ€™s final declarations
  • โ†’ ๋‹ค์‹œ DEFINEํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€
  • [2] To bind names to lambda expressions (LAMBDA is implicit)
  • ์ด ๊ฒฝ์šฐ LAMBDA๊ฐ€ ์•”๋ฌต์ ์œผ๋กœ ํฌํ•จ๋จ
  • [EX] (DEFINE (square x) (* x x)) โ†’ (DEFINE square (LAMBDA (x) (* x x)))
  • [EX of use] (square 5)
  • The first parameter is never evaluated
  • The second parameter is evaluated and bound to the first parameter

Output Functions

Usually not needed

  • Because interpreter always displays the result of a function evaluated at the top level (not nested)
  • ๋‹จ, ์ด๊ฑด ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ๋งŒ ํ•ด๋‹น๋จ. ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ถœ๋ ฅ์„ ์›ํ•  ๊ฒฝ์šฐ ๋ช…์‹œ์  ์ถœ๋ ฅ ํ•จ์ˆ˜๊ฐ’์ด ํ•„์š”ํ•จ
  • Scheme has PRINTF, which is similar to the printf function of C
  • ๋Œ€๋ถ€๋ถ„์˜ ํ‘œ์ค€ Scheme์—๋Š” ์—†๊ณ , ์ผ๋ถ€ ๊ตฌํ˜„์—์„œ๋งŒ ์ง€์›

Display and Read Functions

DISPLAY function: simply prints the arguments

  • (DISPLAY 21) 21
  • (DISPLAY "hello") hello

READ function: enter what we type on the keyboard

  • (DEFINE x (READ)) 7

Numeric Predicate Functions

A predicate function is one that returns a Boolean value

  • #T (or #t) is true and #F (or #f) is false
  • (= 3 3) ; โ†’ #t
  • (< 3 5) ; โ†’ #t
  • (> 7 10) ; โ†’ #f
  • Sometimes () is used for false
  • ์ฃผ์š” ํŒ๋ณ„ ์—ฐ์‚ฐ์ž (=, <>, >, <, >=, <=)
  • ์ˆซ์ž ๊ด€๋ จ ํŒ๋ณ„ ํ•จ์ˆ˜ (EVEN?, ODD?, ZERO?, NEGATIVE?)
  • Notice that the names for all predefined predicate functions that have words for names end with question marks
  • The NOT function inverts the logic of a Boolean expression
  • (NOT #t) ; โ†’ #f
  • (NOT #f) ; โ†’ #t
  • (NOT (EVEN? 3)) ; โ†’ #t
  • (DEFINE x 11)
  • (= x 11) returns #T
  • (> x 11) returns ()
  • (< x 15) return #T
  • (EVEN? x) returns ()
  • (ODD? x) returns #T

Control Flow

Selection- the special form, IF (two-way selector function)

  • (IF predicate then_exp else_exp)
(IF (> 3 2) 'yes 'no)
; returns yes

(DEFINE x 7)
(DEFINE y 10)
(IF (> x y)
    (- x y)
    (- y x))
; returns 3

(DEFINE (test x)
  (IF (>= x 70)
      (DISPLAY "pass")
      (DISPLAY "fail")))
(test 75) ; returns pass

(DEFINE (factorial n)
  (IF (<= n 1)
      1
      (* n (factorial (โˆ’ n 1)))))

Recall from Chapter 8 the COND function (multiple selection):

(DEFINE (admissionfee age)
  (COND
    ((<= age 6) 0)
    ((< age 60) 5000)
    (ELSE 2500)))
(admissionfee 65) ; returns 2500

(DEFINE (leap? year)
  (COND
    ((ZERO? (MODULO year 400)) #T)
    ((ZERO? (MODULO year 100)) #F)
    (ELSE (ZERO? (MODULO year 4)))))
(leap? 2024) ; returns #T

List Functions

QUOTE - takes one parameter; returns the parameter without evaluation

  • QUOTE is required because the Scheme interpreter, named EVAL, always evaluates parameters to function applications before applying the function
  • QUOTE is used to avoid parameter evaluation when it is not appropriate
  • ํ‰๊ฐ€๋ฅผ ๋ง‰๊ณ , ์›๋ž˜ ๋ชจ์–‘ ๊ทธ๋Œ€๋กœ ๋„˜๊น€
  • QUOTE can be abbreviated with the apostrophe prefix operator
  • '(A B) is equivalent to (QUOTE (A B))
  • ๋งŒ์•ฝ QUOTE ์—†์ด ๊ทธ๋ƒฅ (A B)๋ฅผ ์“ฐ๋ฉด, Scheme์€ A๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ B์— ์ ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•จ โ†’ ์˜ค๋ฅ˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ
  • Recall that CAR, CDR, and CONS were covered in Chapter 6

CAR and CDR operations:

  • (CAR '(A B C)) returns A

  • (CAR โ€ฒ((A B) C D)) returns (A B)

  • (CAR โ€ฒA) is an error because A is not a list

  • (CAR '(A)) returns A

  • Names lies in the first implementation (IBM 704) of LISP

  • IBM 704๋Š” ํ•˜๋‚˜์˜ ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ๋‘ ๊ฐœ์˜ ํ•„๋“œ๋กœ ๋‚˜๋ˆ„์–ด ์‚ฌ์šฉ

  • CAR (contents of the address part of a register) - ํ—ค๋“œ๋ฅผ ํ‘œํ˜„

  • CDR (contents of the decrement part of a register) - ๊ผฌ๋ฆฌ๋ฅผ ํ‘œํ˜„

  • (CAR '()) is an error

  • (CDR '(A B C)) returns (B C)

  • (CDR โ€ฒ((A B) C D)) returns (C D)

  • (CDR โ€ฒA) is an error

  • (CDR โ€ฒ(A)) returns ()

  • (CDR '()) is an error

Combine CAR and CDR

  • (DEFINE (second a_list) (CAR (CDR a_list)))
  • (second '(A B C)) returns B
  • [ํ•จ์ˆ˜ ํ•ฉ์„ฑ ์ถ•์•ฝํ˜• (Built-in Compositions)] Some of the most commonly used functional compositions in Scheme are built in as single functions
  • (CAAR x) is equivalent to (CAR(CAR x))
  • (CADR x) is equivalent to (CAR (CDR x))
  • (CADDAR x) is equivalent to (CAR (CDR (CDR (CAR x))))

CONS: inverse of CAR and CDR

  • Two parameters to CONS: CAR and CDR of the new list
  • (CONS (CAR a_list) (CDR a_list)) returns a_list
  • (CONS 'A '()) returns (A)
  • (CONS 'A '(B C)) returns (A B C)
  • (CONS โ€ฒ() โ€ฒ(A B)) returns (() A B)
  • (CONS โ€ฒ(A B) โ€ฒ(C D)) returns ((A B) C D)

LIST is a function for building a list from any number of parameters

  • (LIST โ€ฒapple โ€ฒorange โ€ฒgrape) returns (apple orange grape)
  • = (CONS 'apple (CONS 'orange (CONS 'grape '())))
  • ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” CONS๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ์ค‘์ฒฉํ•ด์„œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Œ

Predicate Function

Predicate Function: EQ? (๊ฐ์ฒด์˜ ๋™์ผ์„ฑ(identity)์„ ๋น„๊ต)

  • EQ? takes two expressions as parameters (usually two atoms);
  • It returns #T if both parameters have the same pointer value; otherwise #F
  • ๋‘ ๊ฐ์ฒด๊ฐ€ ๋™์ผํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ(= ํฌ์ธํ„ฐ)๋ฅผ ์ฐธ์กฐํ•˜๋Š”๊ฐ€๋ฅผ ๊ฒ€์‚ฌ
  • (EQ? 'A 'A) yields #T
  • (EQ? 'A 'B) yields #F
  • (EQ? 'A '(A B)) yields #F
  • (EQ? '(A B) '(A B)) yields #T or #F
  • ์„œ๋กœ ๊ตฌ์กฐ๊ฐ€ ๊ฐ™์•„๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด์ผ ์ˆ˜ ์žˆ์Œ (๋ฆฌ์ŠคํŠธ๋Š” ๋งค๋ฒˆ ์ƒˆ๋กœ ์ƒ์„ฑ๋จ)
  • (EQ? 3.4 (+ 3 0.4)) yields #T or #F
  • ๋ถ€๋™์†Œ์ˆ˜์  ์—ฐ์‚ฐ ๊ฒฐ๊ณผ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ฐ™์•„๋„ ๊ฐ์ฒด๋Š” ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ

Predicate Function: EQV?

  • EQ? works for symbolic atoms but does not necessarily work for numeric atoms
  • = predicate works for numeric atoms but not symbolic atoms
  • ๊ฐ’(value)์ด ๊ฐ™์€์ง€๋ฅผ ๋น„๊ตํ•˜๋Š” predicate ํ•จ์ˆ˜
  • EQV? is like EQ?, except that it works for both symbolic and numeric atoms
  • EQ?์™€ ๋น„์Šทํ•˜์ง€๋งŒ, ๋” ์œ ์—ฐํ•˜๊ณ  ๋„“์€ ๋ฒ”์œ„์˜ ํƒ€์ž…์— ๋Œ€ํ•ด ์ž˜ ์ž‘๋™
  • It is a value comparison, not a pointer comparison
  • (EQV? 3 3) yields #T
  • (EQV? 'A 3) yields #F
  • (EQV 3.4 (+ 3 0.4)) yields #T
  • (EQV? 3.0 3) yields #F (floats and integers are different)
  • Primary reason to use EQ? or =
  • Faster than EQV?

Predicate Functions: LIST? and NULL?

  • LIST? takes one parameter;
  • It returns #T if the parameter is a list; otherwise #F
  • x๊ฐ€ ๋ฆฌ์ŠคํŠธ์ธ์ง€ ํ™•์ธ
  • (LIST? '(X Y)) returns #T
  • (LIST? 'X) returns #F ; ๋‹จ์ˆœ ์‹ฌ๋ณผ
  • (LIST? '()) yields #T ; ๋นˆ ๋ฆฌ์ŠคํŠธ๋„ ๋ฆฌ์ŠคํŠธ์ž„
  • NULL? takes one parameter;
  • It returns #T if the parameter is the empty list; otherwise #F
  • x ๊ฐ€ ๋นˆ ๋ฆฌ์ŠคํŠธ์ธ์ง€ ํ™•์ธ
  • (NULL? '(A B)) returns #F
  • (NULL? '()) returns #T
  • (NULL? 'A) returns #F ; ์‹ฌ๋ณผ์€ ๋ฆฌ์ŠคํŠธ๋„, ๋นˆ ๋ฆฌ์ŠคํŠธ๋„ ์•„๋‹˜
  • (NULL? '(())) yields #F ; ์š”์†Œ๋กœ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ง„ ๋ฆฌ์ŠคํŠธ โ†’ ๋น„์–ด์žˆ์ง€ ์•Š์Œ

Example Scheme Function: sort

(DEFINE (insert atm lst)
  (COND
    ((NULL? lst) (CONS atm '()))
    ((< atm (CAR lst)) (CONS atm lst))
    (ELSE (CONS (CAR lst) (insert atm (CDR lst))))))

(DEFINE (sort lst)
  (if (NULL? lst)
      '()
      (insert (CAR lst) (sort (CDR lst)))))

(sort '(3 7 5 1 9)) ; returns (1 3 5 7 9)

    1. (insert atm lst)
  • ๋ชฉ์ : ์ˆซ์ž ํ•˜๋‚˜ atm์„ ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ lst์— ์•Œ๋งž์€ ์œ„์น˜์— ์‚ฝ์ž…

  • ์ž‘๋™ ๋ฐฉ์‹:

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด โ†’ ๋‹จ๋… ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค๊ธฐ

  • atm์ด ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ์›์†Œ๋ณด๋‹ค ์ž‘์œผ๋ฉด โ†’ ์•ž์— ๋„ฃ๊ธฐ

  • ์•„๋‹ˆ๋ฉด โ†’ ๋ฆฌ์ŠคํŠธ์˜ ๋‚˜๋จธ์ง€์— ์žฌ๊ท€์ ์œผ๋กœ ์‚ฝ์ž…

    1. (sort lst)
  • ๋ชฉ์ : ๋ฆฌ์ŠคํŠธ lst๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ

  • ์ž‘๋™ ๋ฐฉ์‹:

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด โ†’ ๋นˆ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜

  • ์•„๋‹ˆ๋ฉด โ†’ ์ฒซ ์›์†Œ๋Š” ๋นผ์„œ sort๋กœ ์ •๋ ฌํ•œ ๋‚˜๋จธ์ง€์— insertํ•จ์ˆ˜๋กœ ์‚ฝ์ž…

Example C Function: sort

// insert: ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ์— value ์‚ฝ์ž…
Node* insert(int value, Node* lst) {
    if (lst == NULL || value < lst->value) {
        Node* new_node = create_node(value);
        new_node->next = lst;
        return new_node;
    } else {
        lst->next = insert(value, lst->next);
        return lst;
    }
}

// sort: ์‚ฝ์ž… ์ •๋ ฌ
Node* sort(Node* lst) {
    if (lst == NULL) return NULL;
    Node* sorted = sort(lst->next);
    return insert(lst->value, sorted);
}

    1. insert(int value, Node* lst)
  • ๋ชฉ์ : ์ˆซ์ž ํ•˜๋‚˜ value์„ ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ lst์— ์•Œ๋งž์€ ์œ„์น˜์— ์‚ฝ์ž…

  • ์ž‘๋™ ๋ฐฉ์‹:

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ๊ฑฐ๋‚˜, value๊ฐ€ ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ ์›์†Œ๋ณด๋‹ค ์ž‘์œผ๋ฉด โ†’ ์•ž์— ๋„ฃ๊ธฐ

  • ์•„๋‹ˆ๋ฉด โ†’ ๋ฆฌ์ŠคํŠธ์˜ ๋‚˜๋จธ์ง€์— ์žฌ๊ท€์ ์œผ๋กœ ์‚ฝ์ž…

    1. sort(Node* lst)
  • ๋ชฉ์ : ๋ฆฌ์ŠคํŠธ lst๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ

  • ์ž‘๋™ ๋ฐฉ์‹:

  • ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด โ†’ ๋นˆ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜

  • ์•„๋‹ˆ๋ฉด โ†’ ์ฒซ ์›์†Œ๋Š” ๋นผ์„œ sort๋กœ ์ •๋ ฌํ•œ ๋‚˜๋จธ์ง€์— insertํ•จ์ˆ˜๋กœ ์‚ฝ์ž…

Example Scheme Function: member

(DEFINE (member atm a_list)
  (COND
    ((NULL? a_list) #F) ; ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด ์ฐพ์„ ์ˆ˜ ์—†์Œ
    ((EQ? atm (CAR a_list)) #T) ; ์ฒซ ์›์†Œ๊ฐ€ ๊ฐ™์œผ๋ฉด ์ฐพ์•˜์Œ
    (ELSE (member atm (CDR a_list))))) ; ์•„๋‹ˆ๋ฉด ๋‚˜๋จธ์ง€์—์„œ ๊ณ„์† ์ฐพ๊ธฐ

(member 'B '(A B C)) ; returns #T
(member 'B '(A C D E)) ; returns #F

// ๋ฆฌ์ŠคํŠธ์— ํ•ด๋‹น ๊ฐ’์ด ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌ (member ํ•จ์ˆ˜)
bool member(const char* atom, Node* list) {
    if (list == NULL) return false;
    if (strcmp(atom, list->value) == 0)
        return true;
    return member(atom, list->next);
}

Example Scheme Function: equalsimp

  • equalsimp takes two simple lists as parameters; returns #T if the two simple lists are equal; #F otherwise
(DEFINE (equalsimp list1 list2)
  (COND
    ((NULL? list1) (NULL? list2)) ; ๋‘˜ ๋‹ค ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฉด ๊ฐ™์Œ
    ((NULL? list2) #F) ; list1๋งŒ ๋น„์—ˆ๊ณ  list2๋Š” ์•ˆ ๋น„์—ˆ์œผ๋ฉด ๋‹ค๋ฆ„
    ((EQ? (CAR list1) (CAR list2)) ; ์ฒซ ์›์†Œ๊ฐ€ ๊ฐ™์œผ๋ฉด
     (equalsimp (CDR list1) (CDR list2))) ; ๋‚˜๋จธ์ง€๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ๋น„๊ต
    (ELSE #F))) ; ์ฒซ ์›์†Œ๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋‹ค๋ฆ„

  • *Simple list: ๋ฆฌ์ŠคํŠธ ์•ˆ์— ๋˜ ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์—†๋Š” ๊ตฌ์กฐ. ๋ชจ๋“  ์š”์†Œ๊ฐ€ ์›์ž(atom) ๋˜๋Š” ์‹ฌ๋ณผ(symbol) ๊ฐ™์€ ๋‹จ์ˆœํ•œ ๊ฐ’
// equalsimp ํ•จ์ˆ˜: ๋‘ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊ฐ™์€์ง€ ๋น„๊ต
bool equalsimp(Node* list1, Node* list2) {
    if (list1 == NULL && list2 == NULL)
        return true;
    if (list1 == NULL || list2 == NULL)
        return false;
    if (strcmp(list1->value, list2->value) != 0)
        return false;
    return equalsimp(list1->next, list2->next);
}

Example Scheme Function: equal

  • equal takes two general lists as parameters;
  • Complex than simple list case because sublist must be traced (๋ฆฌ์ŠคํŠธ ์•ˆ์— sublist๊ฐ€ ์žˆ์–ด๋„ ๋น„๊ต ๊ฐ€๋Šฅ)
  • Returns #T if the two lists are equal; #F otherwise (๋‘ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋ชจ์–‘๊ณผ ๊ฐ’ ๋ชจ๋‘ ๊ฐ™์€์ง€๋ฅผ ํŒ๋‹จ)
(DEFINE (equal list1 list2)
  (COND
    ((NOT (LIST? list1)) (EQ? list1 list2)) ; Handle the situation where either of the parameters is an atom instead of a list
    ((NOT (LIST? list2)) #F)
    ((NULL? list1) (NULL? list2)) ; Handle the situation where one or both lists are empty
    ((NULL? list2) #F)
    ((equal (CAR list1) (CAR list2)) ; ์ฒซ ์›์†Œ ๋น„๊ต
     (equal (CDR list1) (CDR list2))) ; ๋‚˜๋จธ์ง€ ๋น„๊ต
    (ELSE #F)))

  • equal is equivalent to EQUAL? (but slower than EQ? and EQV?)

Example Scheme Function: append

  • append takes two lists as parameters;
  • Returns the first parameter list with the elements of the second parameter list appended at the end
  • (append '(A B) '(C D R)) returns (A B C D R)
  • (append '((A B) C) '(D (E F))) returns ((A B) C D (E F))
(DEFINE (append list1 list2)
  (COND
    ((NULL? list1) list2) ; list1์ด ๋น„์—ˆ์œผ๋ฉด, list2 ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
    (ELSE (CONS (CAR list1) ; list1์˜ ์ฒซ ์›์†Œ๋ฅผ ์œ ์ง€ํ•˜๊ณ 
                (append (CDR list1) list2))))) ; ๋‚˜๋จธ์ง€(list1์˜ ๊ผฌ๋ฆฌ)์™€ list2๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ์ด์–ด๋ถ™์ž„

Example Scheme Function: guess

  • guess takes two lists as parameters;
  • Yields a simple list that contains the common elements of its two parameter lists
  • ๋‘ ๋ฆฌ์ŠคํŠธ ๊ฐ„์˜ ๊ณตํ†ต ์š”์†Œ๋ฅผ ์ฐพ์•„๋‚ด๋Š” ํ•จ์ˆ˜
(DEFINE (guess list1 list2)
  (COND
    ((NULL? list1) '()) ; list1์ด ๋น„์—ˆ์œผ๋ฉด ๊ณตํ†ต ์š”์†Œ๋„ ์—†์œผ๋ฏ€๋กœ ๋นˆ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜
    ((member (CAR list1) list2) ; list1์˜ ์ฒซ ์›์†Œ๊ฐ€ list2์— ํฌํ•จ๋˜๋ฉด
     (CONS (CAR list1) (guess (CDR list1) list2))) ; ๊ทธ ์›์†Œ๋ฅผ ๊ฒฐ๊ณผ์— ์ถ”๊ฐ€ํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์žฌ๊ท€ ํ˜ธ์ถœ
    (ELSE (guess (CDR list1) list2)))) ; ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉด ๊ทธ๋ƒฅ ๋‚˜๋จธ์ง€์—์„œ ๊ณ„์† ํƒ์ƒ‰

(guess '(A B C D) '(B D F)) ; โ†’ (B D)

Example Scheme Function: adder

  • adder takes lists as parameters;
  • Yields sum of the lists (์ˆซ์ž๋กœ๋งŒ ๊ตฌ์„ฑ๋œ ๋ฆฌ์ŠคํŠธ์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜)
(DEFINE (adder a_list)
  (COND
    ((NULL? a_list) 0) ; ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด ํ•ฉ์€ 0
    (ELSE (+ (CAR a_list) (adder (CDR a_list)))))) ; ์ฒซ ์›์†Œ์™€ ๋‚˜๋จธ์ง€์˜ ํ•ฉ์„ ๋”ํ•จ

(adder '(1 2 3)) returns 6
(adder '(1 (2) 3)) returns error

int adder(Node* list) {
    if (list == NULL)
        return 0;
    return list->value + adder(list->next);
}

  • Resolved! (์ค‘์ฒฉ ๋ฆฌ์ŠคํŠธ(nested list)๊นŒ์ง€ ๋ชจ๋‘ ์ˆœํšŒํ•ด์„œ ์•ˆ์— ์žˆ๋Š” ์ˆซ์ž๋ฅผ ์ „๋ถ€ ํ•ฉ์‚ฐ)
(DEFINE (adder a_list)
  (COND
    ((NULL? a_list) 0) ; ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด 0 ๋ฐ˜ํ™˜
    ((LIST? (CAR lst)) ; ์ฒซ ์›์†Œ๊ฐ€ ๋ฆฌ์ŠคํŠธ์ด๋ฉด
     (+ (adder (CAR lst)) (adder (CDR lst)))) ; ๊ทธ ๋ฆฌ์ŠคํŠธ์™€ ๋‚˜๋จธ์ง€๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ๋”ํ•จ
    (ELSE (+ (CAR a_list) (adder (CDR a_list)))))) ; ์ˆซ์ž๋ฉด ๊ทธ๋Œ€๋กœ ๋”ํ•˜๊ณ  ๋‚˜๋จธ์ง€ ์žฌ๊ท€ ํ˜ธ์ถœ

int adder(Node* list) {
    if (list == NULL) return 0;
    Element e = list->value;
    int head_sum = 0;
    if (e.type == NUMBER) {
        head_sum = e.number;
    } else if (e.type == LIST) {
        head_sum = adder(e.list); // ์ค‘์ฒฉ ๋ฆฌ์ŠคํŠธ ์žฌ๊ท€ ํ˜ธ์ถœ
    }
    return head_sum + adder(list->next);
}

Example Scheme Function: LET

  • LET is actually shorthand for a LAMBDA expression applied to a parameter
  • LET์€ ์ด๋ฆ„์— ๊ฐ’์„ ์ž„์‹œ๋กœ ๋ฐ”์ธ๋”ฉํ•˜๊ณ , ๊ทธ ๊ฐ’์„ ํ‘œํ˜„์‹ ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ตฌ์กฐ
  • ์‹ค์ œ๋กœ๋Š” LAMBDA + ์ฆ‰์‹œ ํ˜ธ์ถœ๋กœ ๊ตฌํ˜„๋œ ๋ฌธ๋ฒ•์  ํŽธ์˜(syntactic sugar)
  • (LET ((alpha 7)) (* 5 alpha)) ; โ†’ 35
  • is the same as: ((LAMBDA (alpha) (* 5 alpha)) 7)
  • alpha๋ผ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์•„ (* 5 alpha)๋ฅผ ์ˆ˜ํ–‰ ์ธ์ž 7์ด alpha์— ์ „๋‹ฌ๋จ
  • LET creates a local scope in which names are temporarily bound to the values of expressions
  • These names can then be used in the evaluation of another expression, but they cannot be rebound to new values in LET.
  • LET ๋‚ด๋ถ€์—์„œ ๋ฐ”์ธ๋”ฉ๋œ ์ด๋ฆ„์€ ๋‹ค์‹œ SET! ๋“ฑ์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†์Œ
  • ๋ณ€์ˆ˜ ์žฌ์ •์˜๋Š” ๋ถˆ๊ฐ€๋Šฅ: ๋‹จ์ˆœํžˆ ๊ฐ’ ํ•˜๋‚˜๋ฅผ ์ผ์‹œ์ ์œผ๋กœ ํ• ๋‹นํ•  ๋ฟ

LET Example

  • ์ด์ฐจ๋ฐฉ์ •์‹์˜ ๊ทผ์˜ ๊ณต์‹์„ ์ด์šฉํ•ด ๋‘ ๊ทผ์„ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜
(DEFINE (quadratic_roots a b c)
  (LET (
        ; ํŒ๋ณ„์‹์˜ ์ œ๊ณฑ๊ทผ์„ 2a๋กœ ๋‚˜๋ˆˆ ๋ถ€๋ถ„
        (root_part_over_2a
         (/ (SQRT (- (* b b) (* 4 a c))) (* 2 a)))
        (minus_b_over_2a (/ (- 0 b) (* 2 a))))
    ; ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ๋ฐ˜ํ™˜: ๋‘ ๊ทผ
    (LIST (+ minus_b_over_2a root_part_over_2a)
          (- minus_b_over_2a root_part_over_2a))))

Tail Recursion in Scheme

  • Definition: A function is tail recursive if its recursive call is the last operation in the function โ†’ ์ฆ‰, ์žฌ๊ท€ ํ˜ธ์ถœ ๋’ค์— ์•„๋ฌด ์—ฐ์‚ฐ๋„ ๋‚จ์ง€ ์•Š์•„์•ผ ํ•จ
  • A tail recursive function can be automatically converted by a compiler to use iteration, making it faster
  • ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์Šคํƒ ํ”„๋ ˆ์ž„์„ ์œ ์ง€ํ•˜์ง€ ์•Š๊ณ , ๋ฐ˜๋ณต๋ฌธ์ฒ˜๋Ÿผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ โ†’ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„ ์—†์Œ, ์„ฑ๋Šฅ ํ–ฅ์ƒ, ์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ ๋ฐฉ์ง€
  • Scheme language definition requires that Scheme language systems convert all tail recursive functions to use iteration
  • Scheme ์ปดํŒŒ์ผ๋Ÿฌ ๋˜๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” tail call์„ ์ž๋™์œผ๋กœ ์ตœ์ ํ™”ํ•ด์•ผ ํ•จ
(DEFINE (member atm a_list)
  (COND
    ((NULL? a_list) #F)
    ((EQ? atm (CAR a_list)) #T)
    (ELSE (member atm (CDR a_list)))))

  • Example of rewriting a function to make it tail recursive, using helper a function
; Original
(DEFINE (factorial n)
  (IF (<= n 0)
      1
      (* n (factorial (- n 1)))))

; Tail recursive
(DEFINE (factorial n)
  (DEFINE (facthelper n factpartial)
    (IF (<= n 0)
        factpartial
        (facthelper (- n 1) (* n factpartial))))
  (facthelper n 1))

Functional Form - Composition

  • If h is the composition of f and g, h(x) = f(g(x)) (๋‘ ํ•จ์ˆ˜ f์™€ g๋ฅผ ํ•ฉ์ณ์„œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜ h๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ)
(DEFINE (g x) (* 3 x)) ; g(x) = 3 * x
(DEFINE (f x) (+ 2 x)) ; f(x) = x + 2
(DEFINE (h x) (f (g x))) ; ํ•จ์ˆ˜ ํ•ฉ์„ฑ
(DEFINE (h x) (+ 2 (* 3 x))) ; (The composition) ; f(g(x)) ์ง์ ‘ ๊ณ„์‚ฐ

  • In Scheme, the functional composition function compose can be written:
  • ํ•ฉ์„ฑ์šฉ ๊ณ ์ฐจ ํ•จ์ˆ˜ compose๋ฅผ ์ง์ ‘ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Œ
(DEFINE (compose f g)
  (LAMBDA (x)
    (f (g x))))

  • compose๋Š” ๋‘ ํ•จ์ˆ˜๋ฅผ ๋ฐ›์•„์„œ ์ƒˆ๋กœ์šด ํ•ฉ์„ฑ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜

  • (compose f g)๋Š” ์ˆ˜ํ•™์ ์œผ๋กœ f(g(x))์™€ ๊ฐ™์Œ

  • ((compose CAR CDR) '((a b) c d)) yields c โ†’ CADR

  • CDR โ†’ ((a b) c d)์˜ ๊ผฌ๋ฆฌ: (c d)

  • CAR โ†’ (c d)์˜ ์ฒซ ์›์†Œ: c

  • ๊ฒฐ๊ณผ: c โ†’ ์ฆ‰, CADR

  • ((compose CDR CAR) '((a b) c d)) yields (b) โ†’ CDAR

  • CAR โ†’ ((a b) c d)์˜ ์ฒซ ์›์†Œ: (a b)

  • CDR โ†’ (a b)์˜ ๊ผฌ๋ฆฌ: (b)

  • ๊ฒฐ๊ณผ: (b) โ†’ ์ฆ‰, CDAR

  • (DEFINE (third a_list)((compose CAR (compose CDR CDR)) a_list)) is equivalent to CADDR

  • (compose CDR CDR) โ†’ CDDR

  • compose CAR ... โ†’ CAR(CDDR(x)) โ†’ ์ฆ‰, CADDR

Functional Form โ€“ Apply-to-All

  • Apply to All - one form in Scheme is map
  • Applies the given function to all elements of the given list
  • ๋ฆฌ์ŠคํŠธ์˜ ๋ชจ๋“  ์š”์†Œ์— ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ด์„œ ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ํ•จ์ˆ˜
(DEFINE (map fun a_list)
  (COND ((NULL? a_list) '()) ; ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด ๋นˆ ๋ฆฌ์ŠคํŠธ ๋ฐ˜ํ™˜
        (ELSE (CONS (fun (CAR a_list)) ; ํ˜„์žฌ ์›์†Œ์— ํ•จ์ˆ˜ ์ ์šฉ
                    (map fun (CDR a_list)))))) ; ๋‚˜๋จธ์ง€ ๋ฆฌ์ŠคํŠธ์— ์žฌ๊ท€์ ์œผ๋กœ map

  • (map (LAMBDA (num) (* num num num)) '(3 4 2 6)) yields (27 64 8 216)
  • (cons 27 (cons 64 (cons 8 (cons 216 '())))) โ†’ (27 64 8 216)

FOLD โ€“ ๋ˆ„์  ๊ณ„์‚ฐ

(DEFINE (FOLD F BASE A_LIST)
  (COND
    ((NULL? A_LIST) BASE) ; ๋ฆฌ์ŠคํŠธ ๋ โ†’ ๋ˆ„์ ๊ฐ’ ๋ฐ˜ํ™˜
    (ELSE (F (CAR A_LIST) (FOLD F BASE (CDR A_LIST)))))) ; ์žฌ๊ท€์ ์œผ๋กœ ๋ˆ„์  ๊ณ„์‚ฐ

(FOLD + 0 '(1 2 3 4)) ; โ†’ 10
(FOLD * 1 '(2 3 4)) ; โ†’ 24

FILTER โ€“ ์กฐ๊ฑด์— ๋งž๋Š” ๊ฐ’๋งŒ ๊ฑธ๋Ÿฌ๋‚ด๋Š” ํ•จ์ˆ˜

(DEFINE (FILTER PRED A_LIST)
  (COND
    ((NULL? A_LIST) '()) ; ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ์œผ๋ฉด ์ข…๋ฃŒ
    ((PRED (CAR A_LIST))
     (CONS (CAR A_LIST) (FILTER PRED (CDR A_LIST)))) ; ํ˜„์žฌ ์›์†Œ๊ฐ€ ์กฐ๊ฑด ๋งŒ์กฑ โ†’ ํฌํ•จ + ๋‚˜๋จธ์ง€ ์žฌ๊ท€
    (ELSE (FILTER PRED (CDR A_LIST))))) ; ์กฐ๊ฑด ๋ถˆ๋งŒ์กฑ โ†’ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

(FILTER EVEN? '(1 2 3 4)) ; โ†’ (2 4)

Functions That Build Code

It is possible in Scheme to define a function that builds Scheme code and requests its interpretation

  • Scheme์€ โ€œ์ฝ”๋“œ๋ฅผ ๋ฐ์ดํ„ฐ์ฒ˜๋Ÿผโ€ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด
  • ๊ทธ๋ž˜์„œ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ , ๊ทธ ์ฝ”๋“œ๋ฅผ ํ•ด์„ํ•ด์„œ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Œ.
  • Scheme์ด ๊ฐ€์ง„ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋Šฅ๋ ฅ ์ค‘ ํ•˜๋‚˜
  • This is possible because the interpreter is a user-available function, EVAL
  • Scheme์—์„œ๋Š” ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ๋ฆฌ์ŠคํŠธ(S-expression) ํ‘œํ˜„
  • ํ”„๋กœ๊ทธ๋žจ ์•ˆ์—์„œ ์ฝ”๋“œ๋ฅผ ์กฐ๋ฆฝํ•˜๊ณ , EVAL์„ ํ†ตํ•ด ๊ทธ๊ฑธ ์‹ค์ œ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Œ
(DEFINE (make-def name val)
  (LIST 'DEFINE name val))

  • ํ•จ์ˆ˜ make-def๋Š” ์‹ค์ œ๋กœ ์ •์˜๋ฌธ(DEFINE x 42)๋ฅผ "๋ฐ์ดํ„ฐ"๋กœ ๋งŒ๋“  ๋‹ค์Œ, EVAL์„ ํ†ตํ•ด ์‹คํ–‰์‹œ์ผœ โ†’ ์‹ค์ œ๋กœ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•จ
  • (make-def 'x 42) ; โ†’ '(DEFINE x 42)
  • (EVAL (make-def 'x 42) (interaction-environment))
  • x ; โ†’ 42

Adding a List of Numbers

The parameter is a list of numbers to be added;

  • Cannot apply + directly on the list, because + can take only atomic parameters
  • Write a function that repeatedly adds the CAR of the list to the sum of its CDR, using recursion
(DEFINE (adder a_list)
  (COND
    ((NULL? a_list) 0)
    (ELSE (+ (CAR a_list) (adder (CDR a_list))))))

  • adder inserts a + operator and evaluates the resulting list
  • Use CONS to insert the atom + into the list of numbers.
  • Be sure that + is quoted to prevent evaluation
  • Submit the new list to EVAL for evaluation
(DEFINE (adder a_list)
  (COND
    ((NULL? a_list) 0)
    (ELSE (EVAL (CONS '+ a_list)))))

  • ๋ฆฌ์ŠคํŠธ์˜ ์ˆซ์ž๋“ค์„ ๋‹ค ๋”ํ•ด์•ผ ํ•˜๋Š”๋ฐ, + ์—ฐ์‚ฐ์ž๋ฅผ ๋ฆฌ์ŠคํŠธ ์•ž์— ๋ถ™์—ฌ์„œ ํ•˜๋‚˜์˜ Scheme ์ฝ”๋“œ๋กœ ๋งŒ๋“  ๋’ค, ๊ทธ๊ฑธ EVAL๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹
์ตœ๊ทผ ์ˆ˜์ •: 26. 6. 12. ์˜คํ›„ 3:28
Contributors: kmbzn, Claude Sonnet 4.6
Prev
11. Concurrency
Next
13. FPL (2)

BUILT WITH

CloudflareNode.jsGitHubGitVue.jsJavaScriptVSCodenpm

All trademarks and logos are property of their respective owners.
ยฉ 2026 kmbzn ยท MIT License