stan-dev / stan

Stan development repository. The master branch contains the current release. The develop branch contains the latest stable development. See the Developer Process Wiki for details.
https://mc-stan.org
BSD 3-Clause "New" or "Revised" License
2.59k stars 370 forks source link

support arbitrary data type in function block's function signatures #2572

Closed yizhang-yiz closed 8 months ago

yizhang-yiz commented 6 years ago

Summary:

support arbitrary type in external C++ code so user_header.hpp can provide higher-order function support.

Description:

Currently external C++ function in Stan must be declared in functions block with full signature, e.g.

functions {
       real foo(real theta);
}
/*...*/
transformed parameters {
       x = foo(y);
}
/*...*/

This allows user-supplied function. One further step would be to allow user's functions with functor arguments, similar to what Stan has for ODE solvers. Specifically, with that one can do

functions {
       real foo(T func, real theta); /* similar to template */
       real bar(real x) {
/* define function bar */
}
}
/*...*/
transformed parameters {
       x = foo(bar, y);
}
/*...*/

With this user can supply both ordinary and higher-order functions through C++ headers. Essentially Stan would have some basic plugin mechanism.

I'm not sure how difficult it'll be to realize something like this.

Current Version:

v2.17.1

bgoodri commented 6 years ago

Perhaps https://www.boost.org/doc/libs/1_67_0/libs/hof/doc/html/doc/ would help

yizhang-yiz commented 6 years ago

Not a problem that I'm familiar with. Leave to you guys for a sanity check.

bob-carpenter commented 6 years ago

This is something we'll be addressing in general by adding functional types. We probably aren't going to want to duplicate the effort in the current parser.

The syntax I want to use is something like (real, real):real, for a two-argument real valued-function. That's what we print out.

As of 2.17/2.18, we have no support for functional types in the Stan language and it'd be a rather substantial effort to add them. The benefit would be that we could remove a bunch of specific grammar rules for functions that take higher-order arguments.

yizhang-yiz commented 6 years ago

That's exactly the syntax I want to see. Is there a timeline for this feature?

bob-carpenter commented 6 years ago

It depends on a number of things. We want to rip out the parser and rebuild it from scratch, so that's going to set things back probably 9 months or so, but then allow us to go much much faster. If that goes too slowly, we'll probably wind up extending the current language to do these things. Either way, very unlikely in the next six to twelve months.

I don't know how we could work around that. We might be able to weaken type checking somehow and add just a generic function type that'd get checked at compile time. That might be workable and a lot easier than building a whole higher-order type-inference system.

yizhang-yiz commented 6 years ago

Yes, something like

functions{
   func foo;
}

and allowing foo to be a higher-order function. I don't mind working on it but would need guidance as I know little about the lang part of Stan.

bob-carpenter commented 6 years ago

Something like that might be workable if we left the actual type-checking of the function to compile time (rather than translation to C++ time).

The reason we want to switch the way we're writing the compiler is that the current infrastructure is such a pain to work with (Boost Spirit Qi---it's all statically typed with super-clever template programs, bindings, etc., which makes it very hard to get things to compile).

WardBrian commented 8 months ago

There is a newer stanc3 issue which is similar: https://github.com/stan-dev/stanc3/issues/1348 I'm going to close this older one in favor of it