Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Функциональные языки: общие вопросы > [Ocaml] Функциональный разбор аргументов


Автор: technologer 25.9.2012, 18:45
Доброе всем время суток!
Пытаюсь понять что такое FP на примере OCaml, переписывая небольшой утилитарный скрипт с императивного языка.
Проблемы начались сразу:
- не получается придумать как легко и дёшево разобрать параметры коммандной строки
- получается только с использованием ссылок:

Код

(* Параметров в пару раз больше чем здесь, просто для краткости порезал *)
let inputXMLPath = ref "localization_client.txt";;(* значения по умолчанию *)
let outputXMLPath = ref "locale";;
let outputXMLName = ref "localization";;
let packagePath = ref "";;
let arg_spec = [
    ("-inputXMLPath", inputXMLPath);
    ("-outputXMLPath", outputXMLPath);
    ("-outputXMLName", outputXMLName);
    ("-packagePath", packagePath);
];;
exception Error of string;;

(*
Берём параметры коммандной строки, они записываются в стиле:
ocaml str.cma generator.ml -outputXMLPath "aaaaa" -packagePath ""
*)
let args = List.tl (Array.to_list Sys.argv);;

(* Распихиваем по 4 ссылкам, перечисленным в arg_spec *)
let rec read_args args =
    match args with
    | [] -> ()
    | x::[] -> raise (Error ("Elone argument option " ^ x))
    | key::v::tail ->
        let pair = (
            try List.find (fun pair -> fst pair = key) arg_spec
            with Not_found -> raise (Error ("Unknown option " ^ key))
        ) in
        let vRef = snd pair in
        vRef := v;
        read_args tail;;
read_args args;;

(* Выводим всё что прочитали и что по умолчанию *)
print_string "parameters:\n";;
List.iter (fun (key, v) -> print_string (key ^ " = " ^ !v ^ "\n")) arg_spec;;


Если уже в этом простом случае приходится использовать мутабельные конструкции, то какое дальше может быть FP?
Подскажите, чего я делаю не так.

Автор: tzirechnoy 25.9.2012, 18:56
Возьмите erlang. Там гораздо меньшэ мутабельных конструкцый, потому таких вопросов не встаёт. ВСё-таки у lisp и ocaml слишком просто писать в императивном стиле (а в haskell вообще тяжэло писать, хоть как-то, и поначалу получается ад, а clean я не знаю).

Автор: technologer 25.9.2012, 19:39
Ну не верю я, что есть что-то такое в Erlang, чего нет в OCaml, и без чего нельзя вышеприведённый код перегнать в немутабельный вид.
Люди, вон говорят, что код чуть ли не копипастили с Haskell в OCaml для повышения производительности - и всё заработало (а haskell вроде чисто-фукциональный язык)

Т.е. "В OCaml много мутабельных функций" != "В OCaml невозможно кодить функционально"

И всё-тки нужен OCaml

Автор: k0rvin 26.9.2012, 10:38
Чисто функциональный пример на Хаскелле (без использования исключений): http://ideone.com/5dGQB
Код

D:\usr\Development\haskell> ghc -o test test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )
Linking test.exe ...

D:\usr\Development\haskell> test -inputXMLPath "foo.xml" -xxx bar -yyy
Error: unknown option -xxx
Error: alone argument option -yyy
Parameters:
-inputXMLPath = foo.xml
-outputXMLPath = locale
-outputXMLName = localization
-packagePath = 

D:\usr\Development\haskell>


На Окамле будет примерно так: http://ideone.com/HFtWW

Добавлено через 3 минуты и 18 секунд
Цитата(technologer @ 25.9.2012,  19:39)
Т.е. "В OCaml много мутабельных функций" != "В OCaml невозможно кодить функционально"

Но это и не значит, что нужно кодить функционально везде, где только можно.

Кстати про Ocaml vs Haskell можно почитать http://vshabanov-ru.blogspot.com/. Точнее почему в итоге чел сменил окамл на хаскелл.

Автор: technologer 26.9.2012, 15:09
k0rvin, спасибо!
Теперь гораздо понятнее что такое функциональный подход.

Только вот как брать теперь эти значения из списка.
Самое первое что приходит в голову - это сделать функцию, берующую значение из списка по ключу. Видимо, так и придётся сделать.

Цитата

Но это и не значит, что нужно кодить функционально везде, где только можно.

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

Цитата

Кстати про Ocaml vs Haskell можно почитать здесь. Точнее почему в итоге чел сменил окамл на хаскелл.

Нисколько не сомневаюсь, что Haskell круче OCaml в функциональном плане, но OCaml выглядит практиченее/производительнее + проект в который тянет залезть с напильником написан на OCaml

Автор: k0rvin 26.9.2012, 16:12
Цитата(technologer @ 26.9.2012,  15:09)
Нисколько не сомневаюсь, что Haskell круче OCaml в функциональном плане, но OCaml выглядит практиченее/производительнее + проект в который тянет залезть с напильником написан на OCaml

Вообще-то там по ссылке как раз про практичность/производительность.

Автор: technologer 26.9.2012, 21:59
А вот здесь наоборот, начинали на Haskell, а потом перешли на OCaml из-за производительности
http://www.slideshare.net/j2a/ss-4625844

P.S. Наверно это не важно, но на всякий случай:
конструкция
Код

let rec tryReplace key aval args = match args
        with []                        -> None
        | ((k, v)::rest) when k == key -> Some ((key, aval)::rest)
        | ((k, v)::rest)               -> match tryReplace key aval rest
                with Some xs -> Some ((k, v)::xs)
                |    None    -> None ;;

не срабатывала, пока не заменил "==" на "=", а так всё работает как ожидалось

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)