In Racket, by default a file creates a module, I import things, export stuff and done. That's really very handy, because I hate fiddling around with package declarations and paths -- these are a pain in the ass in almost every older language.
In Racket, by default a file creates a module, I import things, export stuff and done. That's really very handy, because I hate fiddling around with package declarations and paths -- these are a pain in the ass in almost every older language.
Personally I really don't like it when files are modules. For me that's orthogonal.
http://clhs.lisp.se/Body/m_w_comp.htm
The packaging systems people use nowadays over CL are not a part of CL. The whatever subjective suckage they introduce is their own. If you want racket-style modules, hack them up.
The grandparent's observation that "modularization/package management turned out to be too verbose and archaic for my taste" is very ironic --- in particular, the "archaic" part. ASDF is from around the turn of the century (the 21st that is).
The big hurdle in CL modularization is something very trivial: the fact that a file cannot refer to neighboring files easily by a short path. There is no
(load "foo")
which will look for a "foo" in the same directory as the file which is invoking the load form.This steers package management toward the external mode, whereby some definition exists outside of all the files and handles their inter-dependencies and the manner of actually locating the groups of files.
I fixed this in TXR Lisp, and so simple modularization is a cinch! You load some main file, and that just does (load "foo") (load "bar") ... to load its related files, no matter where they have been located.
I made load a macro, and that macro accesses the source file location at macro-expansion time, imbuing it into the resulting form that actually does the loading when evaluated. If the load path is relative, then the caller's path is used to resolve it, rather than the current working directory.
I don't think it really makes sense to try to roll your own module system? I mean, the whole point is to be able to easily share code with the community, right?
If you want racket-style modules you can also have them by implementing them.
> To be fair this seems like a pretty common mindset in CL-land.
My Lisp Machine has around 60000 functions, and I have only written a tiny fraction of them... Strange. If nobody else has written them, where are they coming from?
Obviously Fare Rideau thought it was a good idea when he started hacking on ASDF. He could just have used Defsystem or whatever. It's very popular now, but its name stands for "another system definition facility" for Lisp!
If you don't like anything, roll your own.
Sharing with the community isn't the entire point of a module system; it's also to internally organize the software you're working on, whether you're just one hacker or a team of one hundred. Niklaus Wirth's Modula-2 language has a module system, and so does Ada. The concept of sharing modules with the community didn't even exist.
A module system as a hub for sharing is a relatively new thing: it's a fusion of the ideas from open source OS distro package management and language modules.
> The packaging systems people use nowadays over CL are not a part of CL
Packaging systems were never a part of CL.
> The big hurdle in CL modularization is something very trivial: the fact that a file cannot refer to neighboring files easily by a short path. There is no
(load (merge-pathnames "test1" *load-pathname*))
If that's not short enough, define a function L which does above...> This steers package management toward the external mode, whereby some definition exists outside of all the files and handles their inter-dependencies and the manner of actually locating the groups of files.
This is the way how to do it.
> I fixed this in TXR Lisp
Oh no..., well there have been zillions of similar attempts...
`#lang foo ....` in name.rkt is (in part) a shorthand for `(module name foo ....)`.
A single Racket file can have 1 or more modules.
Each module can also have sub-modules.
Modules generalize runtime vs. compile-time to many kinds of time, including but not limited to "test time", "doc time", etc. Also they enable reproducible compiles by clarifying what "compile-time" actually means relative to other modules. It's more than "paste these s-expressions at the top-level prompt and auto-prefix some names."
Racket has a wonderful module system and sometimes I miss that in Clojure, although I enjoy Clojure very much in other respects.