최근에 functional에 맛들려서 서버에서는 로직에 lodash대신 ramda를 사용해서 작업을 하고있었습니다.
다만 프론트에서도 ramda를 사용하며 작업을 헀지만 좀 더 functional한 방법이 없을까 해서 찾아보던 중 elm
이라는 언어를 발견했고 맛이나 보자 해서 front-end 학습의 기본인 Todo 코드를 작성해봤습니다.
markdown에서 elm을 support하지 않는 거 같네요...😅
다른분들 익숙하실 typescript, react와 비교해가며 작성해보겠습니다.
# snad box로 프로그램을 선언 (가장 메인이 되는 작업입니다.)
main : Program () Model Event
main =
Browser.sandbox
{ init = init #{redux에서 initalState}
, update = update #{redux에서의 action}
, view = view}
}
# 다음처럼 custom type을 선언해서 할 수 있습니다. {typescript의 interface}
type alias Model =
{ todo : List Todo
, newTodo : String
}
# custom type을 가지고 init에 들어갈 값을 초기화 해줬습니다.
init : Model
init =
{ todo = []
, newTodo = ""
}
# Event를 통해 사용할 action name과 parameter을 정의했습니다.
# 예시) TodoUpdate String은 TodoUpdate action에 string인 parameter가 들어갈것이다.
type Event
= TodoUpdate String
| Submit
| Complated Int
update : Event -> Model -> Model
update event model =
case event of
TodoUpdate value -> # action naming이 잘못되긴 했는데...input 업데이트 action입니다.
{ model | newTodo = value } # model에 newTodo를 value로 update하겠다.
Submit ->
{ model
| todo =
if String.isEmpty model.newTodo then
model.todo
else
Todo model.newTodo False :: model.todo
, newTodo = ""
}
Complated compltedItemIndex ->
let
complatUpdate index item =
if index == compltedItemIndex then
{ item | check = not item.check }
else
item
in
{ model | todo = List.indexedMap complatUpdate model.todo }
# view는 사실 html과 크게 다르지 않고 문법의 차이만 있으므로 자세한 설명은 생략하겠습니다.
view : Model -> Html Event
view model =
div [ style "width" "50%", style "margin" "50px auto" ]
[ h1 [ style "text-align" "center" ]
[ text "Todo: 할 일을 추가해보세요" ]
, div [ style "margin-top" "50px", style "text-align" "center" ]
[ input [ value model.newTodo, onInput TodoUpdate, onEnter Submit ] []
, button [ onClick Submit ] [ text "추가" ]
]
, div [ style "border-top" "1px solid black", style "margin-top" "30px" ]
[ div [ style "margin" "15px auto", style "display" "grid", style "grid-template-columns" "85% 15%", style "border-bottom" "1px solid black", style "padding-bottom" "15px" ]
[ span []
[ text "content" ]
, span []
[ text "status" ]
]
, div [] (List.indexedMap viewTodoItem model.todo)
]
]
"haskell
이나 scala
등 함수형 언어를 시작하기 전에 함수형에 익숙해져 보자" 라는 취지이면 꽤나 괜찮은 시작일 수 있을 거 같습니다.
코드를 짜면서 느낀점은 이게 jquery, react 등과 뭐가 다른가 라는 생각을 했습니다.
nest
하다 django
할 때 같은 느낌입니다. 크게 보았을 때 (정말 단순히)서버는 CRUD라는 똑같은 작업을 하고, 프론트도 view에서 aciton이 일어나 상태값 등을 업데이트 후 다시 노출시켜주는 작업을 한다는 점에서는 큰 틀은 똑같다고 생각합니다. 즉, 언어는 상관이 없다. 어짜피 똑같은 작업을 하는 것이라면 퍼포먼스
에 중점을 두고 기술 스택을 선택하는 게 맞다는 생각에 조금 더 동의를 할 수 있었습니다.
좋은 포스트네요 :)