19. public class Person
{
public string Name { get; set; }
public void Drink(string alcohol)
{
Console.WriteLine($"{this.name} drink {alcohol}");
}
}
class Program
{
static void Main(string[] args)
{
Person wonJun = new Person { Name = "이원준" };
wonJun.Drink("소주");
}
}
20. public class Person
{
public string Name { get; set; }
public static string Drink(string name, string alcohol) => $"{name} drink {alcohol}";
public static string Drink(Person p, string alcohol) => Drink(p.Name, alcohol);
public void Drink(string alcohol)
{
var drinkString = Person.Drink(this, alcohol);
Console.WriteLine(drinkString);
}
}
class Program
{
static void Main(string[] args)
{
Person wonJun = new Person { Name = "이원준" };
wonJun.Drink("소주");
}
}
21. public class Person
{
public string Name { get; set; }
public static string Drink(string name, string alcohol) => $"{name} drink {alcohol}";
public static string Drink(Person p, string alcohol) => Drink(p.Name, alcohol);
public void Drink(string alcohol)
{
var drinkString = Person.Drink(this, alcohol);
Console.WriteLine(drinkString);
Name = "리원준";
}
}
class Program
{
static void Main(string[] args)
{
Person wonJun = new Person { Name = "이원준" };
wonJun.Drink("소주");
wonJun.Drink("소주");
}
}
22. public class Person
{
public string Name { get; init; }
public static string Drink(string name, string alcohol) => $"{name} drink {alcohol}";
public static string Drink(Person p, string alcohol) => Drink(p.Name, alcohol);
public void Drink(string alcohol)
{
var drinkString = Person.Drink(this, alcohol);
Console.WriteLine(drinkString);
Name = "리원준";
}
}
class Program
{
static void Main(string[] args)
{
Person wonJun = new Person { Name = "이원준" };
wonJun.Drink("소주");
wonJun.Drink("소주");
}
}
33. data class Alcohol(val name:String, val abv:Double)
data class Person(val name:String,val
drinkHistory:List<Alcohol>)
fun main(args: Array<String>) {
val soju = Alcohol(name = "소주",abv = 17.6)
val (nameOfSoju,_) = soju
println(nameOfSoju)
}
Destructuring
34. class User
{
public int X { get; set; }
public int Y { get; set; }
// Blah Blah
}
void GetUserXY(User u, out int x, out int y)
{
x = u.X;
y = u.Y;
}
var user = new User { X = 10, Y = 20 };
int x;
GetUserXY(user, out x, out _);
35. class User
{
public int X { get; set; }
public int Y { get; set; }
// Blah Blah
}
void GetUserXY(User u, out int x, out int y)
{
x = u.X;
y = u.Y;
}
var user = new User { X = 10, Y = 20 };
int x;
GetUserXY(user, out x, out _);
36. class User
{
public int X { get; set; }
public int Y { get; set; }
// Blah Blah
}
var user = new User { X = 10, Y = 20 };
int x = GetUserXY(user).X;
struct Point
{
public int X { get; set; }
public int Y { get; set; }
}
Point GetUserXY(User u)
{
return new Point { X = u.X, Y = u.Y };
}
37. class User
{
public int X { get; set; }
public int Y { get; set; }
// Blah Blah
}
(int,int) GetUserXY(User u)
{
return (u.X, u.Y);
}
var user = new User { X = 10, Y = 20 };
(int x, _) = GetUserXY(user);
39. Java Stream.. C# LINQ …
• 결국 리스트처리를 위한 함수!
• 리스트를 위한 함수가 왜 필요한가?
우리가 리스트를 거지같이 다루니까!
40. val list = listOf(1,2,3,4,5)
for (i in 0..list.count())
println(list[i])
41.
42. var even = mutableListOf<Int>()
for (i in list)
if ( i % 2 == 0)
even.add(i)
43. val list = listOf(1,2,3,4,5)
for (i in 0..list.count())
println(list[i])
var even = mutableListOf<Int>()
for (i in list)
if ( i % 2 == 0)
even.add(i)
44. val list = listOf(1,2,3,4,5)
for (i in 0..list.count())
println(list[i])
val even = mutableListOf<Int>()
for (i in list)
if ( i % 2 == 0)
even.add(i)
인덱스 사이즈가 안 맞으면 어떡하지?
누가 Sum 을 바꿔버리면 어떡하지
Mutable 에 계속 Add 해야하나?
45. val list = listOf(1,2,3,4,5)
for (i in 0..list.count())
println(list[i])
var even = mutableListOf<Int>()
for (i in list)
if ( i % 2 == 0)
even.add(i)
다 돌고 싶다!
다 더하고 싶다!
Even 만 뽑고 싶다!
46. 다 돌고 싶다!
다 더하고 싶다!
Even 만 뽑고 싶다!val even = list.filter { it%2 == 0 }
list.forEach(::println)
val sum = list.reduce{x,y-> x + y}
val sum = list.sum()
47. For Each는 똑같은거 아닌가요?
• Switch 문도 Jump 하는데 Go To를 안 쓰는 이유는?
• For Each 는 신뢰 할 만하다!
• “모든 요소 순회” 라는 개념의 추상화
• Index 기반의 For 문을 코드가 변경 되도 신뢰 할만한가?
auto list = new vector<int>()
//.....
for (int i = 0 ; i < list.length ; i++)
{
//어쩌고 저쩌고
}
i--;
48. 선생님 저는 다 돌기 싫은데요?
• 앞에 100개 만 돌고 싶은데요?
• 뒤에 100개 만 돌고 싶은데요?
• 짝수 부분만 돌고 싶은데요?
미리 잘라 놓고 도세요..
49. val list = listOf(1,2,3,4,5)
val listTake100 = list.subList(0,100)
val sum =listTake100.sum()
println(sum)
잘못 잘라도 에러는 여기서 납니다
55. fun f (x:Int) = x + 5
fun g (x:Int) = x + 10
fun h (x:Int) = x + 20
val x = 0
val x2 = f(x)
val x3 = g(x2)
val result1 = h(x3)
fun composed (x: Int) = h(g(f(x)))
val result2 = composed(x)
56. fun f (x:Int) = x + 5
fun g (x:Int) = x + 10
fun h (x:Int) = x + 20
val x = 0
val x2 = f(x)
val x3 = g(x2)
val result1 = h(x3)
fun composed (x: Int) = h(g(f(x)))
val result2 = composed(x)
let f x = x+5
let g x = x+10
let h x = x+20
let x = 0
let composed = f >> g >> h
let result1 = composed x
let result2 = x |> f |> g |> h
57. fun f (x:Int) = x + 5
fun g (x:Int) = x + 10
fun h (x:Int) = x + 20
val x = 0
val x2 = f(x)
val x3 = g(x2)
val result1 = h(x3)
fun composed (x: Int) = h(g(f(x)))
val result2 = composed(x)
let f x = x+5
let g x = x+10
let h x = x+20
let x = 0
let composed = f >> g >> h
let result1 = composed x
let result2 = x |> f |> g |> h
새로운 함수를 만들면
Compose
함수를 연속적으로 호출하면
Pipe
cat /etc/passwd | grep mail
58. val 꽃빛서리 = We.filter { it.drinkHistory.any { (name,_) ->name == "꽃빛서리"
} }
.map { it.name }
val 꽃빛서리People = We.filter { it.drinkHistory.any { (name,_) ->name ==
"꽃빛서리" } }
val 꽃빛서리PeopleName = 꽃빛서리People.map { it.name }
X
59. But…. Method 는…
• 근본적으로 순수하지 않음
this
We.filter { blah blah
}
.map { blah blah }
.map { blah blah }
.reduce { blah blah
}
.Drink()
List<Person> 의 Method 만 사용가능
64. val WeDrinkAlcohols = We.flatMap { it.drinkHistory }.distinct()
val YangJuAlcohols =
listOf<Alcohol>(Alcohol(name = "예거",abv = 40.0),Alcohol(name = "보드카",abv
40.0))
val WeDrinkAlcoholsWithoutYangJu =
WeDrinkAlcohols.filterNot{YangJuAlcohols.contains(it)}
???
파라미터
람다
65. val WeDrinkAlcohols = We.flatMap { it.drinkHistory }.distinct()
val YangJuAlcohols =
listOf<Alcohol>(Alcohol(name = "예거",abv = 40.0),Alcohol(name = "보드카",abv
40.0))
fun isContain (list:List<Alcohol>, alcohol: Alcohol) = list.contains(alcohol)
val WeDrinkAlcoholsWithoutYangJu3 = WeDrinkAlcohols.filterNot(isContainInYangJu
val WeDrinkAlcoholsWithoutYangJu2 =
WeDrinkAlcohols.filterNot{isContain(YangJuAlcohols,it)}
???
파라미터
66. val WeDrinkAlcohols = We.flatMap { it.drinkHistory }.distinct()
val YangJuAlcohols =
listOf<Alcohol>(Alcohol(name = "예거",abv = 40.0),Alcohol(name = "보드카",abv
40.0))
fun isContain (list:List<Alcohol>, alcohol: Alcohol) = list.contains(alcohol)
val isContainInYangJu = {alcohol : Alcohol -> isContain(YangJuAlcohols,alcohol)
val WeDrinkAlcoholsWithoutYangJu = WeDrinkAlcohols.filterNot(isContainInYangJu)
캡쳐
67. val WeDrinkAlcohols = We.flatMap { it.drinkHistory }.distinct()
val YangJuAlcohols =
listOf<Alcohol>(Alcohol(name = "예거",abv = 40.0),Alcohol(name = "보드카",abv
40.0))
fun isContain (list:List<Alcohol>, alcohol: Alcohol) = list.contains(alcohol)
val isContainInYangJu = {alcohol : Alcohol -> isContain(YangJuAlcohols,alcohol)
val WeDrinkAlcoholsWithoutYangJu = WeDrinkAlcohols.filterNot(isContainInYangJu)
불변
//… YangJuAlcohols 가 변경되면?
68. Joy Of Clojure 에서 발쵀
스승과의 다음 산책 때 안톤은 스승에게 잘 보일 요량으로 이렇게 말했다.
“스승님. 열심히 수양을 닦으면서 객체야 말로 가난한 사람들의
진정한 클로저(Closure) 라는것을 이해하게 되었습니다.“
그러자 스승은 막대기로 안톤의 머리를 때리더니 이렇게 말했다.
“대체 언제 깨달으려 하느냐? 클로저는 가난한 사람의 객체이니라.”
그 순간 안톤은 이치를 깨닫게 되었다. – 안톤 반 스토라텐
70. • 저장 할 수도 있고
• 넘길 수도 있고
• 리턴할 수도 있습니다.
Function is Value
val isContainInYangJu = {alcohol : Alcohol ->
isContain(YangJuAlcohols,alcohol)}
val WeDrinkAlcoholsWithoutYangJu =
WeDrinkAlcohols.filterNot(isContainInYangJu)
71. sealed class Liquid
data class Alcohol(val name:String, val abv:Double) : Liquid()
data class SoftDrink (val name:String): Liquid()
data class Methanol (val name:String) : Liquid()
data class Person(val name:String,val drinkHistory:List<Alcohol>)
fun HangOver(person: Person):Unit = println ( "${person.name} feels a hangover :(" )
fun Die(person: Person):Unit = println ( "${person.name} is dead :(" )
fun WhatToDoAfterDrinking(liquid: Liquid):(Person)->Unit = when (liquid) {
is Alcohol -> ::HangOver
is SoftDrink -> {_ -> Unit}
is Methanol -> ::Die
}
val Soju = Alcohol(name = "소주",abv = 17.6)
val AfterDrink = WhatToDoAfterDrinking(Soju)
AfterDrink(Lee)
72. enum class LiquidType{
Alcohol,
SoftDrink,
Methanol
}
val FuntionMap = mapOf<LiquidType,(Person)-
>Unit>(
LiquidType.Alcohol to ::HangOver,
LiquidType.SoftDrink to {_->Unit},
LiquidType.Methanol to ::Die
)
val AfterDrink = FuntionMap[LiquidType.Methanol] ?: {_->Unit}
AfterDrink(Lee)
77. fun YesResponse1() = 1
fun YesResponse2() = 2
fun YesResponse3() = 3
fun NoResponse() = Unit
fun main(args: Array<String>) {
val Response = listOf
(YesResponse1(),YesResponse2(),NoResponse(),NoResponse(),YesResponse3())
val ResponseWithoutUnit = Response.filterNot { it is Unit }.map { it as Int }
ResponseWithoutUnit.forEach(::println)
List[T]
Option[T]
78. Functional
Functional Programming은 대입문 없이 프로그래밍 하는것 by 엉클밥
불변 순수함수
Reliable regardless of time
Reliable regardless of Status
Composable 높은 추상화
선언적 쓰기 쉽다
More Safe (적어도 나보단)
Thread Safe
Testable
견고한 프로그램
유지보수가 쉬워짐
80. For Functional Study
• https://fsharpforfunandprofit.com/
• http://clojure.or.kr/docs/clojure-and-gof-design-patterns.html
• 클로저 프로그래밍의 즐거움
• 스칼라로 배우는 함수형 프로그래밍 (일명 빨간책)
• 한국에서 검색하려면 Haskell / Scala