Monthly language dev meeting

Notes for Oct 2021 meeting

Design doc on deprecation

@WardBrian asked for volunteers to read his design doc on deprecation. If nobody expresses objections soon, we’ll go ahead and make this policy.

Type checking refactor

@WardBrian also asked for volunteers to review and think about a refactor of the type checker. The goal was to make it shorter and more readable. The PR reduces the size by 500 lines of code. The major changes are

  • the global symbol table is replaced with a functional map
  • the validation monad is removed
  • there are about 500 fewer lines of code

Hopefully, this will open the way for function overloading, tuple types, etc.

@WardBrian also volunteered to help update outstanding PRs for things like tuples and closures.

Function types in the langauge and the closure PR

@nhuurre has an outstanding PR for closures. I’d very much like to get this into the language. As it stands, it only implements closures, not lambdas. In order to have lambdas, we’ll need to introduce a syntax for functional types into the language. There’s a proposal in the closures design doc, but of course that’s not binding if there’s a better way to do it.

Apparently, functional types are already treated as first class objects in the type checker and the hang up is more on the parsing side. Closures are actually the more useful feature, but it’d be nice to get lambdas in that we can use in contexts where appropriate. I’m OK merging just the closures part of the closures design doc and not worrying about the lambdas yet.

TensorFlow back end

As things stand, there’s a lot of logic in stanc3 dedicated to generating TensorFlow back end code. It only supports a bare-bones set of a few handfuls of functions and is reportedly slower than the Stan math back end. The question came up as to whether we should continue to support it or move it out into its own module.

It’s not clear if anyone using it. This was mostly developed by @seantalts and @Adam_Haber, so it’d be interesting to hear from them on whether it’s still viable.

Even if it is being used, it was agreed that it’d be nice to move it out of the stanc3 repo so it’s not an ongoing drag on development. The consensus seemed to be that we try to break it off so that it could import stanc3 as a submodule for most of its functionality. Nobody thought it’d be worth fully factoring Stan math out of the parser, but it would be OK from the TensorFlow back end’s perspective with some extra stuff they didn’t need in the repo (there was general objection to splitting stanc3 into two repos for code generation and for parsing/type checking).

@Bob_Carpenter suggested all the cool kids were moving to JAX, so maybe we should target that instead of TensorFlow.

If we move things now, everything that works in 2.28 will continue to work going forward just by using the 2.28 release.

Transforms

We had a freewheeling discussion of variable transforms and how much users can be expected to know about underlying implementations. For example, should users be able to rely on <lower=0> constraints being implemented with log transforms or should that be considered an implementation detail? The conclusion seemed to be that it’s an implementation detail, but also critical for understanding how sampling was going to work. The Reference Manual does detail the transformations, but it’s not prescriptive in saying that they have to be of this form.

This is one of the motivations for user-defined constraints. For example, a user may prefer a soft-abs inverse transform to an exponential inverse transform for variables declared as <lower=0>.

We then realized that constraints and transforms are doing something different. It’s always been awkward for the doc and explaining Stan that constraints work to trigger transforms in the parameters block, but are just validation tests in other blocks. If we separate constraints and transforms, we could have constraints parameter variables act like other block variables. For instance, we might have

real<transform = softplus, lower = 0> a;
real<transform = exp, lower = 0> b;

This would open the gateway for us to have multiple forms of each transform for different computational purposes.

But this’d be a major breaking change in the language if <lower=0> doesn’t trigger a transform all by itself in a parameter’s declaration.

We decided that if users define potentially non-sensical transforms, one place to warn them would be with pedantic mode.

See you next meeting!

3 Likes