<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bobby Priambodo</title>
    <description>The latest articles on Forem by Bobby Priambodo (@bobbypriambodo).</description>
    <link>https://forem.com/bobbypriambodo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2018%2F83a6ea2a-3b5b-44b0-a3d9-540a8353a452.jpg</url>
      <title>Forem: Bobby Priambodo</title>
      <link>https://forem.com/bobbypriambodo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bobbypriambodo"/>
    <language>en</language>
    <item>
      <title>When reading a thorough tutorial, would you rather read it in a single long article or multiple short articles?</title>
      <dc:creator>Bobby Priambodo</dc:creator>
      <pubDate>Sat, 17 Mar 2018 12:32:50 +0000</pubDate>
      <link>https://forem.com/bobbypriambodo/when-reading-a-thorough-tutorial-would-you-rather-read-it-in-a-single-long-article-or-multiple-short-articles-cb0</link>
      <guid>https://forem.com/bobbypriambodo/when-reading-a-thorough-tutorial-would-you-rather-read-it-in-a-single-long-article-or-multiple-short-articles-cb0</guid>
      <description>&lt;p&gt;I'm writing a tutorial, but based on the sections I have outlined I imagine it would be somewhat lengthy for a single post (e.g. more than 4000 words).&lt;/p&gt;

&lt;p&gt;Think of a tutorial in building a complete (although simple) app. The goal is not the end result of the app per se, but rather walking through the development phase, tying things together, in a beginner-friendly way.&lt;/p&gt;

&lt;p&gt;Would love input on which method you prefer and why. Thanks!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Getting your feet wet with OCaml</title>
      <dc:creator>Bobby Priambodo</dc:creator>
      <pubDate>Thu, 14 Dec 2017 13:18:18 +0000</pubDate>
      <link>https://forem.com/bobbypriambodo/getting-your-feet-wet-with-ocaml-dp8</link>
      <guid>https://forem.com/bobbypriambodo/getting-your-feet-wet-with-ocaml-dp8</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published &lt;a href="https://medium.com/@bobbypriambodo/getting-your-feet-wet-with-ocaml-ea1045b6efbc"&gt;on Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have a confession to make: I love OCaml. It was love at nth sight, with n is a sufficiently small positive integer (kept putting it off in favor of Elixir and Haskell, but I have come to regret it).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ocaml.org/"&gt;OCaml&lt;/a&gt; is statically- and strongly-typed, (mostly) functional, fast, safe, and compiled to native, resulting in a single executable binary. The compiler is blazingly fast, and its Hindley-Milner type system (same as for Haskell) is so sophisticated that you don’t need to over-annotate your program and still be type-safe. I’ve always been looking for a fast compiled-to-native—preferably functional—language and OCaml seems to fit the bill so well.&lt;/p&gt;

&lt;p&gt;After bashing Java for years in college, working with JavaScript for a year after I graduated, and almost another year working with Java (karma?), I can’t help but appreciate languages that have explicit types. The compiler is a very great, smart friend that can actually stop you from stupid things like using wrong types in your code. OCaml’s compiler is even more so. And it’s blazingly fast!&lt;/p&gt;

&lt;p&gt;So here I am now, trying to share the love with you. But first, why OCaml?&lt;/p&gt;

&lt;h3&gt;
  
  
  The rise of ReasonML
&lt;/h3&gt;

&lt;p&gt;One trend that has seem to arise on my Twitter feed is &lt;a href="https://reasonml.github.io/"&gt;ReasonML&lt;/a&gt;. Reason is a syntax and toolchain for OCaml from the folks at Facebook. To oversimplify, it’s a new face to OCaml; along with the sister project &lt;a href="https://bucklescript.github.io/"&gt;BuckleScript&lt;/a&gt;, we can write OCaml with a JS-ish syntax that is type-safe and can target JS and native (even mobile!). It is evident that it’s gaining traction on Twitter sphere and other online platforms. Even &lt;a href="https://twitter.com/dan_abramov"&gt;Dan&lt;/a&gt; said so:&lt;/p&gt;

&lt;blockquote data-lang="en"&gt;
&lt;p&gt;Fun pattern I noticed while making this list: people who came to the &lt;a href="https://twitter.com/reactjs?ref_src=twsrc%5Etfw"&gt;@reactjs&lt;/a&gt; community early are now mostly tweeting about &lt;a href="https://twitter.com/reasonml?ref_src=twsrc%5Etfw"&gt;@reasonml&lt;/a&gt;.&lt;/p&gt;— Dan Abramov (&lt;a class="mentioned-user" href="https://dev.to/dan_abramov"&gt;@dan_abramov&lt;/a&gt;
) &lt;a href="https://twitter.com/dan_abramov/status/937355817350828033?ref_src=twsrc%5Etfw"&gt;December 3, 2017&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;span&gt;Acknowledgement from Dan!&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;As with the rise of any technology, new tutorials, articles, and videos start to sprout here and there. I’d also like to contribute, but I thought it might be interesting to cover from the OCaml side of things! It is a bit unfortunate that even though OCaml is not a new language, the materials surrounding it is a bit sparse. I’d like to improve that. (It is steadily improving, and Reason without a doubt has a significant contribution there for bringing more people to the ecosystem.)&lt;/p&gt;

&lt;p&gt;The goal of this article is to get you up and running with an installation of OCaml on your computer to actually try and explore stuff. I’m not going to cover syntaxes and such, only about setting up the development environment. Hopefully this can help fellow beginners who are interested in OCaml. I also will provide you some links at the end to follow-up should you want to explore more.&lt;/p&gt;

&lt;p&gt;Some disclaimers: you’re not going to get much of Reason here, but I believe the information in this article can also benefit you if you wish to dig deeper. Also, it’s necessary to inform you that Windows story is a bit under represented in OCaml, and AFAIK some parts are broken, so I have to assume that you’re running on either Linux, MacOS, or a VM.&lt;/p&gt;

&lt;p&gt;Well then, let’s get to it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Fun stuff: to install OCaml, you don’t need to install OCaml! (Well, at least not right away.)&lt;/p&gt;

&lt;p&gt;What you need first is &lt;a href="http://opam.ocaml.org/"&gt;opam&lt;/a&gt;, the OCaml package manager. If you come from other languages, opam is pretty much &lt;em&gt;rustup + cargo&lt;/em&gt; (Rust); &lt;em&gt;nvm + npm&lt;/em&gt; (Node.js); &lt;em&gt;rbenv/rvm + gem&lt;/em&gt; (Ruby); &lt;em&gt;stack&lt;/em&gt; (Haskell); &lt;em&gt;pyenv + pip&lt;/em&gt; (Python); and others alike. Basically, it is both OCaml version manager &lt;em&gt;and&lt;/em&gt; package manager.&lt;/p&gt;

&lt;p&gt;I’m going to walk you through installing the beta version of opam v2 (2.0.0~beta5 at the point of this writing). The current official stable version is v1.2.2, but I’ve been using v2 beta for months and feel that it’s stable enough for daily use.&lt;/p&gt;

&lt;p&gt;To install, open up your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://raw.github.com/ocaml/opam/master/shell/install.sh
$ chmod +x install.sh
$ ./install.sh --fresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we do three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Download the install script from the repo&lt;/li&gt;
&lt;li&gt; Make the script executable&lt;/li&gt;
&lt;li&gt; Run the script (you may inspect the content of &lt;code&gt;install.sh&lt;/code&gt; first before running it).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can also use the one-liner: &lt;code&gt;wget https://raw.github.com/ocaml/opam/master/shell/install.sh -O - | sh -s -- --fresh&lt;/code&gt;. Note that in general running a shell script from the internet should be done with caution, therefore I advise to inspect the content first.&lt;/p&gt;

&lt;p&gt;The script will download the pre-compiled opam binary (of around 5 MB in size) from the &lt;a href="https://github.com/ocaml/opam/releases"&gt;GitHub releases page&lt;/a&gt; that matches your architecture. It currently has binaries for Linux (i686, arm64, armhf), OpenBSD (amd64), and MacOS/OSX (x86_64). If you already have opam installed, it will make a backup of both your old binary and &lt;code&gt;.opam&lt;/code&gt; directory, so it’s safe!&lt;/p&gt;

&lt;p&gt;After downloading, it will ask you where to put the binary. Unless you have a specific reason not to, the default &lt;code&gt;/usr/local/bin&lt;/code&gt; works fine. Make sure that whatever the destination directory is, it is available on your $PATH.&lt;/p&gt;

&lt;p&gt;Verify the installation by running &lt;code&gt;opam --version&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam --version
2.0.0~beta5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! We have opam up and running. You can now delete &lt;code&gt;install.sh&lt;/code&gt; if you want since we don’t need it anymore.&lt;/p&gt;

&lt;p&gt;Next up, we are going to initialize our opam environment. Run this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Check installed and available version controls on your computer (e.g. git, darcs, mercurial)&lt;/li&gt;
&lt;li&gt; Fetch opam repository information (basically where OCaml third party packages are listed)&lt;/li&gt;
&lt;li&gt; Prompt you to add an entry to your &lt;code&gt;.bashrc&lt;/code&gt;/&lt;code&gt;.zshrc&lt;/code&gt;/&lt;code&gt;.*rc&lt;/code&gt; file to setup opam environment. The default is no (n), but you will most likely want to say yes (y). This will save you from having to execute some extra commands everytime you open a terminal.&lt;/li&gt;
&lt;li&gt; Install OCaml for you!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the time of this writing, the latest stable OCaml version is 4.06.0, so that’s what I get on step 4. On installation, this might take some really long time depending on your computer’s spec (particularly on the commands &lt;code&gt;make world&lt;/code&gt; and &lt;code&gt;make world.opt&lt;/code&gt;), and this is fine. That’s because we’re compiling the OCaml binary from source. It might be best to get used to this since it will happen occasionally, e.g. when we want to switch OCaml versions or when we want to start hacking on a recently created/cloned project.&lt;/p&gt;

&lt;p&gt;(Note: opam related files are isolated inside the &lt;code&gt;~/.opam&lt;/code&gt; directory, so if you want to uninstall it’s as simple as removing that directory, removing the entry added at your &lt;code&gt;.*rc&lt;/code&gt; file from step 3 above, and removing the opam binary itself.)&lt;/p&gt;

&lt;p&gt;Afterwards, you can verify the OCaml installation with &lt;code&gt;ocaml --version&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocaml --version
The OCaml toplevel, version 4.06.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neat! We can now try the builtin REPL, officially called “toplevel”, by invoking &lt;code&gt;ocaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocaml
       OCaml version 4.06.0

#
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#&lt;/code&gt; sign is a prompt. We can use it for a simple calculator like such (note: the double semi &lt;code&gt;;;&lt;/code&gt; is used to mark the end of an expression):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocaml
       OCaml version 4.06.0

# 1 + 1;;
- : int = 2
# 2 + 10 * 3;;
- : int = 32
# "hello " ^ "world!"
- : string = "hello world!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats! Your OCaml installation is working properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switching OCaml versions
&lt;/h2&gt;

&lt;p&gt;One action that you will perform every now and then is switching OCaml versions. As I have described above, opam is also a version manager; that means you can have multiple OCaml compiler versions on your computer and the ability to switch between them at will.&lt;/p&gt;

&lt;p&gt;You are also able to have version aliases, say you want to have two aliases &lt;code&gt;project-a&lt;/code&gt; and &lt;code&gt;project-b&lt;/code&gt;, each using the same OCaml version. The two is considered two different “switch”-es, completely isolated from one another. This is particularly great for dependency isolations — OCaml expects packages to be available globally, and you can imagine the version-conflict troubles it would cause if we use a global namespace for all of our projects’ dependencies. (There are also a neat new feature on opam v2 called &lt;em&gt;local switches&lt;/em&gt;, but we’re not going there in this article.)&lt;/p&gt;

&lt;p&gt;Now that you have the latest 4.06.0 installed, let’s switch to a slightly older version. A good use case of this is that 4.06.0 was just recently released and introduced a (necessary) breaking change, which currently causes many libraries failing to build (&lt;a href="http://obi.ocamllabs.io/triage.html"&gt;more on that here&lt;/a&gt;). So, let’s switch to the older stable version: 4.05.0! Run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam switch create 4.05.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will again download the source of the 4.05.0 compiler and build it locally.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Yes, it will take some time. Better go get your coffee!)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After it’s done, it will advertise a command that you would need to run. Let’s run it now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ eval $(opam env)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will set the necessary environment variables to correctly point to the newly installed switch. To list the installed switches, we can run &lt;code&gt;opam switch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam switch
#   switch   compiler                    description
-&amp;gt;  4.05.0   ocaml-base-compiler.4.05.0  4.05.0
    default  ocaml-base-compiler.4.06.0  default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that we are now using the 4.05.0 switch. You may also notice that the 4.06.0 one has &lt;code&gt;default&lt;/code&gt; as its name. You can switch back to it easily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam switch default
# Run eval $(opam env) to update the current shell environment
$ eval $(opam env)
$ opam switch
#   switch   compiler                    description
    4.05.0   ocaml-base-compiler.4.05.0  4.05.0
-&amp;gt;  default  ocaml-base-compiler.4.06.0  default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice! Switching between, uh, switches, are so fast. You can create switch aliases with &lt;code&gt;opam switch create &amp;lt;name&amp;gt; &amp;lt;compiler&amp;gt;&lt;/code&gt;, for example &lt;code&gt;opam switch create project-a 4.05.0&lt;/code&gt;, which will create a &lt;code&gt;project-a&lt;/code&gt; switch using 4.05.0 as the base compiler. Note that this command will again rebuild the compiler locally, even when you already have a 4.05.0 switch installed!&lt;/p&gt;

&lt;p&gt;(If you’re using ReasonML and/or BuckleScript, this is where you can use &lt;code&gt;4.02.3+buckle-master&lt;/code&gt; as the compiler to get the compatible version.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing, compiling, and running programs
&lt;/h2&gt;

&lt;p&gt;Okay! Now we’re going to try to write a simple program, compiling it to a native executable, and running it. Make sure to switch back to 4.05.0 for the purpose of this experiment (&lt;code&gt;opam switch 4.05.0 &amp;amp;&amp;amp; eval $(opam env)&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Let’s come up with your everyday simple program that prints “Hello, OCaml!” to the standard output. Open up your favorite text editor and write this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="bp"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;print_endline&lt;/span&gt; &lt;span class="s2"&gt;"Hello, OCaml!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it as &lt;code&gt;hello.ml&lt;/code&gt;. We have the source code, now let’s compile it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocamlopt hello.ml -o hello
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will compile &lt;code&gt;hello.ml&lt;/code&gt; into a native executable named &lt;code&gt;hello&lt;/code&gt;. Let’s now try to run it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./hello
Hello, OCaml!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works perfectly! How about if we introduce type errors? Let’s try with this program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ocaml"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="s2"&gt;"not a number"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save it as &lt;code&gt;should_error.ml&lt;/code&gt;. What happens when you try to compile it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocamlopt should_error.ml -o should_error
 This expression has type string but an expression was expected of type
         int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In OCaml, you cannot “+” an integer and a string, because the &lt;code&gt;+&lt;/code&gt; operator only operates on integers, so that resulted in a compile error! Thankfully no weird results such as &lt;code&gt;1not a number&lt;/code&gt; or &lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can play around with the file to write more OCaml code, compile, and run it.&lt;/p&gt;

&lt;p&gt;Note, however, that you will seldom use &lt;code&gt;ocamlopt&lt;/code&gt; directly to compile programs that have multiple files and complex directory structures that uses third party packages, because you would need to enumerate and wire &lt;em&gt;all&lt;/em&gt; the files and packages that your program depend on. Fortunately, there are several tools out there that simplifies this for us, and the majority of the community is converging to Jane Street’s &lt;a href="https://github.com/janestreet/jbuilder"&gt;jbuilder&lt;/a&gt; as the de facto build system.&lt;/p&gt;

&lt;p&gt;I will not delve into the topic of build systems further, perhaps that’s for another article on another time. Just remember that you’re in good hands! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing libraries and programs with opam
&lt;/h2&gt;

&lt;p&gt;The last thing I want to share with you in this article is how we install third party libraries and programs via opam. Let’s differentiate the two:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;em&gt;Libraries&lt;/em&gt; are packages that are meant to be used programmatically in code; while&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Programs&lt;/em&gt; are packages that provide executables that you can run, e.g. via command-line.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A package can act as both a program and library, that is, they provide a command-line executable and an API to use it programmatically. Note that “program” and “library” are terms that I come up with myself for explanation purposes, I‘m not sure if there’s a convention for that already.&lt;/p&gt;

&lt;p&gt;In the perspective of opam, there are no significant differences between the two; only that programs usually have extra steps after downloading the source, which is to copy the resulting executable binary. Installing packages for both programs and libraries are done using the &lt;code&gt;opam install&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Let’s try to install a program, &lt;code&gt;ocp-indent&lt;/code&gt;. It is a utility program that is used to format your OCaml source code to make sure it have proper indentation format (very useful!). Run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam install ocp-indent
The following actions will be performed:
  - install result     1.2          [required by cmdliner]
  ...snip 8&amp;lt;...
===== 9 to install =====
Do you want to continue ? [Y/n]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will list the packages to install. Notice that we will install 9 of them, because &lt;code&gt;ocp-indent&lt;/code&gt; depends on 8 other packages for it to work — and opam resolved them automatically for us! Answer &lt;code&gt;Y&lt;/code&gt; (or just enter) to make it proceed with the installation.&lt;/p&gt;

&lt;p&gt;First, opam will download the sources (subsequent installs will get them from local cache). Then, opam will build all the packages. If you notice, each of the packages may use different command for building, e.g. &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;jbuilder build&lt;/code&gt;, etc. That is because each package provides its own build instructions. That way library authors can have flexibility on what build systems they use.&lt;/p&gt;

&lt;p&gt;After the process is done, you will have the &lt;code&gt;ocp-indent&lt;/code&gt; program installed. Let’s try it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ocp-indent --version
1.6.1
$ ocp-indent hello.ml
let () =
  print_endline "Hello, OCaml!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! You can try for example adding more spaces before &lt;code&gt;print_endline&lt;/code&gt; and run &lt;code&gt;ocp-indent&lt;/code&gt; again on &lt;code&gt;hello.ml&lt;/code&gt;, and it should print out the program with correct indentation. To actually modify the file, you can provide the &lt;code&gt;-i&lt;/code&gt; flag (or &lt;code&gt;--inplace&lt;/code&gt;) , e.g. &lt;code&gt;ocp-indent hello.ml -i&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So that’s a program! Now, let’s try to install a library package. We’re going to install &lt;code&gt;alcotest&lt;/code&gt;, a lightweight testing framework.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ opam install alcotest
The following actions will be performed:
  - install astring  0.8.3      [required by alcotest]
  ...snip 8&amp;lt;...
===== 5 to install =====
Do you want to continue ? [Y/n]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time it’s going to install 5 packages. Let’s proceed with &lt;code&gt;Y&lt;/code&gt;. It will again download and build the sources.&lt;/p&gt;

&lt;p&gt;After it’s done, how about we try it?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ alcotest
zsh: command not found: alcotest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uh-oh, what happened? Turns out that &lt;code&gt;alcotest&lt;/code&gt; is a library, and therefore it doesn’t provide any command-line executables. Alcotest is meant to be used from code. We’re not going to talk about how to use it now, of course; I just want to give you a look on how programs and libraries differ.&lt;/p&gt;

&lt;p&gt;Okay, so how to list the packages that we have installed? We can use &lt;code&gt;opam list&lt;/code&gt;. Try it now! It will list all packages that is installed. You can also use &lt;code&gt;opam list --installed-root&lt;/code&gt; to see the packages you &lt;em&gt;directly&lt;/em&gt; installed, cutting out the transitive dependencies.&lt;/p&gt;

&lt;p&gt;Package installations are local to the current switch. If you switch to another compiler switch and do &lt;code&gt;opam list&lt;/code&gt;, you will see that the installed packages on the previous switch is gone! Again, because packages are expected to be installed “globally”, this is done so that each switch can have isolation on their installed packages, and projects won’t need to worry about version conflicts.&lt;/p&gt;

&lt;p&gt;I hope that you get the gist of installation of packages with opam now! That also concludes my introduction tour to the OCaml ecosystem.&lt;/p&gt;

&lt;p&gt;Are your feet wet enough?&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what’s next?
&lt;/h2&gt;

&lt;p&gt;In this article we have installed opam, installed an OCaml compiler, learned how to switch compiler versions, how to compile and run OCaml programs, and how to install third party packages. Where to go from here?&lt;/p&gt;

&lt;p&gt;For starters, you can explore the official &lt;a href="http://ocaml.org/learn/tutorials/"&gt;Tutorials page&lt;/a&gt;. I recommend skimming the &lt;a href="http://ocaml.org/learn/tutorials/basics.html#Comments"&gt;Basics&lt;/a&gt;, reading the &lt;a href="http://ocaml.org/learn/tutorials/structure_of_ocaml_programs.html"&gt;Structure of OCaml Programs&lt;/a&gt;, and go through the rest in sequential fashion on your own pace. It will give you a good view of the capabilities of the language.&lt;/p&gt;

&lt;p&gt;One canonical resource that most folks recommend is the &lt;a href="https://dev.realworldocaml.org/"&gt;Real World OCaml&lt;/a&gt; book, which is available for free online. &lt;a href="http://ocaml-book.com/"&gt;OCaml from the Very Beginning&lt;/a&gt; is also a recommended book as an entry point.&lt;/p&gt;

&lt;p&gt;I am planning to write more articles on OCaml. Two that I have jotted down on my notes are, in no particular order: setting up your text editor environment for OCaml development, and also building and publishing OCaml packages with jbuilder and topkg. I’m not promising anything yet, though! :D&lt;/p&gt;

&lt;p&gt;I have also written an article about building a lightweight Docker image using multi-stage builds with OCaml that is available here: &lt;a href="https://medium.com/@bobbypriambodo/lightweight-ocaml-docker-images-with-multi-stage-builds-f7a060c7fce4"&gt;Lightweight OCaml Docker Images with Multi-Stage Builds&lt;/a&gt;. When writing it I was using opam v1.2.2, but with the knowledge from this article it’s only a matter of translating the opam commands to the ones for v2 (the only difference is on switching compilers, which I have shown above).&lt;/p&gt;

&lt;p&gt;Blocked? Have questions? A few channels of communication you can try: &lt;a href="https://discuss.ocaml.org/"&gt;discuss.ocaml.org&lt;/a&gt; official Discourse forum, the &lt;a href="https://discord.gg/reasonml"&gt;ReasonML Discord&lt;/a&gt;, &lt;a href="https://www.reddit.com/r/ocaml/"&gt;/r/ocaml&lt;/a&gt; on Reddit, and #ocaml on Freenode. The community is full of friendly folks more than willing to help you out!&lt;/p&gt;

&lt;p&gt;So that’s it for today, folks! Thanks for reading, I hope you get something out of this post! Tell me in the comments if I can improve anything.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>ocaml</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How do you handle updating project dependencies?</title>
      <dc:creator>Bobby Priambodo</dc:creator>
      <pubDate>Sat, 30 Sep 2017 06:29:22 +0000</pubDate>
      <link>https://forem.com/bobbypriambodo/how-do-you-handle-updating-project-dependencies-7ia</link>
      <guid>https://forem.com/bobbypriambodo/how-do-you-handle-updating-project-dependencies-7ia</guid>
      <description>&lt;p&gt;Most projects use third-party packages as dependency, no matter what languages you use.&lt;/p&gt;

&lt;p&gt;How often do you update your dependencies? Do you automate it, and if yes what tool do you use? Do you use single commit for updating each dep or use one commit for all the deps? Some libs don't provide changelogs that makes it hard to know the changes between versions, what are your thoughts on them (are you using them anyway)? Any other thing that you consider when updating deps?&lt;/p&gt;

&lt;p&gt;Suggestions, anecdotes, any kind of experiences welcome!&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Why I dislike chat-based platforms for OSS communities</title>
      <dc:creator>Bobby Priambodo</dc:creator>
      <pubDate>Thu, 03 Aug 2017 14:52:26 +0000</pubDate>
      <link>https://forem.com/bobbypriambodo/why-i-dislike-chat-based-platforms-for-oss-communities</link>
      <guid>https://forem.com/bobbypriambodo/why-i-dislike-chat-based-platforms-for-oss-communities</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was &lt;a href="https://medium.com/@bobbypriambodo/why-i-dislike-chat-based-platforms-for-oss-communities-f19444302d6d"&gt;first published on Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the past few years, I’ve been trying to keep myself up-to-date with the latest news in technologies that I’m interested in. I started going through the “Community” pages of many OSS products, from programming languages to tools and libraries. I registered and subscribed to many platforms, mailing lists, IRC channels, subreddits, etc.&lt;/p&gt;

&lt;p&gt;Fast-forward to today. Among all the platforms that I tried, I can say with confidence: &lt;strong&gt;I dislike chat-based apps&lt;/strong&gt;. By “chat-based apps”, I am including the most prominent ones on this field, such as Slack, Discord, IRC, and Gitter. By “dislike” I mean that I prefer not to use them if possible, unless the issue is pressing and no other choice is available. Unfortunately, several communities seem to use it as their primary channel of communication.&lt;/p&gt;

&lt;p&gt;Note that I’m not saying that Slack et al are bad products. I use Slack at work and it’s been very helpful with its integrations and such. Seeing how most communities have at least one chat-based channel, I also believe that it definitely has value for some–if not most–people.&lt;/p&gt;

&lt;p&gt;Now, with that out of the way, let me tell you why I think the way I do.&lt;/p&gt;




&lt;p&gt;I dislike chat-based apps because they are &lt;strong&gt;synchronously real-time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What’s so bad about it? Real-time is good! We make everything real-time nowadays!&lt;/em&gt; Well, Let’s see how being synchronously real-time can hurt communications and the community as a whole.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Great conversations vanish into thin air
&lt;/h2&gt;

&lt;p&gt;At times when I lurk at some Slacks and Discords, I can’t deny that is where many discussions on interesting topics got initiated. It also solves many issues that needs to be solved immediately.&lt;/p&gt;

&lt;p&gt;But then that’s that. The discussions and solutions there are not globally searchable. AFAIK there’s still no way a google search could point to a specific point of conversation in a Slack channel, so it’s not really SEO-friendly. Perhaps it helped one user, but it will not help the next person, and they would need to ask the question again.&lt;/p&gt;

&lt;p&gt;Unless someone put the result of discussions into a blog or something, there will be no record of the exchanges whatsoever. Of course, there actually can be a record, by using services such as &lt;a href="https://slackarchive.io/"&gt;SlackArchive.io&lt;/a&gt;. But good luck finding specific conversation there–which brings me to the next issue…&lt;/p&gt;

&lt;h2&gt;
  
  
  2. It’s unorganized and hard to keep track of conversations
&lt;/h2&gt;

&lt;p&gt;With many people speaking at the same time, there’s a high possibility of race conditions. Two or more questions got asked at the same time and many people tried answering them in the same manner. &lt;em&gt;Who’s replying to who? Has the other person finished writing their answer?&lt;/em&gt; There is no logical way to group messages. Even after Slack introduced &lt;a href="https://get.slack.help/hc/en-us/articles/115000769927-Message-threads"&gt;message threads&lt;/a&gt;, I never see anyone actually uses it in OSS Slack channels. They mostly stick with the IRC style of conversation.&lt;/p&gt;

&lt;p&gt;As software engineers/developers, we embrace efficiency. We embrace the DRY principle. It should be the same with questions–the same question should not be asked twice, or at least there should be a way to answer the second question by only a reference to the first one. It would save everyone’s time. Stack Overflow does it with duplicate questions. Quora does it with merging questions. You would need to search for a similar question before posting your own. But that is impossible in chat-based apps; you have no choice but to ask the question again–not knowing if it has been asked and answered before.&lt;/p&gt;

&lt;p&gt;Seriously, I’ve seen an instance where a question was answered by “please scroll up a few hours”. For longer than a few hours (or less if the channel is really active), the answerer would have no choice but to write their answer again.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. It’s distracting
&lt;/h2&gt;

&lt;p&gt;It being synchronous means that if I post something, I would need to keep the window open and focused to see whether or not I get responses. It’s good if someone mentions your handle when they answer and you receive notifications, but at times they don’t. I simply can’t do other things; leaving the app would introduce the possibility that the response (if any) is far up already; drowned in other chats.&lt;/p&gt;

&lt;p&gt;It’s even more distracting than Facebook and Twitter, which I am able to open only occasionally and not miss out on many things.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Language barrier for non-English speakers
&lt;/h2&gt;

&lt;p&gt;It being real-time might introduce problems to non-English speaking users that may not be used to expressing their ideas in English. It might take time for them to write questions, and write the replies to the answers. My English is not perfect, and there are times when I can’t find the vocabulary that I needed to express what I want to know exactly. The real-time aspect of chats can be intimidating.&lt;/p&gt;

&lt;p&gt;Of course, me being generally an introvert might have something to do with that, and I’m trying to improve my English over time. However, doing things less real-time-y and asynchronously would certainly help me compose better messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Timezone issues
&lt;/h2&gt;

&lt;p&gt;This is where chat-based apps being synchronously real-time hits me hard. I live in Indonesia, and the timezone here is UTC+7. The timezone in the US (where most interesting things happen) ranges from UTC-8 to UTC-4, which roughly translates to 12 hours difference from here. That means their noon is my midnight.&lt;/p&gt;

&lt;p&gt;I don’t know about you, but I’m not keen on the idea of asking questions in the middle of the night, even when doing so will get more active responses from the folks on the other side of the world.&lt;/p&gt;




&lt;h1&gt;
  
  
  So what’s the solution?
&lt;/h1&gt;

&lt;p&gt;What platform gives us the capability to record and group discussions, communicate asynchronously, navigate through conversations, and be globally searchable and SEO-friendly?&lt;/p&gt;

&lt;p&gt;Reddit or mailing lists come to mind. I’m not exactly a fan of Reddit’s or Hacker News’ threaded discussions as it is not chronological, although navigating to parent post and replies are a breeze. Mailing lists on the other hand, are a bit better, but too linear. There are also no way to “mention” a participant, and it has poor support for code blocks. Subscribing to too many mailing lists might also make your inbox unwieldy, even when it is labeled differently.&lt;/p&gt;

&lt;p&gt;I am finding &lt;a href="https://www.discourse.org/"&gt;Discourse&lt;/a&gt; as the most ideal communication channel that I have experienced so far. There are many communities go down this path: &lt;a href="https://elixirforum.com/"&gt;Elixir&lt;/a&gt;, &lt;a href="https://forums.docker.com/"&gt;Docker&lt;/a&gt;, &lt;a href="https://discuss.kotlinlang.org/"&gt;Kotlin&lt;/a&gt;, &lt;a href="https://forum.golangbridge.org/"&gt;Go&lt;/a&gt;, and &lt;a href="https://users.rust-lang.org/"&gt;Rust&lt;/a&gt; to name a few, and they are arguably several of the best OSS communities out there. I know there’s &lt;a href="https://discuss.reactjs.org/"&gt;one for React&lt;/a&gt;, but I’m not sure how active it is. I am delighted that the OCaml community has also started to migrate the discussions from the mailing list to the &lt;a href="https://discuss.ocaml.org/"&gt;new forum&lt;/a&gt; (although it might take some time for it to get traction).&lt;/p&gt;

&lt;p&gt;FWIW, I am also a fan of Twitter for being my one-stop news outlet and community channel for tech related things. I follow many devs and that fills my timeline with so many great discussions and blog posts, and fewer fake news.&lt;/p&gt;




&lt;p&gt;So that’s about it! I realize that this is mostly a rant :) If I missed something, or if you think that I am not giving chat-based apps the credit it deserves for bringing together a community, do tell in the comments!&lt;/p&gt;

</description>
      <category>learning</category>
      <category>culture</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
