-
Notifications
You must be signed in to change notification settings - Fork 10
/
0215.txt
382 lines (382 loc) · 20.4 KB
/
0215.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
안녕하세요, 포프입니다.
오늘은 진짜 Old한 얘기 하나 해보죠.
goto는 과연 나쁜가?
요즘 이렇게 뭐...
프로그래밍을 배우시는 분들은
당연히 goto같은 것에 대해서 배우지 않을거예요.
아니면 들어도 "goto는 정말 나쁜거다. 쓰지마라."
이 정도 얘기를 들으시는데
저는 goto시절부터 코딩을 한 사람이에요.
GW-Basic이 제가 처음 만졌던 프로그래밍 언어였고
실제로 거기는 무슨
goto 말고는
함수 비슷한걸 만들 방법이 없었던것 같아요
뭐 있었을지도 모르는데
제가 코딩을 그냥 스크립트 짜듯이 처음 배워서 모르는 거 일 수도 있죠
재밌는게 뭐냐면
goto가 뭐냐
어셈블리언어에서 보면 jump에요
이미 어셈블리어로 있는 내용이고
실제 모든 함수도 점프로 이루어져 있는건데
결과적으로 모든 프로그램 하나를
한 줄로 쫘악 짜는거예요.
함수 하나에 짠다고 생각하시면 돼요. 쫘악 짜고.
코드가 가잖아요. 그럼 가다가
그래, 나는 이제...
이걸로 이렇게 됐으니까
그러면 이 밑에 코드로 가서 실행을 해줘
그리고 코드를 실행하다가 다시 jump를 하는거예요.
goto에서 또 "여기로 와서 실행을 해"
그러니까 한 마디로 goto 되는 위치 하나하나가
함수라고 보시면 편한데
옛날에 함수 같은 코딩을 안할 때에는
그냥 한 줄에 다 짜놓고
라인번호 여기로 goto
여기로 goto
저기로 goto
요기로 goto
이게 전부였어요.
그래서 이제
스파게티 코드라는 말을 들어보신 적 있을거예요
다 들어봤겠죠, 사실은.
스파게티 코드가 뭐냐면
결과적으로 이렇게 코드가 쭉 진행이 되다가
jump를 하는 거예요. 밑으로.
jump하고나서 쭉 밑으로 가다가
다시 딴 데로 jump해서 또 가다가
다시 jump하고
돌아서 jump하고
jump하고 해서 보면은
"스파게티가 꼬이듯이
코드의 흐름(Flow)이 꼬여버린다"해서
goto가 나왔고...
아니, goto가 나온게 아니라
그게 스파게티코드라고 하는 것이고
goto의 가장 큰 문제는
지금 제가 스파게티처럼 그려 보여드려서 아시겠지만
코드의 흐름을 따라잡기가 매우 힘들구요
코드의 흐름을 따라잡기 힘든게 뭐냐면
변수같은걸 쓰잖아요, 코딩을 하다 보면은.
그럼 변수에 어떤 값을 갱신하고,
이것을 상태라고 하거든요.
어디에 goto를 해서 jump를 했는데
한참 지나서 보니까
내 상태가 뭔지 감이 안오는거예요.
디버그 걸고 디버깅 하지 않는 이상은
정말 이게 "어디서 상태가 바뀌었는지"
이런게 없는거예요.
그러니까 모든게 Global Scope라고 하죠, 전역 Scope.
아무나 와서 아무나 바꿀 수 있는 것
좋은 예를 들면은
예를 들어서
그.. 뭐라 그래
뭐... 집이나 그런데 가는데 암호(Passcode)가 있잖아요.
아니면 열쇠(key)가 있거나.
이 열쇠를 아무나 열 수 있다고 생각해 봐요.
아무나 열었어.
그런데 어느 날 집 안에 있던 금고가 없어진거야.
"그럼 누가 훔친거야?"
이런 문제가 생기잖아요.
그런데 각 사람마다 열쇠가 따로 있고,
열 수 있는 문이 따로 있다면
그것만, 그거 로그 보는 것만으로
누가 문을 열 수 연지 알 수 있고,
누가 어떤 상태로 바꿨는지 알 수 있다는게
가장 중요한 거였거든요.
그래서 결론적으로 말하면
goto는 나빠요
그런데 언제나 나쁜 것은 아니예요
그게 재밌는 거예요
goto를 흔히 쓰지 말라고 하는 이유는
이런 문제 때문에 쓰지 말라고 하는 것이구요
심지어는 제가 아마 거의 유일하게 존경하는
C++ 교수님이 한 분 있어요
정말 C++ 잘하고, 정말 OOP 잘하시는 분인데
(*역 주. OOP = 객체지향 프로그래밍)
이 분도 심지어는
goto가 한 가지에서는 상관없다는 식으로 얘기해요
딱 한 가지
그게 뭐냐면
반복문(Loop) 빠져 나올 때,
그러니까 이게 왜 이렇게 됐냐면
goto가...
기본적으로 goto를 없애기 위해
모든 언어가 지원하게 된 '함수'
이 부분의 코드를 따로 함수로 뽑아서
이 함수를 호출하고 돌아오면 다시 여기로 돌아온다
그리고 두 번째가 반복문 돌 때,
for, while 반복문 같은 것을 돌 때
중간에 break 걸 수 있고
continue 걸 수 있잖아요
break하면 중간에 빠져나오는 것이고
continue하면 다시 그 반복문 시작으로 돌아가는 것이고.
이게 옛날에는 goto였다고 보시면 맞고
지금도 어셈블리 수준에서는 여전히 jump예요
가다가 jump, 가다가 jump인데
그런 사용 범위를 굉장히
엄격하게(strict) 제한해 둔 것이죠
할 수 있는 것은 이것밖에 없다
함수 호출, continue, break 밖에 없다
이거였는데
goto가 반복문에서 조금 더 편할 때가 있어요
예를 들어서 이런 경우를 생각해 봐요
아마 많이 코딩을 해보셨을텐데
반복문을 두 겹으로 돌리는 거예요
i 반복문과 j 반복문을 돌리는거죠
그러면 돌리다가
이제 j에서 막 무언가를 하고 판단하다가
"어, 여기서 내가 반복문을 끝내야 돼" 했는데
break를 걸면은 i 반복문에 걸려서
다시 i 반복문 시작점으로 가잖아요
사실 여기서 하고 싶은 것은 break를 거는 순간
j도 빠져나오고 i도 빠져나와야 되는 것이거든요
그럼 이런 경우에는 요즘에 어떻게 하냐면
i 반복문 넣고 j 반복문 바로 위에다
무슨.. 아니다
i 반복문 위에다 변수 같은 것을 하나 넣어요
boolean exit_loop = FALSE;
이런 식으로 한 다음에
for문이 i 처리를 하면서 그 안에서
또 하나 체크하는 거예요
if(exit_loop == TRUE) break;
이런 식으로
그래서 j 반복문을 돌다가
나가야 하는 상황이 발생하면
그 boolean 변수에
exit_loop = TRUE;를 박아주고
그러면 i로 올라가서 다음 것을 보는 순간
'exit_loop값이 TRUE니까
여기서 break를 걸어서 나와야겠다'라고 하는,
그런 if문을 두 번 사용하는 개념인데
사실 코드를 짜다보면 이게 좀 더러워 보여요
왜 안쪽에 있는 j 반복문에서
위쪽에 있는 i 반복문도 같이 빠져나가지 못할까
그런데 이런 경우에 goto문을 쓰면
정말 간단해지거든요
j 반복문에서 보고
'아, 여기서 break 해야 하는 순간이야' 그러면
goto...
뭐 이름을 잘 정해야겠죠
잘 모르겠는데...
이름을 뭐라고 정할지는...
뭐...
EXIT_BOTH_LOOP라고 하던가...
뭐 그건 모르겠어요
그러면 그 Loop A...
뭐, 네임(이름)을A라고 하죠, 그냥 편안하게
그러면 코드에 goto A라고 해버리면은
둘 다 빠져나오는 거예요
그래서 그런 경우에는 goto가 편하구요
실제로 그런데에 goto를 써도
그거 가지고 문제를 삼는 프로그래머는 별로 없어요
아마 문제를 삼으시는 분들은 대충
'goto는 나쁘다, 악마다'라고만 듣고
'왜 나쁜지도 이해하지 못한 채
나쁘니까 쓰지 말아야 돼'라는 생각에서
그렇게 들은거라고 '나뻐, 쓰지 마'
이런 개념인 것 같은데
그거는...
제가 예전에 한 번
어느 비디오에서 말했는지는 모르겠지만
아마 exception safe programing 쪽에서
말했던 것 같은데
거기서 그런 이야기를 했거든요, 제가.
그...
프로그래머는 자기가 한 줄 한 줄 짠 코드에 대해
누가 "이거 왜 이렇게 짰어?"라고 물어보면
이유를 댈 줄 알아야 한다고
제 얘기가 그거에요.
누가 goto에 대해 물어봤을 때
'어, 나는 이런 이중 반복문에서는
이게 더 깔끔하고 읽기가 쉬워서'
결국에는 읽기 쉽냐 마냐의 문제예요
'읽기가 쉬워서 goto를 했어'
이런 건 이해가 되거든요
그런데 goto ~ continue는 조금 애매하죠
왜냐하면은
제가 goto에 대해 지금 유일하게 쓸 수 있는 곳,
제가 아는건 이중 반복문을 빠져나올 때 뿐이고
심지어 다른데에 쓸 수 있을지도 모르겠는데
제가 goto를 허용을 한다면
정말 허용을 한다면
언제나 아래쪽으로 jump하는 것만 허용할 것 같아요
그러니까 goto에서 아래쪽으로 jump하고
다시 위쪽으로 jump하는 이런 짓은 하지 말라고
무조건 goto는 아래쪽으로만
그러면 코드를 읽다가도 복잡해지지 않는거예요
어차문 for 반복문 빠져나가는 범위나
goto로 이 밑으로 가는 범위나
그거는 나빠지지 않거든요
똑같거든요, 가독성 부분에서는
어디서 상태(state)가 바뀌는지도 알 수 있고
뭐...
마찬가지 논리로
코드 중간에, 함수 중간에
Return문을 여러개 박는 경우도 있어요
어떤 사람은 그게 나쁘다
if문으로 다 바꿔서 아래에서 하나만 Return 하도록 해라
어떤 사람은 '아니다, 중간에 Return을 빨리 해서
if문 같은 여러 들여쓰기(indentation)를 빼라'
이런 두 가지 부류인데
저는 Return을 중간에 해도
상관없다고 생각하는 이유가 뭐냐면
결과적으로 Return을 하는 순간
코드는 나가는 거거든요. 밖으로.
그러면 그거는
가독성에서는 크게 문제가 없다고 봐요, 저는.
그런데 이제...
다른쪽 주장도 제가 크게
틀렸다라고 생각하지는 않아서
저도 이렇게
적당히 밸런스 맞춰 쓰는거죠
너무 들여쓰기를 5, 6개 들어가버리면
복잡해지니까
중간에 적당히 빠져나오기(Early Exit)도 하고
아니면 제일 위에서 에러 체크 한 다음
Return을 바로하는건 차라리 그게 더 깔끔하니까
그런 경우도 하기도 하고
그거는 결국 가독성의 문제고
어느 한 쪽이 반드시 옳다고 할 수는 없을 것 같고
이 goto를 얘기하다가 굉장히 재밌어지는게 뭐냐면
제가 조금 전에 exception safe programing,
뭐 exception handling programing 얘기를 했으니까
이 goto가 나쁘다고 하는 이유가 바로
코드의 상태를 예측하기가 너무 어렵다는 거예요
정확하게 얘기하면.
goto가 위로, 아래로 왔다갔다하면
내가 지금 변수가 값이 어디서 뭘 설정했는지 모르겠는데
이 문제잖아요?
이게 되게 재밌는 게 execption safe 프로그래밍이라고 전에 한번 말했죠.
execption이 나도 뭐 현재 상태에 문제가 없게끔 코드가...
execption이 나는 상황에서 보통은 execption이 그 라인에서 throw 하면서 코드 밑에 코드를 실행을 안 시키니까
그 상황에서 아 ...
이 밑에게 실행이 안되더라도 현재 상태는 문제가 없게하는 코드를 만들자
이런 이런 개념이 execption safe에요. 뭐 여러 가지 단계가 있지만
결과적으로 이제 완벽히 퍼펙트한 상황에서는 그런 저죠.
execption이 나도 아무 문제가 없이 코드가 돌게 하자
뭐 그런데
예를 들어 execption이 나도 그전 상태가 망가지지 않게 하자 이런 건데
이게 되게 애매해지는 게 뭐냐면
그 예전에 한번 그 execption safety가 되게 어렵다고 하면서 코드 샘플을 만드신 분이 있는데
되게 유명하신 분이에요. 레이몬드 첸이었나?
그분이 나온 샘플에서도 실수를 한 부분이에요.
그래서 나중에 누가 해가지고 실수했다고 해가지고 고친 거예요.
그렇게 엄청 훌륭하신 프로그래머도 실수하는 정도의 그런...
그 정도를 제대로 하기가 어려운 게 execption safe인데
재밌는 게 뭐냐면 예를 들어서 이런 경우가 있다고 생각을 해봐요.
내 함수에서 어떤 오브젝트를 만들어서 리턴을 해요.
그리고 그 오브젝트가 화면에 보이는 오브젝트이기 때문에 visible flag를 true로 해주어야 되는 거예요.
그러니까 눈에 보여야 된다고요.
그래서 그리고 코드 밑에 따른 아니 그 오브젝트 안에 다른
뭐라고 그럴까 서브 오브젝트를 또 create 해주는 그 로직이 있다고 봐요.
그러면은 코드가 어떻게 되냐면은 new Object 이런 게 나올 거잖아요. GameObject
그리고 그다음 줄에 GameObject.visible = true로 해주고요.
뭐 이건 프로퍼티 개념으로 거의 하고 있네요. 사실은
그리고 그 밑에는 거기다가 이제
뭐 뭐였지 아까 그 Object.child 뭐 아니면 skeleton도 괜찮고 뭐 다른 필요한 정보들
그리고 또 new를 붙여줘야 하는데 예를 들어서 이 두 번째 new에서 execption이 나 봐요.
그러면 곧바로 나면서 전에 함수로 올라가는데
그러면 이미 visible flag를 set을 set을 true로 해버렸잖아요.
근데 안에 이게 child가 없으면 아예 visible도 안되게 하는 게 정상적인 behavior야
그러면 이거는 이제 나중에 Object는 올라갔고 visible이라고 하니까 그거를 그리려다가 뻑이 나겠죠. 어디선가
그럼 이게 execption에 안전하지 못한 거예요.
그래서 이거를 올바르게 하는 법은 뭐 그런 얘기를 해요
처음에 Object를 만들고 visible을 true 로 세팅하기 전에 child를 먼저 만들어 주라는 거예요.
new를 해서 그럼 child에서 뻑이 나면 visible이 true가 아니기 때문에
다른 함수에서 그걸 봐도 visible이 true가 아니어서 처리를 안 한다. 뭐 이런 식의 개념인데...
하....
이게 근데 만약에 visible은 false이더라도
update는 해줘야 돼 active는 또 기본적으로 다 true라고 해봐 그러면 또 헷갈리는 거거든요. 이게
굉장히 애매해져요.
그리고 실제 뭐 C#이나 java같은류에 그 뭐라 그럴까
default patameter 설정해주는 법이 있잖아요.
재가 볼 때 C++도 이제 그걸 허용한다고 했던 거 같긴 한데
재가 지금 그건 정확히 기억이 안 나요.
C#하고 java 같은 경우에는 그냥 private변수 선언하면서 곧바로 값을 값도 대입하잖아요.
그럼 그거를 visible true로 해줬으면 또 이런 exception이 난 경우에는 어떻게 해야 돼
try catch 써서 또 잡아줘야 돼?
이.. 이게 문제가 뭐냐면
아까 goto가 문제라고 했던 상태를 볼 수 없다고 한 거 있잖아요.
그게 똑같이 exception이 throwing 되는 코드 베이스를 하다 보면은 그 문제가 똑같이 생겨요.
exception이 나도 안전되게 코드를 만들려고 어떻게든 돌다 보면은 .
매 코드 한 줄 한 줄 보때마다
이 코드가 요거 위에 와야 되나? 말아야 되나 고민을 해야 되는 거예요
로직상으로는 아무 상관이 없는 건데
예외 상황이 발생할 때를 생각을 해서
이 코드가 이것보다 전에 와야 돼? 아니지 그러면 이게 여기서 exception이 나오면 이게 망가지네
그럼 이게 이게 돼야 돼? 막 그런 거 생각하다 보면은 장난 아니게 이상해지고
그러니까 그리고 이제 try를 이제 catch를 해서 finally까지 돌다 보면은
당연히 catch안에서 뭔가 또 처리를 할 때 exception이 또 날 수가 있어요.
그럼 또 catch를 해줘야 하고 막 이런 이런 말도 안 되는 생각을 하면은 코드가 어느 순간 스파게티가 되는 거예요.
진짜 그게 문제예요. 그니까 코드가 진행되다가 어느 한 줄에서 exception이 날 수도 있으니까 여기로 뛰어
그러면 이게 과연 상태가 여기서 오는 거랑 그다음 줄에서 오는 거랑 똑같이 유지가 되는가
이런 것들을 생각을 하면은 코드가 깔끔하게 나올 수가 없어요.
사람들이 가독이 불가능한 정도의 코드가 나와요. 그래서
이거는 정말 어려운 개념이다 라는 게
이제 뭐라고 그럴까
일반적인 견해라고 봐요. 저는 쉽지 않다 어렵다가 일반적인 견해고
그래도 이게 올바른 방법이다는 반대 진형이 있는 건데
저는 이거는 전에도 몇 번이나 누누이 말했지만
예전에 문제를 고치기 위해 나온 그런 방법 중에 하나죠. 사실은
근데 그 방법을 제대로 고치지 못한 경우라고 봐요.
잘못된 시도 저는 그래서 지금
저는 지금 이게 정확히 어떻게 고쳐야 될지는 모르겠는데
재가 생각하는 거는 try catch는 최소화하는 게 맞고
본인이 컨트롤할 수 있는 코드는 그냥 다 고쳐야 된다고 봐요.
아예 exception 상황이 안 나도록
그리고 이제 으익.. 그게 가장 큰 문제예요. 사실은
그래서..
시작 그러니까 go... 재가 한 자기 뭐 이렇게
언어를 배우시는 분도 그렇고
언어를 디자인하시는 분도 제가 좀 원하는 건데 솔직히 언어 디자인이
뭐라고 그럴까 아카데미 위주로 디자인이 된 언어는 이런...
모순이라고 하나요. 그런 거에 빠지는 경우가 꽤 많은 것도 같아요. 그에 비해
이제 큰 회사 규모로 진행되는 프로젝트들이 있어요.
언어 지원되는 게 이제 C#도 좋은 예였고
Java도 첨엔 누가 sun이 할 땐 좋았다고 하더라고요.
그것도 좋은 예였고 지금 Rust Lang도 사실은 뭐 오픈소스라고 하지만 Mozilla 회사에서 진행하고 있는 거잖아요.
그 Firefox 만든데 그런 언어들을 보면은
그...
이런 이런 그 뭐라 그럴까 실수를 만들 수 있는 부분을 굉장히 줄이고 있고
그리고...
그게 좀 모순되는 것들 그러니까 한 가지 원칙이 있으면 그 원칙을 따라가야 되는데
그 원칙을 여기선 이러고 저기는 저러고
그런 타당한 이유가 없는 그런 예가 많이 나와요.
왜냐하면은 그만큼 어느 한 사람이 끌고 가는 게 아니기 때문에
그래서
그.. exception이 그게 그 핸들링을 통해서 해결하려고 했던 건 아는데
결국엔 goto에서 생겼던 그 문제를
그대로 다시 또 부활시키는 그런 경향이 있어서 저는
유지보수가 되는 코드가 그렇게 쉽게 나올 거라 생각하지는 않아요.
이 그.. exception을 핸들링해주고 exception safety코드를 그렇게 열심히 만들려고 노력하는 순간에
그리고 아까도 말했지만 굉장히 훌륭한 프로그래머들도 언제나 실수하는 부분이 이거고
그게 실수를 한다는 경우는 결국에는 회사에서도 코드를 짤 때 실수가 쉽다는 거구
이건 QA의 문제지
그...
절때 재가 볼댄 exception을 어떻게 처리하고 완벽한 코드를 만드는 문제는 아닌 것 같아요.
그래서 뭐 이제는 굉장히 유명한 책 있잖아요. Writing Secure Code인가? 마이크로소프트에서 나온 책
거기 솔직히
그 뭐라 그럴까
exception에 대해서 그다지 큰 비중을 두지 않아요.
그렇게 안전한 코드를 쓰자는 대에서
exception이 지금 받고 있는 비중은 생각보다 적은 것 같아요. 오히려..
남용을 해서 지금 문제지.. 그래서
하고 싶었던 말은 결과적으론 goto는 요약을 해야죠.
goto는 기본적으로 나쁘다. 그러나 루프를 빠져나올 때 nested loop를 빠져나올 때는 쓸모가 있다.
정말 어디 그 외 쓸 때가 있다면 재가 여태까지 겪어 보지 못한
그런 게 있다면 무조건 goto는 아래쪽으로만 점프하게
그런 식으로 하는 게 맞고
똑같은 예기로 이제 그 부수적인 예기로
새로운 언어가 나오거나 새로운 기능이 나오거나 이랬을 때
그건 제가 다음 비디오에서 이야기할 건데
거기에서 오는 어떤 그...
문제가 있는지 예전에 겪었던 문제를 우리가 다시 부활시키고 있진 않는지 이거는 .
한 번쯤은 누구나 생각해 봐야 될 거 같아요
그리고 다행히도 소프트웨어 업계는 그 정도에
실제 프로그래밍 경력도 많아지고 실무도 제대로 돌아보셨고
그런 분들이 이런 문제를 일찍 파악해서 이거는 문제다 짚어 주시는 분들이 있기 때문에
그나마 좀 다행이라고 생각을 해요.
근데 이제 그거는 프로그래머 좋은 프로그래머가 되려면
그런 자세는 가지는 게 좋은 거 같아요.
그래서 이제 그 정도로 오늘 포프 TV는 마무리하죠.
예 포프였습니다.