rhombus-prototype
rhombus-prototype copied to clipboard
Make an RFC for "incremental" definitions
One of my favorite features of modern Racket is module+
where you an incrementally define the body of a module. I want something like that where I incrementally attach information to a binding. Defining a function by cases is a special example of this.
(def+ length)
(def+ length type (-> List Number))
(def+ (length '()) 0)
(def+ (length (cons x l)) (add1 (length l)))
(def+ length docs @para{Returns the number of @racket[cons] cells in the argument.})
One thing I concern about this specific example is extensibility. How easy is it going to be to, for instance, make def+
work with defining test cases for a function (a la Pyret)?
I think there are two solutions to this:
- Have something like
define-def+-expander
that will cooperate withdef+
. - Let's have separate forms for each functionality -- don't throw everything into
def+
's responsibility.
@sorawee Remix has something like this that I prototyped. In it, there were def+
transformers and a def+
'd structure would essentially be a hash of keys to key specific values. The keys would be partially ordered and the key-handler would get to see/influence the expansion of the keys of the things beneath it. This way, the type can influence the body and the docs can depend on the type to generate things.
Would this work across module boundaries? Relatedly, how does this compare to/interact with something like Julia's facilities for defining generics? I imagine there could be issues similar to Julia's generics where it would be possible to import multiple modules that have conflicting (def+ ...)
definitions. I think module+
avoids this because you can't really export a module from another module in the same way it is possible to export a binding.
I think incremental definitions probably shouldn't work across module boundaries. Otherwise there's no way to tell what modules you need to import in order to get a complete definition.
I agree @jackfirth I did not assume it would work across boundaries. I was imaging an implementation like module+
's
If it works across modules it open the door to monkeypatching, that is (IMHO) not a good idea, especially when two other modules try to monkeypatch in different directions.
I like that in racket1 the definitions can be set!
ed only from the same module.