caml-list - the Caml user's mailing list
 help / Atom feed
From: Alan Schmitt <alan.schmitt@polytechnique.org>
To: "lwn" <lwn@lwn.net>, "cwn"  <cwn@lists.idyll.org>, caml-list@inria.fr, comp@lists.orbitalfox.eu
Subject: [Caml-list] Attn: Development Editor, Latest OCaml Weekly News
Date: Tue, 01 Sep 2020 09:55:51 +0200
Message-ID: <87imcy9bi0.fsf@m4x.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 15200 bytes --]

Hello

Here is the latest OCaml Weekly News, for the week of August 25 to
September 01, 2020.

Table of Contents
─────────────────

Writing bindings for Google Apps Script (GAS)
What the Jane Street interns have wrought
a small library for shell/AWK/Perl-like scripting
letters 0.2.0
raylib-ocaml 0.1.0
OCaml Workshop 2020 Online Conference is live now
Other OCaml News
Old CWN


Writing bindings for Google Apps Script (GAS)
═════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/writing-bindings-for-google-apps-script-gas/6293/1>


Danielo Rodríguez announced
───────────────────────────

  Thanks to the help of this community I successfully completed a crazy
  idea: To write some ocaml functions to use inside [Google Apps Script]
  for a small stupid spreadsheet that I had.

  The way it works now is by having a main index.js file that calls the
  Ocaml functions that are available under a global Lib
  namespace. Everything is bundled using parcel and the Idea was to use
  as few JS code as possible. Because it was easier than I expected I
  decided to go one step further and write some bindings for the GAS
  functions I was using and reduce the glue JS code even more.

  This are the bindings that I wrote so far. They work, but are not
  usable inside Ocaml yet.

  ┌────
  │ type spreadsheet
  │ type sheet
  │ type range
  │ external getActiveSpreadsheet : unit -> spreadsheet = "getActiveSpreadsheet" [@@bs.val][@@bs.scope
  │ "SpreadsheetApp"]
  │ external getSheets : spreadsheet -> sheet array = "getSheets" [@@bs.send]
  │ external getSheetByName : spreadsheet -> string -> sheet = "getSheetByName" [@@bs.send]
  │ external getDataRange : sheet -> range = "getDataRange"  [@@bs.send]
  │ external getValues : range -> 'a array array = "getValues"  [@@bs.send]
  └────

  My doubt are on the edges. When it is just obscure GAS stuff I have no
  doubt, abstract types and functions to interact with them. Is when a
  GAS function returns data where I have doubts. Usually they are just
  arrays of arrays of Numbers or Strings. In the example above, the last
  definition says that you will get an array of arrays of `'a', but that
  is not true because it will be an array of "stuff" (strings, numbers,
  floats).  How should I type it in a way that it's flexible but not
  cumbersome? For example, I don't think using a functor will help
  because you will need to create a functor for every possible return
  type, in my case if you have 3 sheets with 3 different shapes, you
  will need 3 functors.  An alternative that I have used was to provide
  some helper functions to convert from JS to Ocaml types and then
  unwrap the Ocaml types, like the example I'm doing with
  Number_or_string.  This is nothing serious and I will just add the
  bindings that I may need for now, but I want to hear what the
  community (and potential users) thinks.

  If anyone is interested in taking a look on the project, it is here:
  <https://github.com/danielo515/ElectronicProjectsSpreadsheet>


[Google Apps Script] <https://developers.google.com/apps-script>


Matthieu Dubuget said
─────────────────────

  Not answering directly to your question, sorry.

  But here is a binding I have been using for around 4 years:
  <https://dubuget.fr/gitea/matthieu/ocaml-google-app.git>.


Hongbo Zhang also replied
─────────────────────────

  For return type polymorphism, you can use GADT with bs.ignore, the
  rough idea:

  ┌────
  │ type 'a t =  Int : int t | String : string t
  │ external f : ('a t [@bs.ignore]) -> ... -> 'a = "xx"
  └────
  I read discuss.ocaml.org from time to time, but checks
  <https://forum.rescript-lang.org/> daily where you can get a quick
  answer


What the Jane Street interns have wrought
═════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/what-the-jane-street-interns-have-wrought/6294/1>


Yaron Minsky announced
──────────────────────

  I thought folks here might find this interesting:

  <https://blog.janestreet.com/what-the-interns-have-wrought-2020/>

  The post summarizes three of the intern projects that happened this
  summer at Jane Street. It might be interesting if you're looking for
  an internship (or know someone who is), or if you're interested in any
  of the underlying tech. For example, if there's significant interest
  in a library for writing OCaml, we'd be more likely to open-source it.


a small library for shell/AWK/Perl-like scripting
═════════════════════════════════════════════════

  Archive:
  <https://sympa.inria.fr/sympa/arc/caml-list/2020-08/msg00021.html>


Oleg announced
──────────────

  Some time ago Chet Murthy asked about writing shell-like scripts in
  OCaml. Prompted by it, I also want to report on my experience and
  announce a small library that made it pleasant to do
  shell/AWK/Perl-like scripting in OCaml.

  The library is available at
          <http://okmij.org/ftp/ML/myawk/0README.dr>
  and consists of two small ML files, myawk.ml and strings.ml. The
  latter collects general-purpose string operations, more convenient
  than those in Stdlib.String. The rest of that web directory contains
  half a dozen sample scripts with comments.

  Here is the first example: a typical AWK script, but written in OCaml:

  ┌────
  │ #!/bin/env -S ocaml
  │ 
  │ #load "myawk.cma"
  │ open Myawk open Strings
  │ let hash = string_of_int <|> Hashtbl.hash
  │ ;;
  │ (* Sanitize the files originally used by join1.ml and join2.ml
  │    The files are made of space-separated fields; the first field is the
  │    key. It is sensitive; but because it is a key it can't be replaced with
  │    meaningless garbage. We obfuscate it beyond recognition. The third field
  │    is obfuscated as well. The second and fourth can be left as they are,
  │    and the fifth, if present, is replaced with XXX
  │ 
  │    The script is a proper filter: reads from stdin, writes to stdout
  │  *)
  │ 
  │ for_each_line @@ map words @@ function (f1::f2::f3::f4::rest) ->
  │   print [hash f1; f2; hash f3; f4; if rest = [] then "" else "XXX"]
  │ ;;
  └────

  Here <|> is a function composition. I wish it were in Stdlib. The real
  example, used in real life, was performing a database join

  ┌────
  │ SELECT T2.* from Table1 as T1, Table2 as T2 where T1.f1 = T2.f1
  └────

  where Table1 and Table2 are text files with space-separated column
  values. Table1 is supposed to be fed to stdin:

  ┌────
  │ let () =
  │   for_each_line @@ map words @@
  │   map_option (function (x::_) -> Some x | _ -> None) @@
  │   (ignore <|> shell "grep %s table1.txt")
  └────

  It is a typical rough-and-dirty script. Alas, it was too rough: I was
  so excited that it typechecked and worked the first time, that I
  didn't look carefully at the output and overlooked what I was looking
  for (resulting in an unneeded hassle and apology). I should have
  queried exactly for what I wanted:
  ┌────
  │ SELECT T1.f1, T1.f4 FROM Table1 as T1, Table2 as T2
  │ WHERE T1.f1 = T2.f1 AND T1.f3 <> "3"
  └────

  which is actually easy to write in myawk (probably not so in AWK
  though)

  ┌────
  │ let () =
  │   for_each_line ~fname:"table2.txt" @@ map words @@
  │   map_option (function (w::_) -> Some w | _ -> None) @@
  │   fun w ->
  │     for_each_line ~fname:"table1.txt" @@  map words @@
  │     map_option (function
  │      (x::f2::f3::f4::_) when x = w && f4 <> "3" -> Some [x;f4] | _ -> None) @@
  │     print
  └────

  This is the classical nested loop join. Chet Murthy might be pleased
  to see the extensive use of the continuation-passing style. I was
  apprehensive at first, but it turned out not to be a hassle.

  The library has a few other examples, including case-branching and
  rewriting a real AWK script from the OCaml distribution.

  Finally, let's compare with shell scripts. The example below doesn't
  show off the library, but it does show the benefits of OCaml for
  scripting. The original shell script is a sample GIT commit hook,
  quoted in the comments:

  ┌────
  │ (*
  │ From GIT's sample hooks:
  │   ANY-GIT-REPO/.git/hooks/commit-msg.sample
  │ 
  │   # Called by "git commit" with one argument, the name of the file
  │   # that has the commit message.  The hook should exit with non-zero
  │   # status after issuing an appropriate message if it wants to stop the
  │   # commit.  The hook is allowed to edit the commit message file.
  │ 
  │   # This example catches duplicate Signed-off-by lines.
  │ 
  │ test "" = "$(grep '^Signed-off-by: ' "$1" |
  │ 	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
  │ 	echo >&2 Duplicate Signed-off-by lines.
  │ 	exit 1
  │ }
  │ 
  │ *)
  │ module H = Hashtbl
  │ 
  │ let commit_msg = Sys.argv.(1)
  │ let ht = H.create 5
  │ let () =
  │   for_each_line ~fname:commit_msg @@ fun l ->
  │   if is_prefix "Signed-off-by: " l <> None then begin
  │     if H.find_opt ht l <> None then begin
  │       prerr_endline "Duplicate Signed-off-by lines.";
  │       exit 1
  │     end else
  │       H.add ht l ()
  │   end
  └────

  Although the OCaml script seems to have more characters, one doesn't
  need to type them all. Scripts like that are meant to be entered in an
  editor; even ancient editors have completion facilities.

  Looking at the original shell script brings despair, and drives me
  right towards Unix Haters. Not only the script is algorithmically
  ugly: if a duplicate signed-off line occurs near the beginning, we can
  report it right away and stop. We don't need to read the rest of the
  commit message, filter it, sort it, precisely count all duplicates and
  filter again. Not only the script gratuitously wastes system resources
  (read: the laptop battery) by launching many processes and allocating
  communication buffers. Mainly, the script isn't good at its primary
  purpose: it isn't easy to write and read. Pipeline composition of
  small stream processors is generally a good thing – but not when each
  stream processor is written in its own idiosyncratic
  language. Incidentally, I have doubts about the script: I think that
  quotes around $1 are meant to be embedded; but why they are not
  escaped then? Probably it is some edge case of bash, out of several
  0thousands.

  In contrast, OCaml script does exactly what is required, with no extra
  work. Everything is written in only one language.


letters 0.2.0
═════════════

  Archive: <https://discuss.ocaml.org/t/ann-letters-0-2-0/6307/1>


Miko announced
──────────────

  Getting this release done took a bit longer than expected due to some
  real life factors, but finally here it is.

  This one mainly focuses on the most requested features and
  improvements like simplifying configuration around CA certificates,
  provides some basic documentation and additionally adds support for
  `multipart/alternative' emails with combined HTML and plain text
  content.


jerben then added
─────────────────

  Link to Github: <https://github.com/oxidizing/letters>


raylib-ocaml 0.1.0
══════════════════

  Archive: <https://discuss.ocaml.org/t/ann-raylib-ocaml-0-1-0/6313/1>


Tobias Mock announced
─────────────────────

  I'd like to announce the first version of [raylib-ocaml], a binding to
  the awesome [raylib] game development library. The release can be
  found on opam as ["raylib"].

  The bindings are nearly complete, as far as functions and types go,
  but only a subset was tested so far. I will work on bringing more of
  the numerous examples of the C version to OCaml in the future.

  Currently, raylib-ocaml only works on Linux, but I plan to support
  Windows (and possibly other targets) in the future.

  Feel free to give it a spin and please report any issues you run into.


[raylib-ocaml] <https://github.com/tjammer/raylib-ocaml>

[raylib] <https://www.raylib.com/>

["raylib"] <https://opam.ocaml.org/packages/raylib/>


OCaml Workshop 2020 Online Conference is live now
═════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ocaml-workshop-2020-online-conference-is-live-now/6287/30>


Deep in this thread, Didier Wenzek announced
────────────────────────────────────────────

  [OCaml 2020 All Videos]


[OCaml 2020 All Videos]
<https://www.youtube.com/playlist?list=PLKO_ZowsIOu5fHjRj0ua7_QWE_L789K_f>


Other OCaml News
════════════════

>From the ocamlcore planet blog
──────────────────────────────

  Here are links from many OCaml blogs aggregated at [OCaml Planet].

  • [BuckleScript Good and Bad News]
  • [What the interns have wrought, 2020 edition]
  • [Coq 8.12.0 is out]


[OCaml Planet] <http://ocaml.org/community/planet/>

[BuckleScript Good and Bad News]
<http://psellos.com/2020/08/2020.08.east-van-girls.html>

[What the interns have wrought, 2020 edition]
<https://blog.janestreet.com/what-the-interns-have-wrought-2020/>

[Coq 8.12.0 is out] <https://coq.inria.fr/news/coq-8-12-0-is-out.html>


Old CWN
═══════

  If you happen to miss a CWN, you can [send me a message] and I'll mail
  it to you, or go take a look at [the archive] or the [RSS feed of the
  archives].

  If you also wish to receive it every week by mail, you may subscribe
  [online].

  [Alan Schmitt]


[send me a message] <mailto:alan.schmitt@polytechnique.org>

[the archive] <http://alan.petitepomme.net/cwn/>

[RSS feed of the archives] <http://alan.petitepomme.net/cwn/cwn.rss>

[online] <http://lists.idyll.org/listinfo/caml-news-weekly/>

[Alan Schmitt] <http://alan.petitepomme.net/>


[-- Attachment #2: Type: text/html, Size: 34062 bytes --]

         reply index

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-03  7:35 Alan Schmitt
2019-10-15  7:28 Alan Schmitt
2019-11-05  6:55 Alan Schmitt
2019-11-12 13:21 Alan Schmitt
2019-11-26  8:33 Alan Schmitt
2019-12-03 15:43 Alan Schmitt
2019-12-10  8:21 Alan Schmitt
2019-12-17  8:52 Alan Schmitt
2019-12-31  9:18 Alan Schmitt
2020-01-07 13:43 Alan Schmitt
2020-01-14 14:17 Alan Schmitt
2020-01-21 14:09 Alan Schmitt
2020-01-28 10:54 Alan Schmitt
2020-02-04  8:47 Alan Schmitt
2020-02-18  8:18 Alan Schmitt
2020-02-25  8:51 Alan Schmitt
2020-03-03  8:00 Alan Schmitt
2020-03-10 14:29 Alan Schmitt
2020-03-17 11:04 Alan Schmitt
2020-03-24  9:31 Alan Schmitt
2020-03-31  9:55 Alan Schmitt
2020-04-07  7:51 Alan Schmitt
2020-04-14  7:28 Alan Schmitt
2020-04-21  8:58 Alan Schmitt
2020-04-28 12:45 Alan Schmitt
2020-05-05  7:45 Alan Schmitt
2020-05-12  7:46 Alan Schmitt
2020-05-19  9:53 Alan Schmitt
2020-06-09  8:29 Alan Schmitt
2020-06-16  8:36 Alan Schmitt
2020-06-30  7:00 Alan Schmitt
2020-07-07 10:05 Alan Schmitt
2020-07-14  9:55 Alan Schmitt
2020-07-21 14:43 Alan Schmitt
2020-07-28 16:58 Alan Schmitt
2020-08-18  7:26 Alan Schmitt
2020-09-01  7:55 Alan Schmitt [this message]
2020-09-08 13:11 Alan Schmitt
2020-09-22  7:27 Alan Schmitt
2020-09-29  7:02 Alan Schmitt
2020-10-06  7:22 Alan Schmitt
2020-10-20  8:16 Alan Schmitt
2020-10-27  8:44 Alan Schmitt

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87imcy9bi0.fsf@m4x.org \
    --to=alan.schmitt@polytechnique.org \
    --cc=caml-list@inria.fr \
    --cc=comp@lists.orbitalfox.eu \
    --cc=cwn@lists.idyll.org \
    --cc=lwn@lwn.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

caml-list - the Caml user's mailing list

Archives are clonable: git clone --mirror https://inbox.ocaml.org/caml-list

AGPL code for this site: git clone https://public-inbox.org/ public-inbox