where is pretty great. Say you have a bunch of chained
lets, like this:
-- NOTE: Haskell code; computes (x + 2) * 2 foo x = let y = x+2 let z = y*2 in z
where keyword lets you rewrite them in the following lovely, clean way:
-- NOTE: Haskell code foo x = z where y = x+2 z = y*2
Surprisingly, OCaml doesn't support this syntax! So, I wrote this patch, which changes OCaml so that something like the
where clause is allowed. For technical reasons (an important rule is right-associative), the syntax is somewhat different:
(* OCaml version *) let foo x = z where y = x+2 and z = y*2
Note the use of
and to separate bindings here. This is necessary between every binding:
(* Moar OCaml stuff *) let foo x = x''' where x' = x+2 and x'' = x'*2 and x''' = y''+2
You're welcome, hardcore
where fans! :)
Running the demo
The output will inform you that this code:
let x = z where y = 10 and z = 20
will desugar to this code:
let x = let y = 10 in let z = 20 in z
This is exactly what we desire---the
where simply desugars into a list of
So, how does this work? If you look at the makefile, you'll see the syntax extension (i.e.,
where.ml) gets compiled and then linked in to compiling the test file (i.e.,
test.ml) at compile time.
What do all these files do?
where.ml is where the magic happens---this implements our syntax extension, and can be compiled down to a
.cmo file. This can then be linked into any project you want to use the
where keyword in, and it should just work.
test.ml is the test file that our demo uses to demonstrate how our extension cleanly desugars down into a chain of
_tags make compilation easy---they automatically include stuff we want and need, and tell the OCaml build utilities what's up about all the stuff we're using.
Using in real projects
You can compile
where.ml into a
where.cmo with the command
ocamlc -pp "camlp4o pa_extend.cmo q_MLast.cmo" -I +camlp4 -c where.ml.
From here you can link it in the normal way, e.g.,
camlc -pp "ocamlp4o ./where.cmo" your_ml_file_here.ml.
You can see how it desugars your source by running
camlp4o where.cmo your_ml_file_here.ml.
Note that there isn't really a standardized way to do syntax extensions, so this may be subtly uncomaptible with other extensions! :(
Because I like you and we're friends, I've chosen to distribute this under MIT. Basically, this means that you can this code for pretty much anything, you just have to keep a note on the code that I wrote, which says I wrote the code. You don't have to acknowledge me in the product or anything. Just the code. It's a pretty friendly license.
Copyright (C) 2013 Alex Clemmer firstname.lastname@example.org
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.