I had the pleasure of learning about Lean 4 with David Christiansen and Joachim Breitner at their tutorial at BOBKonf 2024. I‘m planning on doing a couple of formalizations with Lean and would love to share what I learn as a total newbie, working on macOS.
I‘m on macOS and use Homebrew extensively. My simple go-to approach to finding new software is to do brew search lean
. This revealed lean
as well as surface elan
. Running brew info lean
showed me that that package (at the time I write this) installs Lean 3. But I know, out-of-band, that Lean 4 is what I want to work with. Running brew info elan
looked better, but the output reminds me that (1) the information is for the elan-init
package, not the elan
cask, and (2) elan-init
conflicts with both the elan
and the aforementioned lean
. Yikes! This strikes me as a potential problem for the community, because I think Lean 3, though it still works, is presumably not where new Lean development should be taking place. Perhaps the Homebrew formula for Lean should be updated called lean3
, and a new lean4
package should be made available. I‘m not sure. The situation seems less than ideal, but in short, I have been successful with the elan-init
package.
After installing elan-init
, you‘ll have the elan
tool available in your shell. elan
is the tool used for maintaining different versions of Lean, similar to nvm
in the Node.js world or pyenv
.
When I did the Lean 4 tutorial at BOB, I worked entirely within VS Code (…) and created a new standalone package using some in-editor functionality. At the command line, I use lake init
to manually create a new Lean package. At first, I made the mistake of running this command, assuming it would create a new directory for me and set up any configuration and boilerplate code there. I was surprised to find, instead, that lake init
sets things up in the current directory, in addition to creating a subdirectory and populating it. Using lake --help
, I read about the lake new
command, which does what I had in mind. So I might suggest using lake new
rather than lake init
.
What‘s in the new directory? Doing tree foobar
reveals
foobar
├── Foobar
│ └── Basic.lean
├── Foobar.lean
├── Main.lean
├── lakefile.lean
└── lean-toolchain
Taking a look there, I see four .lean
files. Here‘s what they contain:
Main.lean
import «Foobar»
def main : IO Unit :=
IO.println s!"Hello, {hello}!"
Foobar.lean
-- This module serves as the root of the `Foobar` library.
-- Import modules here that should be built as part of the library.
import «Foobar».Basic
Foobar/Basic.lean
def hello := "world"
lakefile.lean
import Lake
open Lake DSL
package «foobar» where
-- add package configuration options here
lean_lib «Foobar» where
-- add library configuration options here
@[default_target]
lean_exe «foobar» where
root := `Main
It looks like there‘s a little module structure here, and a reference to the identifier hello
, defined in Foobar/Basic.lean
and made available via Foobar.lean
. I’m not going to touch lakefile.lean
for now; as a newbie, it looks scary enough that I think I’ll just stick to things like Basic.lean
.
There‘s also an automatically created .git
there, not shown in the directory output above.
Now that you‘ve got Lean 4 installed and set up a package, you‘re ready to dive in to one of the official tutorials. The one I‘m working through is David‘s Functional Programming in Lean. There‘s all sorts of additional things to learn, such as all the different lake
commands. Enjoy!