[cwn] Attn: Development Editor, Latest OCaml Weekly News
Alan Schmitt
alan.schmitt at polytechnique.org
Tue May 16 06:05:09 PDT 2023
Hello
Here is the latest OCaml Weekly News, for the week of May 09 to 16,
2023.
Table of Contents
─────────────────
Rendering React in OCaml
Ahrefs is Hiring
tmx: Import 2D game maps with ease
Brr 0.0.5, the WebGPU edition
A bestiary of GADT examples?
Open-source tool to make a static blog in OCaml?
BER MetaOCaml N114, for OCaml 4.14.1
Building iOS apps with OCaml?
A Minimal Prototype of In-Package Search is on staging.ocaml.org
New release of Fix (20230505)
QCheck 0.21
Old CWN
Rendering React in OCaml
════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-rendering-react-in-ocaml/12133/1>
David Sancho announced
──────────────────────
Here is `server-reason-react', the OCaml implementation of React I
have been working on:
<https://sancho.dev/blog/server-side-rendering-react-in-ocaml>
The blog post is targeted for a Frontend/JS dev, but I believe it can
be interesting from the OCaml site as well.
`server-reason-react' is an implementation of `react-dom/server' and
some of React’s internals in OCaml. The purpose is to render HTML
markup from the server for a Reason React application natively.
<https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/f/fa3544e3ce933ded735ac9e77c570cff3f1870f5_2_1380x814.jpeg>
It supports hydration (renderToString) and full render
(renderToStaticMarkup) and most unit tests from ReactDOMServer are
migrated as well. Basically, to ensure hydration “hacks” work the same
way as react’s DOM (in JavaScript).
It’s obviously fast, talking about req/s: x10 against Node and x6
against Bun on the same codebase. Performance is not the priority,
though. I did 0 perf work but is cool. If you want to help making it
very fast, let me know!
The priority is to implement streaming and later RSC. Can’t wait to
try OCaml multicore with Server components.
All of this is thanks to Melange, and I’m grateful to work with
[@_anmonteiro] and [@javierwchavarri].
[@_anmonteiro] <https://twitter.com/_anmonteiro>
[@javierwchavarri] <https://twitter.com/javierwchavarri>
Ahrefs is Hiring
════════════════
Archive: <https://discuss.ocaml.org/t/ahrefs-is-hiring/12136/1>
benmonopoli announced
─────────────────────
As always here at Ahrefs we’re on the lookout for OCaml devs.
We are headquartered in Singapore but our team is dotted all over the
place so we’re open to remote too.
Check out our posting [here]
Feel free to reach out for more info.
[here] <https://ahrefs.com/jobs/ocaml-developer>
Louis Roché then added
──────────────────────
To try to give some context as the job post on the website is pretty
dry
Ahrefs is heavily invested in Melange to compile ocaml to javascript.
With it the company is also putting resources to maintain the projects
related to reasonml. Some recent posts from @jchavarri and @davesnx:
• <https://discuss.ocaml.org/t/ahrefs-is-now-built-with-melange/12107>
• <https://discuss.ocaml.org/t/ann-rendering-react-in-ocaml/12133>
A bunch of commonly used libraries that you probably have heard about
are maintained by ahrefs or with the help of ahrefs
• <https://github.com/ahrefs/atd>
• <https://github.com/ahrefs/ocaml-sodium>
• <https://github.com/davesnx/styled-ppx>
• <https://github.com/ygrek/ocaml-extlib>
There’s more at <https://github.com/ahrefs>
When not maintaining we try to contribute. One example is [ocaml-lsp]
We are also sponsoring projects:
• <https://github.com/owlbarn/owl>
• <https://akabe.github.io/ocaml-jupyter/>
Conferences:
• <https://icfp23.sigplan.org/>
• <https://popl23.sigplan.org/>
(also the reasonml conferences in the past)
And last but not least the OCaml Software Foundation
<https://ocaml-sf.org/>
[ocaml-lsp] <https://github.com/ocaml/ocaml-lsp/>
tmx: Import 2D game maps with ease
══════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-tmx-import-2d-game-maps-with-ease/12138/1>
fishyfriend announced
─────────────────────
`tmx' is an OCaml library for reading data files from the 2D game map
editor [Tiled].
The library aims for broad coverage of Tiled’s [TMX file formats]. It
provides an imperative context for loading TMX data files and a
collection of immutable types corresponding to TMX data structures.
`tmx' emulates the semantics of TMX data structures as they exist in
the Tiled desktop application, including proper application of [custom
property] inheritance and [object templates]. This allows the
attributes of game resources in OCaml to match exactly what is
observed in the editor.
Check out the [project page] for more.
[Tiled] <http://mapeditor.org>
[TMX file formats]
<https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#>
[custom property]
<https://doc.mapeditor.org/en/stable/manual/custom-properties/>
[object templates]
<https://doc.mapeditor.org/en/stable/reference/tmx-map-format/#template-files>
[project page] <http://github.com/fishyfriend/tmx>
Brr 0.0.5, the WebGPU edition
═════════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-brr-0-0-5-the-webgpu-edition/12141/1>
Daniel Bünzli announced
───────────────────────
There’s a new release of Brr. Brr is an ISC licenced toolkit for
programming browsers with the js_of_ocaml compiler.
The highlight of this release is support for the new [WebGPU API] that
is gradually being rolled out in browsers. You can find it in the
[`Brr_webgpu.Gpu'] module – the binding is large and has been little
tested so far, early adopters may run into glitches. But the [250
lines example] to render the usual triangle works.
The [release notes] have the other changes.
The WebGPU binding work was supported by a grant from the [OCaml
Software Foundation]. A big thank to my [donators] aswell, I welcome
and thank a new private donator.
• Homepage: <https://erratique.ch/software/brr>
• Docs: <https://erratique.ch/software/brr/doc> (or `odig doc brr')
• Install: `opam install brr' (once [this PR] has been merged)
[WebGPU API]
<https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API>
[`Brr_webgpu.Gpu']
<https://erratique.ch/software/brr/doc/Brr_webgpu/Gpu/index.html>
[250 lines example]
<https://github.com/dbuenzli/brr/blob/master/test/test_gpu.ml>
[release notes]
<https://github.com/dbuenzli/brr/blob/master/CHANGES.md#v005-2023-05-10-la-forclaz-vs>
[OCaml Software Foundation] <http://ocaml-sf.org/>
[donators] <https://github.com/sponsors/dbuenzli>
[this PR] <https://github.com/ocaml/opam-repository/pull/23774>
A bestiary of GADT examples?
════════════════════════════
Archive:
<https://discuss.ocaml.org/t/a-bestiary-of-gadt-examples/12143/1>
Chet Murthy asked
─────────────────
Is there someplace a bestiary of GADT examples ? I’d like to find such
a thing in order to more-fully understand the universe of
possibilities for using GADTs in programming. I’ve never used ’em, and
while, sure, reading about the theory is great, and reading a few
example is cool, it would be complementary to have a bottom-up
understanding (lots of examples) as well as a top-down one.
Yawar Amin replied
──────────────────
We do seem to have a home-grown ’GADT’-iary:
<https://discuss.ocaml.org/t/open-source-projects-using-gadts/9640>
A couple of new and interesting ones since that thread:
• <https://discuss.ocaml.org/t/ann-petrol-1-0-0-a-high-level-typed-sql-api-for-ocaml-designed-to-go-fast/11166>
• <https://github.com/yawaramin/ocaml_sql_query/blob/0516ea6c7d80a6fcf61c4d9ba551b9f0b780d9ff/lib/sql.ml#L21>
by yours truly to model ’a query can return either nothing or some
resultset’
Kiran Gopinathan also replied
─────────────────────────────
I haven’t got round to properly publicising it, but I actually wrote
blog post about the internal development process of Petrol, and how I
gradually moved from Caqti, to macros, to GADTs which may be useful:
<https://gopiandcode.uk/logs/log-ways-of-sql-in-ocaml.html>
Armael also replied
───────────────────
Not exactly examples of GADTs “in the wild”, but I’ve found @yallop ’s
slides (from the [Advanced Functional Programming course at
Cambridge]) to be interesting for seeing “GADT design patterns”:
<https://www.cl.cam.ac.uk/teaching/1617/L28/lecture-8-slides.pdf> ,
<https://www.cl.cam.ac.uk/teaching/1617/L28/lecture-9a-slides.pdf>. (I
hope it is OK to link those here!)
[Advanced Functional Programming course at Cambridge]
<https://www.cl.cam.ac.uk/teaching/1617/L28/materials.html>
Gaëtan Gilbert also replied
───────────────────────────
We use a lot of GADTs in Coq For instance
<https://github.com/coq/coq/blob/14946eb0cbce09c1a63d36aac21ccb1161fbd869/plugins/ltac2/tac2ffi.ml#L16-L18>
used to have arbitrary-arity functions Slightly simplified:
┌────
│ type ('arg,'result,'f) arity =
│ | One : ('arg, 'result, 'arg -> 'result) arity
│ | More : ('arg, 'result, 'f) arity -> ('arg, 'result, 'arg -> 'f) arity
│
│ type ('arg, 'result) nary = Nary : ('arg, 'result, 'f) arity * 'f -> ('arg, 'result) nary
│
│ type value =
│ | Closure of (value, value) nary
│ | SomeInt of int
│
│ let to_nary = function
│ | Closure f -> f
│ | SomeInt _ -> failwith "can't apply someint"
│
│ let rec apply : type f. (value,value,f) arity -> f -> value list -> value =
│ fun arity f args -> match args, arity with
│ | [], _ -> Closure (Nary (arity, f))
│ | [arg], One -> f arg
│ | arg :: args, More arity -> apply arity (f arg) args
│ | arg :: args, One ->
│ let f = f arg in
│ let Nary (arity, f) = to_nary f in
│ apply arity f args
│
│ let apply_val f args =
│ let Nary (arity, f) = to_nary f in
│ apply arity f args
│
│ let addf x y = match x, y with
│ | SomeInt x, SomeInt y -> SomeInt (x + y)
│ | _ -> failwith "addf got non-ints"
│
│ let addval =
│ Closure (Nary (More One, addf))
│
│ let addval' =
│ Closure (Nary (One, fun x -> Closure (Nary (One, fun y -> addf x y))))
│
│ let () = assert
│ (apply_val addval [SomeInt 1; SomeInt 2] =
│ apply_val addval' [SomeInt 1; SomeInt 2])
│
│ let () = assert
│ (apply_val addval [SomeInt 1; SomeInt 2] =
│ SomeInt 3)
└────
Or
<https://github.com/coq/coq/blob/14946eb0cbce09c1a63d36aac21ccb1161fbd869/engine/evd.ml#L208-L230>
a record where some fields are nontrivial if and only if some other
field is nontrivial
or around
<https://github.com/coq/coq/blob/14946eb0cbce09c1a63d36aac21ccb1161fbd869/gramlib/grammar.ml#L201>
which replaced some Obj.magic in the camlp5 engine this file is
derived from.
I guess you can find more by looking at
<https://github.com/search?q=repo%3Acoq%2Fcoq+GADT&type=commits>
Anton Bachin also replied
─────────────────────────
`'a Lwt.t' promise states and several other types in Lwt are
internally GADTs. See
<https://github.com/ocsigen/lwt/blob/cc05e2bda6c34126a3fd8d150ee7cddb3b8a440b/src/core/lwt.ml#L321-L340>.
This is mainly to use the existential types capability of GADTs.
Calascibetta Romain also replied
────────────────────────────────
You can also check a protocol implementation with GADT here (which
proves that a client should never send something to another client):
<https://github.com/dinosaure/bob/blob/main/lib/state.ml>. A detailled
article is available here:
<https://blog.osau.re/articles/gadt_and_state_machine.html>
Also, I re-implemented a `printf' function with a _promotion_
mechanism of certains values (à la C) here:
<https://github.com/mirage/conan/blob/main/src/fmt.ml>. You can also
check the implementation of the decision tree which helps us to
regognize MIME type, it’s a GADT too:
<https://github.com/mirage/conan/blob/main/src/tree.ml#L10>.
Finally, you can check this typed lambda calculus:
<https://github.com/mirage/mirage-lambda/blob/a89b265b552f8b63ff725fc942f41a276fabb4f5/src/typedtree.ml#L436>
and the transformation from a simple lambda-calculus with a typed one
(and where we prove that variables are bounds via the De-Bruijn
indice).
EDIT: Ah and probably the most complicated GADT I ever see which has a
real application, [a zipper on an AST where the _path_ is a GADT].
[a zipper on an AST where the _path_ is a GADT]
<https://github.com/Octachron/codept/blob/master/lib/zipper_def.ml>
Emile Trotignon also replied
────────────────────────────
Menhir generates code with gadts using the method described in [this
paper]
In that case, the specific technique used is ADTs without allocation,
of which a more simple example is the following :
┌────
│ type 'a number =
│ | Float : float number
│ | Int : int number
│
│ let show_number : type n. n number -> n -> string =
│ fun witness n ->
│ match witness with
│ | Float -> string_of_float n
│ | Int -> string_of_int n
└────
[this paper]
<http://cambium.inria.fr/~fpottier/publis/fpottier-regis-gianas-typed-lr.pdf>
zapashcanon also replied
────────────────────────
In [owi], to allow the user [to define host functions] usable from
Wasm, we also [use GADTs].
[owi] <https://github.com/ocamlpro/owi>
[to define host functions]
<https://github.com/OCamlPro/owi/tree/main/example#using-and-defining-external-functions-host-functions>
[use GADTs]
<https://github.com/OCamlPro/owi/blob/main/src/value.ml#L1-L104>
Jean Christophe Filliatre also replied
──────────────────────────────────────
Arthur Wendling (Tarides) has an implementation of Kaplan/Tarjan 99
(Purely Functional, Real-Time Deques with Catenation), which makes a
non-trivial use of OCaml’s GADT. See [https://github.com/art-w/deque]
[https://github.com/art-w/deque] <https://github.com/art-w/deque>
Open-source tool to make a static blog in OCaml?
════════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/open-source-tool-to-make-a-static-blog-in-ocaml/11967/8>
deep in this thread, roddy said
───────────────────────────────
My tool [finch] meets most of these requirements. I think it is much
more Hugo/Jekyll-like than YOCaml or Soupault. It should be easy for
you to add any features you need, it’s <600 lines of straightforward
OCaml.
Two examples of its use are [its documentation] and [my meagre
website].
[finch] <https://github.com/roddyyaga/finch>
[its documentation] <https://roddyyaga.github.io/finch/>
[my meagre website] <https://roddymacsween.co.uk>
BER MetaOCaml N114, for OCaml 4.14.1
════════════════════════════════════
Archive:
<https://sympa.inria.fr/sympa/arc/caml-list/2023-05/msg00009.html>
Oleg announced
──────────────
BER MetaOCaml N114 is a strict superset of OCaml 4.14.1 for ``writing
programs that generate programs’’. BER MetaOCaml adds to OCaml the
type of code values (denoting ``program code’’, or future-stage
computations), and two basic constructs to build them: quoting and
splicing. The generated code can be printed, stored in a file – or
compiled and linked-back to the running program, thus implementing
run-time code optimization. A subset of the generated OCaml code can
also be converted to C, via offshoring. (The generated C needs no
particular runtime or GC.) A well-typed BER MetaOCaml program
generates only well-scoped and well-typed programs: The generated code
shall compile without type errors. Staging-annotation–free BER
MetaOCaml is identical to OCaml; BER MetaOCaml can link to any
OCaml-compiled library (and vice versa).
The main changes in version N114 are
• smoothing the path for the possible future integration into OCaml;
• starting and almost finishing the complete solution to the
long-standing CSP problem;
• complete support for offshoring
The problems of syntax are said to command the most discussion. This
message is no exception. In MetaOCaml, code to be generated is
enclosed in brackets: .<1 + 2>. (which may contain `holes’, to be
filled with code: fun h -> .<1 + .~h>. where .~, analogous to
unquotation in Lisp, is called escape). Although `.<’ and `.~’ are not
valid in OCaml and hence can’t be confused, `>.’ is a a valid OCaml
operator (and so are the operators that start with that character
sequence, like `>..’ and `>.>.’). In fact, there are some libraries
that do define the operator `>.’ and which therefore cannot be used in
MetaOCaml code. Version N114 introduces an adaptive lexer, which
treats `>.’ identically to ordinary OCaml, until it sees the first
`.<’. If one arranges the code such that all occurrences of the
operator `>.’ come before the opening bracket, one can use the
operator even in the same file as brackets. If one cannot arrange code
such way, or must use `>.’ within brackets, one has to use the
alternative syntax for brackets and escapes:
┌────
│ fun h -> [%metaocaml.bracket 1 >. [%metaocaml.escape h]]
└────
although one may prefer
┌────
│ fun h -> [%metaocaml.bracket 1 >. .~h]
└────
For more explanations, please see
<https://okmij.org/ftp/ML/MetaOCaml.html> particularly about
CSP, and
<https://okmij.org/ftp/meta-programming/tutorial/genc.html>
about offshoring. See also ChangeLog and NOTES.txt in the BER
MetaOCaml distribution.
BER MetaOCaml N114 should be available through OPAM, hopefully soon.
In the meanwhile, it is available as a set of patches to the OCaml
4.14.1 distribution.
<https://okmij.org/ftp/ML/ber-metaocaml.tar.gz>
See the INSTALL document in that archive. You need the source
distribution of OCaml 4.14.1.
Building iOS apps with OCaml?
═════════════════════════════
Archive:
<https://discuss.ocaml.org/t/building-ios-apps-with-ocaml/12153/1>
RobertN asked
─────────────
Is it possible to create iOS apps with OCaml? I know it might take
some extra work to use a foreign-function interface to call
Objective-C functions to create the UI objects. But I’m wondering if I
can cross compile for ARM and send a binary to my iPhone, and
eventually the App Store. I’ll be working from macOS (x86).
I’m also interested in macOS apps for the App Store, which probably
require cross-compiling to make an ARM+x86 binary of some kind.
Daniel Bünzli replied
─────────────────────
Don’t know what the state of that is but at least it has been [done]
at some point.
[done] <http://psellos.com/ocaml/compile-to-iphone.html>
Nathan Fallet also replied
──────────────────────────
I’ve already seen people trying to do that. [Here is an example].
It’s not from me but it’s an example I got shown when I built my
[OCaml editor for iOS/iPadOS/macOS].
[Here is an example]
<https://github.com/dboris/ocaml-cocoa/blob/master/examples/count_clicks.ml>
[OCaml editor for iOS/iPadOS/macOS]
<https://discuss.ocaml.org/t/open-source-editor-for-ios-ipados-and-macos/7624/21>
jbeckford added
───────────────
Couple more options …
Option 1: I mentioned last week in an unrelated thread that there is
an opam package `dkml-base-compiler` that does cross-compilation. It
supports most of the Android cross-compile matrix (ex. x86 -> arm32),
and the macOS (ex. x86_64 -> arm64). I haven’t updated the official
opam package to do iOS cross-compiles b/c most of my open-source time
commitment has been for Windows. If you know how to compile the OCaml
compiler, please extend that package! The bits will be very similar to
the macOS cross-compiler, and I can guide you. See:
<https://discuss.ocaml.org/t/how-to-compile-ocaml-program-on-linux-for-running-on-freebsd/12110/4?u=jbeckford>
Option 2: If you want a more out-of-the-box solution, you can use my
commercial [DkSDK] native development kit. From an OCaml perspective,
it is a OCaml-beginner friendly kit that embeds OCaml into other
languages and frameworks. Two short-term things are relevant. 1) The
docs mentions C a lot, but only because I haven’t finished writing its
FFI. It will support OCaml objects <–> Objective-C/Swift objects using
Apple’s [Foundation] library. 2) I inadvertently broke support for
Xcode builds, but that will get fixed sooner or later (depending on
the interest).
Anyway, ping me privately if Objective-C/Swift dev in Xcode with the
Run button automatically building FFI-supported OCaml code sounds like
a fit.
[DkSDK] <https://diskuv.com/cmake/help/latest/>
[Foundation]
<https://github.com/apple/swift-corelibs-foundation/tree/main#readme>
Vincent Balat also replied
──────────────────────────
Be Sport app is written in OCaml (iOS, Android, Web client and server)
with Ocsigen (Eliom, Js_of_ocaml, Ocsigen Start…) as an HTML5 app
(with Cordova) <https://apps.apple.com/fr/app/be-sport/id1104216922>
A Minimal Prototype of In-Package Search is on staging.ocaml.org
════════════════════════════════════════════════════════════════
Archive:
<https://discuss.ocaml.org/t/a-minimal-prototype-of-in-package-search-is-on-staging-ocaml-org/12163/1>
Sabine Schmaltz announced
─────────────────────────
We added an experimental, incomplete and basic in-package search to
[staging.ocaml.org]. :camel: The current prototype implementation uses
an existing JavaScript library. That turned out to be the quickest /
least-effort way to get something up and running while we work behind
the scenes on something more refined.
On <https://staging.ocaml.org/p/dream/latest> (or any other package
for which documentation has been successfully built by the
documentation pipeline) you should see a search bar that allows you to
search identifiers within the package.
The goal from our side is to bring a “minimum useful product” to you
quickly. Please let us know if there are any problems or wishes for a
“version 1.0.0” of the search.
If no show-stopping issues are uncovered, we’ll go ahead and apply a
patch to the live site at ocaml.org by end of the week or early next
week. :slight_smile:
Thank you @panglesd, @EmileTrotignon, and @art-w for enabling this! I
spent surprisingly little time on the integration into
staging.ocaml.org so far, so it’s going to be fun to see where this
goes.
[staging.ocaml.org] <http://staging.ocaml.org/>
Barisere Jonathan asked and Sabine Schmaltz replied
───────────────────────────────────────────────────
Is it possible to run the docs UI locally, just as
[Racket] does?
It is possible to use [odoc] locally to render and consume
documentation.
However, search has not yet been added to `odoc'.
This particular prototype of search is only on staging.ocaml.org at
the moment.
[Racket] <https://docs.racket-lang.org>
[odoc] <https://github.com/ocaml/odoc>
Sid Kshatriya then added
────────────────────────
To suplement to what @sabine mentioned, I would like to recommend
`odig'.
`odig' is a very easy way to invoke `odoc' on your local machine. See
<https://erratique.ch/software/odig>
New release of Fix (20230505)
═════════════════════════════
Archive:
<https://discuss.ocaml.org/t/ann-new-release-of-fix-20230505/12168/1>
François Pottier announced
──────────────────────────
Frédéric Bour and I are pleased to announce a new release of Fix.
In short, Fix is a toolkit that helps perform memoization and fixed
point computations (including data flow analyses). More generally, it
offers a number of basic algorithmic building blocks that can be
useful in many circumstances.
In this release, two new modules have been added:
• [Fix.Minimize] offers a minimization algorithm for deterministic
finite automata (DFAs). It is based on Antti Valmari’s 2012 paper,
“Fast brief practical DFA minimization”.
• [Fix.Partition] offers a partition refinement data structure, which
is used by the minimization algorithm, and could be useful in other
algorithms.
There are other minor [changes].
The library can be installed as follows:
┌────
│ opam update
│ opam install fix.20230505
└────
[Documentation] is available online.
[Fix.Minimize]
<http://cambium.inria.fr/~fpottier/fix/doc/fix/Fix/Minimize/>
[Fix.Partition]
<http://cambium.inria.fr/~fpottier/fix/doc/fix/Fix/Partition/>
[changes]
<https://gitlab.inria.fr/fpottier/fix/-/blob/master/CHANGES.md>
[Documentation] <http://cambium.inria.fr/~fpottier/fix/doc/fix/>
QCheck 0.21
═══════════
Archive: <https://discuss.ocaml.org/t/ann-qcheck-0-21/12169/1>
Jan Midtgaard announced
───────────────────────
I’m happy to announce the release of QCheck 0.21, a property-based
testing library in the style of Haskell’s QuickCheck :tada: More
information is available in the [QCheck Github repository] and in the
[package documentation].
The 0.21 release offers better negative test integration and
furthermore fixes a couple of bugs in `QCheck.Shrink' and in
`ppx_deriving_qcheck':
• make `Test.check_result', `Test.check_cell_exn', and
`Test.check_exn' honor test polarity by raising
`Test_unexpected_success' when a negative test (expected to have a
counter example), unexpectedly succeeds.
• fix issue with `ppx_deriving_qcheck' deriving a generator with
unbound `gen' for recursive types [#269] and a related issue when
deriving a generator for a record type
• fix #241 causing `QCheck.Shrink.int*' to emit duplicates, also
affecting `QCheck.Shrink.{char,string}'
• fix a cornercase where `Shrink.list_spine' would emit duplicates
[QCheck Github repository] <https://github.com/c-cube/qcheck>
[package documentation] <https://c-cube.github.io/qcheck/>
[#269] <https://github.com/c-cube/qcheck/issues/269>
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 at polytechnique.org>
[the archive] <https://alan.petitepomme.net/cwn/>
[RSS feed of the archives] <https://alan.petitepomme.net/cwn/cwn.rss>
[online] <http://lists.idyll.org/listinfo/caml-news-weekly/>
[Alan Schmitt] <https://alan.petitepomme.net/>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20230516/ff490c06/attachment-0001.html>
More information about the caml-news-weekly
mailing list