jump-dev / jump-dev/JuMP.jl

Explore namespace ideas

Open
#3,791 5 comments 1 reaction 0 assignees View on GitHub
Type: Feature request
Dominant language
Julia
Stars
2.5k
Forks
428
Avg merge
18h 10m
Merged PRs (30d)
28

Description

I just watched @blnicho's JuMP-dev talk https://youtu.be/G1tW68vrOBM. (Thanks Bethany! It was a very useful talk and exactly what I was after.)

It has come up in various discussions over the years, but one of the biggest differences between JuMP and Pyomo is how we handle namespacing.

## JuMP

JuMP uses a single global namespace, and all objects are stored in the `object_dictionary(model)`:
```julia
model = Model()
@variable(model, x)
model[:x] === x # true
@variable(model, x) # Errors. x already exists.
```
The downside is that for unrelated model parts to compose, you need to use anonymous variables, but this has poorer printing, and the macro syntax is more limited.
```julia
model = Model()
x = model[:x] = @variable(model, base_name = "x")
model[:x] === x # true
x = model[:x2] = @variable(model, base_name = "x")
```

## Pyomo

Pyomo has blocks. At a high level, blocks create a new namespace, and can be nested inside each other. You can delete/deactive entire blocks as a single component.

In Julia-land, we might do:
```julia
model = Model()
@block(model, blocks[1:2])
@variable(blocks[1], x)
blocks[1][:x] === x # true
@variable(blocks[2], x)
blocks[1][:x] === x # false: Julia binding `x` has been replaced in this scope
blocks[2][:x] === x # true
@objective(model, Min, sum(b[:x] for b in blocks))
```

## Next steps

I don't have a concrete syntax proposal, or believe that we should necessarily implement this, but I'd be open to exploring possibilities, and I'd very much like to come up with a few examples where JuMP's current syntax is limiting and the block/namespace would be beneficial.

I don't think this would change anything at the MOI level. This is strictly a JuMP-level feature.

I also don't know if this is that easy to explore in a JuMP-extension, but maybe it is. A prototype could store everything in `model.ext[:block_extension]` for now.

Some questions:

* What exactly is the struct of `block[1]`?
* Are blocks added to the model lazily or eagerly?
* You could imagine a block being a self-contained JuMP model with no solver backing it, and when `block` is referenced in the `model` scope everything gets copied across.
* Dropping a breadcrumb to https://github.com/geoffleyland/rima and https://github.com/geoffleyland/rima/blob/master/papers/Rima-ORSNZ-paper-2010.pdf

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.