On Github niquola / railsclub-2015-slides
применяються
значения
Нет объектов и классов
list = [1, 2, 3] new_list = push(list, 4) puts list # => [1, 2, 3] puts new_list # => [1, 2, 3, 4]
mapa = {a: 1} new_mapa = assoc(mapa, :b, 2) puts mapa #=> {a: 1} puts new_mapa #=> {a: 1, b: 2}
cos(π) => 1
cos(π) => 1
cos(π) => 1
cos(π) => 1
Вообще ничего не прячут
f(g(h(x))) f.g.h x (-> (h x) g f)
параметризация вычисления
конструкторы вычислений
# fold(col, init-value, &proc) sum = fold([1,2,3], 0,+) prod = fold([1,2,3], 0,*) map = fn (f, col) fold col, [] do |acc,x| push(acc,f(x)) end end filter = fn (pred, col) fold col, [] do |acc,x| pred(x) ? push(acc,f(x)) : acc end end
fn wrap(f) fn (x) if ??? f(x) else return ??? end end end
Like our decorators or chain of responsibility
f' = wrap(f) f'' = other_wrap'(f') .... .... .... f''''(x)
# chain(acc,elem) chain = compose( filter(odd?), map(double), take(5) ) reduce(chain, [], coll)
собираем вычисление, потом выполняем
# isolation transaction do change(state1) change(state2) end
Ни тебе race condition, dead lock, incosistent read
fn server(req) return { status: 200, body: "Hello", headers: { ContentType: 'text' } } end server({uri: "/home", params: {q: '???'}})
server = compose( wrap_params, wrap_cookies, wrap_json_request, wrap_form_params, dispatch ) server(request)
Наш rack
# dispatch(request, routes_spec) -> handler fn dispatch(request, routes_spec) handler = find_in_routes(request, routes_spec) handler(request) end
Они ничего не знают про паттерны
route_spec = { admin: { users: { POST: users/create GET: users/index } } } route_spec = [ ["admin", "users", "POST", users/create], ["admin", "users", "GET", users/create], ]
fn layout(content) [:html, [:header, [:title "layout"]], [:body, menu() content]] end def render(data) layout( [:ul, map data {|x| [:li, link_to(x.url, x.text)]}] end
Я же говорю одни функции
layout1( layout2(content1()), layout3(content2()) ) def decorate_user(user) user[:full_name] = user[:first_name] + user[:last_name] user end def link_to(url, label) [:a, {href: url}, label] end
нет проблем с лайаутами и хэлперами
Ups, а объектов то нет
А работа с базой?
query = { select: [:id, :name], from: "users", where: [:name "=" x] } fn by_name(name, query) merge(query, :where,["name", "ilike", name]) end fn active_users(query) merge(query, :where,["status", "=", "active"]) end conn/exec( sql( active_users( by_name("nicola", query)))
опять функции ~ 800 SLOC
String:HTTP -> fns -> String:SQL -> DB -> fns -> String:HTTP
State -> ui_function -> VirtualDom -> React.diff/patch -> DOM Event -> change State -> State' State' -> ui_function -> VirtualDom -> React.diff/patch -> DOM
Почти нет, много маленьких библиотек, которые легко склеиваются
Сильно сфокусированны на задаче
SOLIDные
Почему мы тогда тратим в 10 раз больше сил?
Почему декомпозиция тоже проблема?
а они просто для этого пишут функцию