NML 프로그래밍 소개 2004년 9월 9일 신재호 <netj@ropas.snu.ac.kr> 서울대학교 컴퓨터공학부 - 2004년 봄, 4190.102A 수업에서 김재황님이 사용했던 것을 다듬은 자료입니다.

Slides:



Advertisements
Similar presentations
Ⅰ. 연산자 Ⅱ. 제어 구조. 연산자 : 할당 연산자 - 사용자가 정의한 변수에 임의의 값을 저장하는 기능 strvar = strVar1+ “ Hello ”
Advertisements

Copyright © 2006 The McGraw-Hill Companies, Inc. 프로그래밍 언어론 2nd edition Tucker and Noonan 5 장 타입 “ 타입은 컴퓨터 프로그래밍의 효소이다 ; 프로그래밍은 타입을 통해 소화할만한 것이 된다.” 로빈.
1 구조체 윤 홍 란 컴퓨터 프로그래밍 2 구조체 정의  구조체란 ? o 서로 다른 형의 변수들을 하나로 묶어주는 mechanism. (cf. 배열 : 같은 형의 변수들을 하나로 묶어주는 mechanism) o 예 : 카드의.
이진 나무 구조 강윤섭 2008년 5월 23일.
목 차 C# 언어 특징 .NET 프레임워크 C# 콘솔 프로그램 C# 윈도우 프로그램 실습 프로그래밍세미나 2.
2장. 프로그램의 기본 구성. 2장. 프로그램의 기본 구성 2-1"Hello, World!" 들여다 보기 /* Hello.c */ #include int main(void) { printf("Hello, World! \n"); return 0;
Power Java 제3장 이클립스 사용하기.
최윤정 Java 프로그래밍 클래스 상속 최윤정
C 프로그래밍 I.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
컴퓨터 프로그래밍 기초 [Final] 기말고사
자료 구조: Chapter 3 (2)구조체, 포인터
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
제15장 파일 입출력 문자열을 출력하는 여러가지 방법 (15-2쪽) 문자열만 처리하는 입출력 함수
제 6장. 생성자와 소멸자 학기 프로그래밍언어및실습 (C++).
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express Slide 1 (of 13)
5장. 참조 타입.
Dynamic Memory and Linked List
8장 함수 함수의 필요성 라이브러리 함수와 사용자 정의 함수 함수의 정의, 원형, 호출 배열을 함수 인자로 전달 재귀호출.
컴퓨터 프로그래밍 기초 #02 : printf(), scanf()
C++ Espresso 제12장 템플릿.
Tail-recursive Function, High-order Function
자료구조: CHAP 4 리스트 (3) 순천향대학교 컴퓨터공학과 하 상 호.
프로그래밍 랩 – 7주 리스트.
14장. 포인터와 함수에 대한 이해.
공학컴퓨터프로그래밍 Python 염익준 교수.
C#.
C 프로그래밍 C언어 (CSE2035) (Chap11. Derived types-enumerated, structure, and union) (1-1) Sungwook Kim Sogang University Seoul, Korea Tel:
Method & library.
사용자 함수 사용하기 함수 함수 정의 프로그램에서 특정한 기능을 수행하도록 만든 하나의 단위 작업
어서와 C언어는 처음이지 제14장.
3장 상수 변수 기본 자료형 키워드와 식별자 상수와 변수 기본 자료형 형변환 자료형의 재정의.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
19. 함수 포인터와 void 포인터.
3장. 변수와 연산자 교안 : 전자정보통신 홈페이지 / 커뮤니티/ 학술세미나
6장 데이터 타입(4) 순천향대학교 컴퓨터공학부 하 상 호.
Chapter6 : JVM과 메모리 6.1 JVM의 구조와 메모리 모델 6.2 프로그램 실행과 메모리 6.3 객체생성과 메모리
에어 조건문.
컴퓨터 프로그래밍 기초 - 10th : 포인터 및 구조체 -
2장. 변수와 타입.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
자바 5.0 프로그래밍.
김선균 컴퓨터 프로그래밍 기초 - 7th : 함수 - 김선균
8주차: Strings, Arrays and Pointers
메모리 타입 분석을 통한 안전하고 효율적인 메모리 재사용
6.4 타입 검사 (Type Checking).
컴퓨터 프로그래밍 기초 [01] Visual Studio 설치 및 사용방법
Fucntion 요약.
조 병 규 Software Quality Lab. 한 국 교 통 대 학 교
제 15 강 문자와 코드 shcho.pe.kr.
Scheme ML Review & Preview 재귀와 반복(recursion and iteration)
4장. 데이터 표현 방식의 이해. 4장. 데이터 표현 방식의 이해 4-1 컴퓨터의 데이터 표현 진법에 대한 이해 n 진수 표현 방식 : n개의 문자를 이용해서 데이터를 표현 그림 4-1.
05. General Linear List – Homework
[INA240] Data Structures and Practice
프로그램분석 어떻게하나 (quick/tiny)
Lecture 02 프로그램 구조 및 문법 Kwang-Man Ko
7주차: Functions and Arrays
구조체(struct)와 공용체(union)
16장. 변수, 연산자, 사용자 정의 함수 변수 배열과 객체 연산자 함수.
Numerical Analysis Programming using NRs
실습과제 (변수와 자료형, ) 1. 다음 작업 (가), (나), (다)를 수행하는 프로그램 작성
1장 C 언어의 개요 C 언어의 역사와 기원 C 언어의 특징 프로그램 과정 C 프로그램 구조 C 프로그램 예제.
제 29 강 스트링(string) 다루기 s a i s . s T i h t g r i n.
29장. 템플릿과 STL 01_ 템플릿 02_ STL.
어서와 C언어는 처음이지 제21장.
SNU 컴퓨터의 기초 월 14:00-16:00 43동101호 ropas. snu. ac
 6장. SQL 쿼리.
수업 내용 수업 목표 강의 내용 강의 계획서 교과서 및 참고도서 평가 방법 수강생의 학습 방법 제안 강의자료 사이트
6장 데이터 타입(5) 순천향대학교 컴퓨터공학부 하 상 호.
6 객체.
Presentation transcript:

nML 프로그래밍 소개 2004년 9월 9일 신재호 <netj@ropas.snu.ac.kr> 서울대학교 컴퓨터공학부 - 2004년 봄, 4190.102A 수업에서 김재황님이 사용했던 것을 다듬은 자료입니다.

ML의 특징 값 중심의 프로그래밍 언어 small & simple language 작고 간단 type safety 타입 검사를 통해 안전한 프로그램만 수행 polymorphism 타입은 다르지만 하는 일이 같은 함수를 하나로 작성 가능 higher-order function 함수를 다른 값과 구분 없이 사용 abstract data type 다양한 데이터 구조 쉽게 사용 exception handling 예외 상황 관리 구조 module system 정제된 모듈 구조

ML 컴파일러 시스템 Standard ML of New Jersey Objective Caml nML Bell Lab. & Princeton, USA Objective Caml INRIA, France nML SNU/KAIST, Korea 한글 식별자 (identifier) 사용 가능

nML 바로 실행 컴파일러: nml ropas> nml # val x = 1+2;; val x: int = 3 nML 컴파일러 0.92b (2004/04/19) Copyright(c) 2000-2004 KAIST/SNU 프로그램 분석 시스템 연구단 (과기부 창의적 연구진흥사업 1998-2003) http://ropas.snu.ac.kr/n Objective Caml 3.04 코드를 기반으로 작성 # val x = 1+2;; val x: int = 3 # x+1;; val it: int = 4 # #use “file.n”;; ... Unix, MS Windows 에서 수행 가능 http://ropas.snu.ac.kr/n

nML 컴파일러: nmlc 컴파일 그리고 수행 의존 순서대로 분리 컴파일 자동 Makefile 생성 ropas> nmlc file.n ropas> a.out 의존 순서대로 분리 컴파일 ropas> nmlc -c a.n ropas> nmlc -c b.n ropas> nmlc -o a.out a.cmo b.cmo 자동 Makefile 생성 ropas> nmakegen ropas> make ropas> run - 모듈 이름은 모두 달라야 한다. - 모듈로 포장한 것들만 다른 파일에서 쓸 수 있다.

값 중심의 프로그래밍? 값은 변하지 않는다. int fac (int n) { int i, result = 1; for (i=1; i<=n; i++) result = result * i; return result; } fun fac n = if n = 0 then 1 else n * fac (n - 1)

타입 (type) ! 타입이 맞는 프로그램은 오류가 발생하지 않는다. 자동으로 타입을 유추하므로 타입을 명시할 필요가 없다. 1 + 1.0 (X) (real_of_int 1) + 1.0 (O) 자동으로 타입을 유추하므로 타입을 명시할 필요가 없다. fun fac n = if n = 0 then 1 else n * fac (n - 1) 다양한 타입 제공 기본, 튜플, 레코드, 리스트, 사용자 정의 데이터 타입 다형 타입 (polymorphic type)

정의 (이름 붙이기) nML 프로그램은 정의의 모임이다. # val kwang = "이광근";; val kwang: string = "이광근" # val result = let val 둘 = 2 val 셋 = 3 in 둘 * 셋 end;; val result: int = 6 바로 실행 컴파일러에서는 "정의" 대신 "프로그램 식"을 쓰면 편의상 "val it = "를 앞에 붙여 준다.

기본적인 값 정수, 실수, 문자, 문자열, 논리값, ... # (1 + 0xc) % 2 << 2;; # 1.0 + 2.0;; val it: int = 4 val it: real = 3 # 'a';; # "하" ^ "나";; val it: char = 'a' val it: string = "하나" # (true && false) || true;; val it: bool = true # ();; val it: unit = ()

튜플 (tuple) 값들의 모임 # val 하나들 = (1, 1.0, "하나");; val 하나들: int * real * string = (1, 1, "하나") # 하나들.2;; val it: string = "하나" # val (정수, 실수, 문자열) = 하나들;; val 정수: int = 1 val 실수: real = 1 val 문자열: string = "하나"

레코드 (record) 꼬리표 (label) 붙은 값들의 모임 # val 값 = {첫째="이광근", 둘째="nML"};; val 값: {첫째: string, 둘째: string} = {첫째="이광근", 둘째="nML"} # 값.둘째;; val it: string = "nML" # val {첫째=교수님, 둘째=언어} = 값;; val 교수님: string = "이광근" val 언어: string = "nML"

리스트 (list) 같은 타입 값들의 나열 # val 첫째 = [3,5];; val 첫째: int list = [3, 5] # case 셋째 of [] => 0 | h::t => h;; val it: int = 1 [3,5] 는 3::5::[]과 같다.

사용자 정의 데이터 타입 다양한 구조의 값을 정의 사용 가능하다. # type tree = Leaf | Node of int * tree * tree;; # val 나무 = Node(5,Node(6,Leaf,Leaf),Leaf);; val 나무: tree = ... # case 나무 of Leaf => "잎새" | Node _ => "노드";; val it: string = "노드"

타입 정의 타입 줄임말 (type abbreviation) 새로운 데이터 타입 정의 type position = int * int type student = {name: string, id: int, age: int} type ('a, 'b) pair = 'a * 'b 새로운 데이터 타입 정의 type tree = Leaf | Node of int * tree * tree type 'a tree = Leaf | Node of 'a * 'a tree * 'a tree type 'a children = 'a tree * 'a tree and 'a tree = Leaf | Node of 'a * 'a children

함수 이름없는 함수값 함수 정의 fn x => x + 1 fn 0 => true | _ => false fun incr x = x + 1 fun is_zero 0 = true | is_zero _ = false fun fac n = if n = 0 then 1 else n * fac (n - 1) fun f (n, i) = if n = 0 then i else f (n - 1, i * n) and fac n = f (n, 1)

패턴 (pattern) 값을 맞추어 보는 틀 패턴의 종류 val o = ... fun f o = ... | f o = ... fn o => ... | o => ... case ... of o => ... | o => ... ... handle o => ... | o => ... 패턴의 종류 0 "abc“ x _ (o, o, ...) {a=o, b=o, ...} [] o::o [o, o, ...] Leaf Node o 순서대로 맞추어 보다가 맞는 것이 없으면 예외상황 발생 fun fac n = if n = 0 then 1 else n * fac (n - 1) fun fac 0 = 1 | fac n = n * fac (n-1)

다형 타입 함수 (polymorphic function) 여러 타입의 값을 인자로 받는 함수 # fun swap (a, b) = (b, a) val swap: 'a * 'b -> 'b * 'a = <fun> # fun 머리 (h::t) = h | 머리 _ = raise EmptyList val 머리: 'a list -> 'a = <fun> 모든 정의가 다형 타입이 되는 것은 아니다. fun으로 정의한 것은 다형 타입이 될 수 있음을 기억하자. fun f x = ... (O) val f = fn x => x ... (O) val ... = ... (fn x => x) ... (X)

고계도 함수 (higher-order function) 함수가 인자/결과인 함수 # fun add x y = x + y;; // int -> int -> int # val incr = add 1;; // int -> int # incr 6;; val it: int = 7 # fun map f [] = [] | map f (h::t) = f h :: map f t;; // ('a -> 'b) -> 'a list -> 'b list # val map_inc = map (fn x => x + 1);; # map_inc [1, 2, 3];; val it: int list = [2, 3, 4]

예외상황 (exception) 발생하면 처리하는 데까지 빠져 나온다. 오류 처리 (eg. Division_by_zero) 복잡한 구조를 한번에 빠져 나오고 싶을 때 exception Fail exception Error of string if input < 0 then raise Error "Illegal Input" ... handle Fail => ... | Error "Illegal Input" => ...

참조값(reference)과 배열(array) 참조값: 수행 중에 바뀔 수 있는 값 # val count = ref 0;; val count: int ref = ref 0 # count := !count + 1; !count;; val it: int = 1 배열: 같은 타입의 값들의 변경 가능한 모임 # val 배열 = [| 1, 2, 3 |];; val 배열: int array = ... # 배열.[1] <- 5; 배열.[1] + 배열.[2]; val it: int = 8

루프 (loop) while 문 for 문 # val x = ref 0; # while !x < 100 do x += 7 end; !x;; val it: int = 105 for 문 # val x = ref 1;; # for y = 1; y < 6; y + 1 do x *= y end; val it: int = 120 while e1 do e2 end let fun f () = if e1 then (e2; f ()) else () in f () end for x = e1; e2; e3 do e4 end let fun f x = if e2 then (e4; f e3) else () in f e1 end

nML 프로그래밍 소개 2004년 9월 15일 신재호 <netj@ropas.snu.ac.kr> 서울대학교 컴퓨터공학부 - 2004년 봄, 4190.102A 수업에서 김재황님이 사용했던 것을 다듬은 자료입니다.

모듈 (structure) 값, 타입, 예외상황, 모듈 정의의 모임 예 struct ... end structure Name = struct ... end 예 # structure _정수스택 = struct type 원소 = int and t = 원소 list exception _비었다 val 빈것 = [] fun 뿌직 s = case s of []=>raise _비었다 | h::t=>(h,t) ... end;; # _정수스택.빈것;; val it: 'a list = [] # open _정수스택;; # 빈것;; 이름에 대한 규칙: - 값, 타입: 소문자 또는 한글로 시작 - 예외상황, 데이터 구성자, 모듈, 모듈 타입, 모듈 함수: 대문자 또는 _ 로 시작

모듈 타입 (signature) 모듈 기술, 모듈 함수의 입출력 기술 효과: 값, 타입 가리기, 타입 고정시키기 sig ... end signature Name = sig ... end 효과: 값, 타입 가리기, 타입 고정시키기 # signature _대기열_ = sig type 원소 type t exception _비었다 val 빈것: t val 뿌직: t -> 원소 * t ... end;; # signature _정수열_ = _대기열_ where type 원소 = int;; # structure _정수스택 : _정수열_ = struct ... end;; # _정수스택.빈것;; val it: _정수스택.t = <abstr>

모듈 함수 (functor) 모듈을 받아 모듈을 결과로 주는 함수 예 functor F (M1:S1, ..., Mn:Sn): S = struct ... end structure M = F (M1, ..., Mn) 예 functor _빠른큐 (A: _대기열_) : _대기열_ where type 원소 = A.원소 = struct type 원소 = A.원소 type t = A.t * A.t exception _비었다 val 빈것 = (A.빈것, A.빈것) fun 뿌직 (s1, s2) = let val (결과, s1') = A.뿌직 s1 in (결과, (s1', s2)) end handle A._비었다 => ignore (A.뿌직 s2); 뿌직 (A.뒤집기 s2, A.빈것) handle A._비었다 => raise _비었다 ... structure _빠른정수큐 = _빠른큐 (_정수스택)

리스트의 기본적인 연산 1/2 # val 리스트 = [1,2,3,4,5];; 리스트의 기본적인 연산 1/2 # val 리스트 = [1,2,3,4,5];; val 리스트: int list = [1,2,3,4,5] # List.length 리스트;; // 'a list -> int val it: int = 5 # List.hd 리스트;; // 'a list -> 'a val it: int = 1 # List.tl 리스트;; // 'a list -> 'a list val it: int list = [2, 3, 4, 5] # List.nth 리스트 3;; // 'a list -> int -> 'a val it: int = 4

리스트의 기본적인 연산 2/2 # val 앞 = [1,2,3];; # val 뒤 = [4,5];; 리스트의 기본적인 연산 2/2 # val 앞 = [1,2,3];; # val 뒤 = [4,5];; # List.rev 앞;; // 'a list -> 'a list val it: int list = [3, 2, 1] # List.append 앞 뒤;; // 'a list->'a list->'a list val it: int list = [1, 2, 3, 4, 5] # List.flatten [앞, 뒤, [], [6]];; // 'a list list -> 'a list val it: int list = [1, 2, 3, 4, 5, 6]

리스트를 뒤져 보는 연산 1/2 # val 홀수 = [1,3,5,7,9] and 짝수 = [2,4,6,8,10];; 리스트를 뒤져 보는 연산 1/2 # val 홀수 = [1,3,5,7,9] and 짝수 = [2,4,6,8,10];; # val 모두 = 홀수 @ 짝수;; # fun 짝수니 n = n % 2 = 0;; # List.for_all 짝수니 모두;; // ('a -> bool) -> 'a list -> bool val it: bool = false # List.exists 짝수니 모두;; val it: bool = true # List.mem 3 짝수;; // 'a -> 'a list -> bool

리스트를 뒤져 보는 연산 2/2 # val 뒤질것 = [17,9,24,3,2,213,8,9,0,13];; 리스트를 뒤져 보는 연산 2/2 # val 뒤질것 = [17,9,24,3,2,213,8,9,0,13];; # List.find (fn x => x < 10) 뒤질것;; // ('a -> bool) -> 'a list -> 'a val it: int = 9 # List.filter (fn x => x < 10) 뒤질것;; // ('a -> bool) -> 'a list -> 'a list val it: int list = [9, 3, 2, 8, 9, 0] # List.partition (fn x => x < 10) 뒤질것;; // ('a -> bool) -> 'a list -> 'a list * 'a list val it: int list * int list = ([9, 3, 2, 8, 9, 0], [17, 24, 213, 13])

리스트 반복 연산 1/2 # List.iter print_int [1,2,3,4];; 리스트 반복 연산 1/2 # List.iter print_int [1,2,3,4];; // ('a -> unit) -> 'a list -> unit 1234val it: unit = () # List.map string_of_int [1,2,3,4,5];; // ('a -> 'b) -> 'a list -> 'b list val it: string list = ["1", "2", "3", "4", "5"] # List.map (fn i => 10 * i) [1,2,3];; val it: int list = [10, 20, 30]

리스트 반복 연산 1’/2 main() { int l[] = {1,2,3,4,5}; int i, sum = 0; 리스트 반복 연산 1’/2 main() { int l[] = {1,2,3,4,5}; int i, sum = 0; for (i=0; i<5; i++) sum += l[i]; printf("%d", sum); } val _ = let val l = [1,2,3,4,5] val sum = ref 0 in List.iter (fn x => sum += x) l; print_int !sum end

리스트 반복 연산 2/2 # List.fold_left (fn x y => x*10+y) 0 [1,2,3];; 리스트 반복 연산 2/2 # List.fold_left (fn x y => x*10+y) 0 [1,2,3];; // ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a val it: int = 123 # List.fold_right (fn x y => y*10+x) [1,2,3] 0;; // ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b val it: int = 321

리스트 반복 연산 2’/2 main() { int l[] = {1,2,3,4,5}; int i, sum = 0; 리스트 반복 연산 2’/2 main() { int l[] = {1,2,3,4,5}; int i, sum = 0; for (i=0; i<5; i++) sum += l[i]; printf("%d", sum); } val _ = let val l = [1,2,3,4,5] in print_int ( List.fold_left (fn x y => x + y) 0 l) end

웹페이지: http://ropas.snu.ac.kr/n 참고 자료 웹페이지: http://ropas.snu.ac.kr/n 정확한 정의: "프로그래밍 언어 nML" 참고서: "nML 프로그래밍 걸음마" "nML 프로그래밍 언어 참고서" "nML과 함께하는 프로그래밍 여행" 라이브러리: O'Caml 표준 라이브러리 읽을거리: 마이크로 소프트웨어 연재기사