tag:blogger.com,1999:blog-2590786243514585895.post1865365001549211352..comments2022-03-28T13:41:03.207+01:00Comments on Camltastic!: 3 things that will confuse you when reading functional programsRichard Joneshttp://www.blogger.com/profile/08315526595922432607noreply@blogger.comBlogger4125tag:blogger.com,1999:blog-2590786243514585895.post-86479000061118310952008-08-22T19:49:00.000+01:002008-08-22T19:49:00.000+01:00Warren:Yes, I fully agree. It's both very conveni...Warren:<BR/><BR/>Yes, I fully agree. It's both very convenient (for the experienced) and very confusing (for the newbie) to leave out brackets.<BR/><BR/>But you know it's just one of those things about getting used to a new language. I recall C appears equally confusing if all you've used before is BASIC.Richard Joneshttps://www.blogger.com/profile/08315526595922432607noreply@blogger.comtag:blogger.com,1999:blog-2590786243514585895.post-50357397856332536442008-08-22T19:33:00.000+01:002008-08-22T19:33:00.000+01:00I'm sorry my example was so over-simplified th...I'm sorry my example was so over-simplified that it obscured my point... which was that I've found that the first thing that confuses new/potential users about functional programs is the immediate need to understand syntactic precedence of operators and expressions in general. <BR/><BR/>Unlike familiar languages like c and java, programs in functional languages like ocaml and haskell allow (even encourage) users to leave off many visual bracketing cues (parens) that are unnecessary with respect to precedence relations in the grammar. This raises the bar for new users who must understand this precedence to understand how the program will be understood by the compiler. <BR/><BR/>List processing code often exhibits this need to understand precedence. Consider this line from the pairwise-mapping function map2 in ocaml:<BR/><BR/> | a1 :: l1, a2 :: l2 -> let r = f a1 a2 in r :: map2 f l1 l2<BR/><BR/>One must not only understand that :: binds tighter than comma in the pattern, but also that function application ("map2 f l1 l2") binds tighter than :: (and consequently is performed first, providing the tail of the list to which r is prepended). All of this is alien to users that are new to functional programming. (Not to mention code with user-defined infix operators like this: a ++ b >>= fun v -> return (k v).)<BR/><BR/>The second thing that probably throws new users off is why many things are done by using recursive functions rather than the ubiquitous iteration used in traditional languages -- and this gets into composability, understanding tail recursion, functional data structures, etc. -- although this gets more into the value of functional programming rather than its confusing aspects.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-2590786243514585895.post-83352058095199182992008-08-18T07:33:00.000+01:002008-08-18T07:33:00.000+01:00To be honest Warren, I wouldn't know immediate...To be honest Warren, I wouldn't know immediately what 'fun () -> (), fun () -> ()' means.<BR/><BR/>Typing it into the toplevel shows the true type, but it's still rather obscure to me:<BR/><BR/># fun () -> (), fun () -> () ;;<BR/>- : unit -> unit * (unit -> unit) = <fun><BR/><BR/>If this was real code, I'd tell people to fully bracket the expression <I>and</I> give some explanatory comment.Richard Joneshttps://www.blogger.com/profile/08315526595922432607noreply@blogger.comtag:blogger.com,1999:blog-2590786243514585895.post-53023751626734159172008-08-18T03:16:00.000+01:002008-08-18T03:16:00.000+01:00One of the biggest things I've seen new users ...One of the biggest things I've seen new users trip on is that you have to know a lot about operator precedence to understand what programs mean. E.g. is "fun () -> (), fun () -> ()" of type "(unit->unit)*(unit->unit)", or "unit->unit*(unit->unit)" (and what's the precedence of * vs ->)? I often trip on this myself when reading academic papers on the subject.Anonymousnoreply@blogger.com