# alokmenghrajani/opalang forked from MLstate/opalang

### Subversion checkout URL

You can clone with HTTPS or Subversion.

[enhance] doc/book: Partial re-write of all wiki-based chapters.

```We are now using Markdown instad of Templates. Plus took this
opportunity to do a little clean-up.```
commit 626cab31368b4835f97f926280b7777993179afa 1 parent 76c582d
akoprow authored
 @@ -826,9 +826,47 @@ a comparison is a boolean. We write that the type of function ======================== In Opa, booleans are values +{true = void}+ and +{false = void}+, or, more concisely but equivalently, +\{true\}+ and +\{false\}+. -You can check whether boolean +b+ is true or false by using +if b then ... else ...+ or, -equivalently, +match b with \{true\} -> ... | \{false\} -> ...+. + +Their type declaration looks as follow: +type bool = \{true\} / \{false\}+. +Such types, admitting one of a number of variants, are called sum types. +======================== + +[TIP] +.About sum types ======================== +A value has a _sum type_ +t / u+, meaning that the values of this type are either +of the two variants: either a value of type +t+ or a value of type +u+. + +A good example of sum type are the aforementioned boolean values, which are defined +as +type bool = \{false\}/\{true\}+. + +Another good example of sum type is the type +list+ of linked lists; its definition +can be summed up as +\{nil\} / \{hd: ...; tl: list\}+. + +Note that sum types are not limited to two cases. Sum types with tens of cases +are not uncommon in real applications. +======================= + +Safely determining which variant was used to construct a value of a sum type +can be accomplished with pattern matching. + +[TIP] +.About pattern-matching +======================== +The operation used to branch according to the case of a sum type +is called _pattern-matching_. A good example of pattern-matching +is +if ... then ... else ...+ . The more general syntax for pattern matching is ++match ... with | case_1 \-> ... | case_2 \-> ... | case_3 \-> ...+ + +The operation is actually more powerful than just determining which case of a +sum type is used. Indeed, if we use the vocabulary of languages such as Java or +C#, pattern-matching combines features of +if+, +switch+, +instanceof+/+is+, +multiple assignment and dereferenciation, but without the possible safety issues +of +instanceof+/+is+ and with fewer chances of misuse than +switch+. + +As an example, you can check whether boolean +b+ is true or false by using ++if b then ... else ...+ or, equivalently, +match b with \{true\} -> ... | \{false\} -> ...+. +======================= Distinguishing messages between users ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-
67 doc/book/hello_web_services/hello_wiki_rest.opa
128 doc/book/hello_web_services/hello_wiki_rest_client.opa
 @@ -1,83 +1,93 @@ -import stdlib.web.template +import stdlib.tools.markdown -uri_for_topic(topic) = Uri.of_absolute({Uri.default_absolute with schema = {some = "http"} : option(string) - domain = "localhost" - port = {some = 8080} : option(int) - path = ["_rest_", topic]}) +uri_for_topic(topic) = + Uri.of_absolute( + {Uri.default_absolute with + schema = {some = "http"} : option(string) + domain = "localhost" + port = {some = 8080} : option(int) + path = ["_rest_", topic] + } + ) + +@publish load_source(topic) = + match WebClient.Get.try_get(uri_for_topic(topic)) with + | {failure = _} -> "Error, could not connect" + | {~success} -> + match WebClient.Result.get_class(success) with + | {success} -> success.content + | _ -> "Error {success.code}" + end -@publish load_source(topic) = match WebClient.Get.try_get(uri_for_topic(topic)) with - | {failure = _} -> "Error, could not connect" - | {~success} -> match WebClient.Result.get_class(success) with - | {success} -> success.content - | _ -> "Error {success.code}" - end @publish load_rendered(topic) = - source = load_source(topic) - match Template.try_parse( Template.default, source) with - | {failure = _} -> <>{source} - | ~{success}-> Template.to_xhtml(Template.default, success) + source = load_source(topic) + Markdown.xhtml_of_string(Markdown.default_options, source) @publish save_source(topic, source) = - match Template.try_parse(Template.default, source) with - | ~{success} -> match WebClient.Post.try_post(uri_for_topic(topic), source) with - | { failure = _ } -> {failure = "Could not reach distant server"} - | { success = s } -> match WebClient.Result.get_class(s) with - | {success} -> {success = Template.to_xhtml(Template.default, success)} - | _ -> {failure = "Error {s.code}"} - end - end - | {failure = _} -> {failure = "Incorrect syntax"} + match WebClient.Post.try_post(uri_for_topic(topic), source) with + | { failure = _ } -> + {failure = "Could not reach the distant server"} + | { success = s } -> + match WebClient.Result.get_class(s) with + | {success} -> {success = load_rendered(topic)} + | _ -> {failure = "Error {s.code}"} + end remove_topic(topic) = - _ = WebClient.Delete.try_delete(uri_for_topic(topic)) - void + _ = WebClient.Delete.try_delete(uri_for_topic(topic)) + void edit(topic) = - do Dom.transform([#show_messages <- <>]) - do Dom.set_value(#edit_content, load_source(topic)) - do Dom.hide(#show_content) - do Dom.show(#edit_content) - do Dom.give_focus(#edit_content) - void + do Dom.transform([#show_messages <- <>]) + do Dom.set_value(#edit_content, load_source(topic)) + do Dom.hide(#show_content) + do Dom.show(#edit_content) + do Dom.give_focus(#edit_content) + void save(topic) = - match save_source(topic, Dom.get_value(#edit_content)) with - | { ~success } -> - do Dom.transform([#show_content <- success]); - do Dom.hide(#edit_content); - do Dom.show(#show_content); - void - | {~failure} -> - do Dom.transform([#show_messages <- <>{failure}]) - void + match save_source(topic, Dom.get_value(#edit_content)) with + | { ~success } -> + do Dom.transform([#show_content <- success]); + do Dom.hide(#edit_content); + do Dom.show(#show_content); + void + | {~failure} -> + do Dom.transform([#show_messages <- <>{failure}]) + void display(topic) = - Resource.styled_page("About {topic}", ["/resources/css.css"], -
-
-
158 doc/book/hello_web_services/hello_wiki_rest_client_customizable.opa
 @@ -1,108 +1,106 @@ -import stdlib.web.template +import stdlib.tools.markdown uri_for_topic = - domain_parser = {CommandLine.default_parser with - names = ["--wiki-server-domain"] - description = "The REST server for this wiki. By default, localhost." - on_param(x) = parser y=Rule.consume -> {no_params = {x with domain = y}} + domain_parser = + {CommandLine.default_parser with + names = ["--wiki-server-domain"] + description = "The REST server for this wiki. By default, localhost." + on_param(x) = parser y=Rule.consume -> {no_params = {x with domain = y}} } - port_parser = {CommandLine.default_parser with - names = ["--wiki-server-port"] - description = "The server port of the REST server for this wiki. By default, 8080." - on_param(x) = parser y=Rule.natural -> {no_params = {x with port = {some = y}}} + port_parser = + {CommandLine.default_parser with + names = ["--wiki-server-port"] + description = "The server port of the REST server for this wiki. By default, 8080." + on_param(x) = parser y=Rule.natural -> {no_params = {x with port = {some = y}}} } - base_uri = CommandLine.filter({title = "Wiki arguments" - init = {Uri.default_absolute with domain = "localhost" - schema = {some = "http"}} - parsers = [domain_parser, port_parser] - anonymous = [] - }) - topic -> Uri.of_absolute({base_uri with path = ["_rest_", topic]}) + base_uri = + CommandLine.filter( + {title = "Wiki arguments" + init = {Uri.default_absolute with domain = "localhost" schema = {some = "http"}} + parsers = [domain_parser, port_parser] + anonymous = [] + } + ) + topic -> Uri.of_absolute({base_uri with path = ["_rest_", topic]}) -@publish load_source(topic) = - match WebClient.Get.try_get(uri_for_topic(topic)) with - | {failure = _} -> "Error, could not connect" - | {~success} -> match WebClient.Result.get_class(success) with - | {success} -> success.content - | _ -> "Error {success.code}" - end +@publish load_source(topic) = + match WebClient.Get.try_get(uri_for_topic(topic)) with + | {failure = _} -> "Error, could not connect" + | {~success} -> + match WebClient.Result.get_class(success) with + | {success} -> success.content + | _ -> "Error {success.code}" + end @publish load_rendered(topic) = - source = load_source(topic) - match Template.try_parse( Template.default, source) with - | {failure = _} -> <>{source} - | ~{success}-> Template.to_xhtml(Template.default, success) + source = load_source(topic) + Markdown.xhtml_of_string(Markdown.default_options, source) @publish save_source(topic, source) = - match Template.try_parse(Template.default, source) with - | ~{success} -> match WebClient.Post.try_post(uri_for_topic(topic), source) with - | { failure = _ } -> {failure = "Could not reach distant server"} - | { success = s } -> match WebClient.Result.get_class(s) with - | {success} -> {success = Template.to_xhtml(Template.default, success)} - | _ -> {failure = "Error {s.code}"} - end - end - | {failure = _} -> {failure = "Incorrect syntax"} + match WebClient.Post.try_post(uri_for_topic(topic), source) with + | { failure = _ } -> + {failure = "Could not reach the distant server"} + | { success = s } -> + match WebClient.Result.get_class(s) with + | {success} -> {success = load_rendered(topic)} + | _ -> {failure = "Error {s.code}"} + end remove_topic(topic) = - _ = WebClient.Delete.try_delete(uri_for_topic(topic)) - void + _ = WebClient.Delete.try_delete(uri_for_topic(topic)) + void edit(topic) = - do Dom.transform([#show_messages <- <>]) - do Dom.set_value(#edit_content, load_source(topic)) - do Dom.hide(#show_content) - do Dom.show(#edit_content) - do Dom.give_focus(#edit_content) - void + do Dom.transform([#show_messages <- <>]) + do Dom.set_value(#edit_content, load_source(topic)) + do Dom.hide(#show_content) + do Dom.show(#edit_content) + do Dom.give_focus(#edit_content) + void save(topic) = - match save_source(topic, Dom.get_value(#edit_content)) with - | { ~success } -> - do Dom.transform([#show_content <- success]); - do Dom.hide(#edit_content); - do Dom.show(#show_content); - void - | {~failure} -> - do Dom.transform([#show_messages <- <>{failure}]) - void + match save_source(topic, Dom.get_value(#edit_content)) with + | { ~success } -> + do Dom.transform([#show_content <- success]); + do Dom.hide(#edit_content); + do Dom.show(#show_content); + void + | {~failure} -> + do Dom.transform([#show_messages <- <>{failure}]) + void display(topic) = - Resource.styled_page("About {topic}", ["/resources/css.css"], -