Разработка на коленке

"тут должна быть красивая цитата о программировании"

Сортировка пузырьком на OCaml

2016-04-14 13:08

Принимая во внимание мой провал как функциоанльщика при генерации всех пересатновок, решил начать с чего-то меньшего. Попробую писать на OCaml'е в функциоанльном стиле простые алгоритмы. Результат буду также отправлять на codereview.stackexchange.com.

Вот такой код отправил на очередное [ревью].

let print lst =
    List.map string_of_int lst
        |> String.concat " "
        |> print_endline
;;


let rec sort lst =
    let sorted = match lst with
    | hd1 :: hd2 :: tl ->
        if hd1 > hd2 then
            hd2 :: sort (hd1 :: tl)
        else
            hd1 :: sort (hd2 :: tl)
    | tl -> tl
    in
    if lst = sorted then
        lst
    else
        sort sorted
;;


let () =
    let lst1 = [3; 4; 2; 1] in
    print lst1;
    sort lst1 |> print;

    let lst2 = [5; 6; 7; 0; 1; 4; 2; 9; 3; 8] in
    print lst2;
    sort lst2 |> print;
;;

Перестановки элементов массива на OCaml

2016-04-08 20:00

Написал свою реализацию поиска всех перестановок на OCaml. Код отправил на код-ревью [ссылка], посмотрю, что скажут.

Пока писал, сломал себе голову. Многие вещи в OCaml до сих пор загадка. Постоянно приходится лазить по справке, чтобы узнать, что может делать та или иная структура данных.

open Core.Std;;


let print aofa =
    let s1 = ( Array.length aofa ) - 1 in
    for i = 0 to s1 do
        for j = 0 to (Array.length aofa.(i)) - 1 do
            printf "%d " aofa.(i).(j);
        done;
        printf "\n";
    done;
;;


let rec fact i =
    if i <= 1 then 1 else i * fact (i - 1)
;;

let rec permutations ints =
    let length = Array.length ints in

    if length < 2 then
        [|ints|]
    else begin
        let total = fact length in

        let result = Array.create total (Array.create length 0) in
        for i = 0 to total - 1 do
            result.(i) <- Array.create length 0
        done;

        let block_size = total / length in
        for i = 1 to length do
            let rest = Array.append (Array.sub ints 0 (i - 1)) (Array.sub ints i (length - i)) in
            let rights = permutations rest in
            for r = 0 to (Array.length rights) - 1 do
                let n = Array.append [|Array.get ints (i - 1) |] rights.(r) in
                result.((i - 1) * block_size + r) <- n
            done;
        done;

        result
    end
;;


let () =
    let aofa = permutations [|1; 2; 3|] in
    print aofa;
;;

Результат такой:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

Прочитал "Программирование на языке OCaml"

2016-02-08 13:20

Вчера закончил читать "Программирование на языке OCaml" (перевод на русский Real world OCaml). Интересная книга, интересный язык. Теперь попробую применять его на практике.

Пока читал, попробовал сделать простейший клеточный автомат - ocaml-conway-game-of-life.

Пост, по сути, просто отметка, когда я закончил читать книгу.

Mistake in broken code example

2015-09-02 15:15

I read a book Real World OCaml (well, actually, I read russian edition, but that doesn't matter), and I found one funny thing - authors made an mistake in broken code example.

Chapter 2 - Prefix and Infix Operators, and code part 36, just after this.

# let (^>) x f = f x;;

# Sys.getenv_exn "PATH"
  ^> String.split ~on:':' path
  ^> List.dedup ~compare:String.compare
  ^> List.iter ~f:print_endline
  ;;

Variable path can't be used here. If you will replace ^> with |> then you get an error.

OCaml для python-программиста

2015-07-31 23:55
Фотография аквариума от будущего OCaml-программиста

В интернетах говорят, что для улучшения своих программистских навыков нужно сделать что-нибудь хорошее, а следом приводят список такого хорошего. Обычно одним из пунктов "выучить новый язык программирования с концепциями отличными от тех, что вы используете каждый день". На самом деле это не цитата из списка, а вольный пересказ. Часто там предлагают список языков, которые обязательно должны помочь программисту стать чуточку лучше, обычно это Lisp, OCaml, Haskell. Ещё к этому списку были добавлены Rust и Nim. Поддавшись желанию стать немного лучше, взялся за выбор языка из этих пяти.

Lisp

Был вычеркнут почти сразу. Во-первых, я с ним уже имел дело, а во вторых у него динамическая типизация, что я и так каждый день вижу в python и javascript. Хотя как язык он мне понравился.

Nim, Rust

Следующими на вылет стали Nim и Rust. С Nim я немного поигрался до этого, прочёл его официальную документацию, а о Rust почерпнул немного информации с официального сайта. Как ни крути, но оба языка очень молодые, где-то сырые, идёт постоянная работа над изменениями. Т.е. мне бы пришлось не столько изучать новый язык и концепции, сколько следить за творческими метаниями авторов. Этого мне не хотелось. А Nim помимо молодости содержит совершенно непривычные для меня вещи, вроде регистро-независимости и возможности писать один и тот же код разными способами, например,

iecho "Hi"
"Hi".echo

В общем, пусть оба эти языка подождут лучших времён.

OCaml vs Haskell

Осталось два кандидата. у обоих статическая типизация, оба невероятно круты и холивары чем-то напоминают vim vs emacs. Чтобы в таких условиях делать осознанный выбор (как когда-то я делал в случае с vim и emacs), нужно попробовать в деле оба языка. первым выбрал OCaml, без каких-либо веских доводов, просто "вот так".

Книга про OCaml

Первым делом просмотрел список доступных книг и примеров кода. Потом полистал официальную документацию. По ходу чтения OCaml нравился мне всё больше. После беглого ознакомления с официальной документацией взялся за realworldocaml.org. Авторы книги уже много лет пишут на OCaml, разработали расширения для языка и большую библиотеку. Ну я и подумал, что почему бы не поучиться у тех, кто имеет опыт в разработке на новом для меня языке. Книга мне понравилась с первого предложения:

Programming languages matter.

realworldocaml.org

Первое погружение

Помимо чтения книги, подсматривания в официальную документацию и поиска по форумам, делаю простые, но необходимые для меня вещи. Для начала запишу строку в файл.

open Core.Std;;


let create_json_file str =
    let ofp = Out_channel.create "list.json" in
    fprintf ofp "%s" str;
    Out_channel.close ofp
;;


let () =
    create_json_file "[1, 2, 3, 4, 5]";
    printf "Bye\n";
;;

Признаюсь, что помимо этого примера попытался записывать в файл список строк, превратив его в список в json-формате, но у меня пока что не получилось. При попытке написать что-то длиннее 10 строк вызывает целый поток ругательств от corebuild. Дело в том, что почти вся первая глава крутится вокруг utop, и предполагается, что читатель делает тоже самое.