Code Monkey home page Code Monkey logo

Comments (11)

bob-carpenter avatar bob-carpenter commented on July 29, 2024

I think it would make sense to get a design for this before opening an issue. Is there a proposed syntax you have in mind? It's hard to have design discussions in issue comments as there's no quoting or LaTeX support.

Is the idea here that a function currently declared in the functions block would just be declared in the data block because it wouldn't need any closure variables? And just to kick off the syntax discussion, I think that'd look like this:

data {
  (real, real):real hypoteneuse = (real x1, real x2).sqrt(x1^2 + x2^2);
  ...

where we'd do type inference to deduce the return type of the function on the right-hand side to make sure it matched the declaration on the left-hand side. I'm not at all wedded to any of this syntax, by the way---it's just similar to what C++11 does for binding and what I've done in the manual for describing function types.

from stanc3.

VMatthijs avatar VMatthijs commented on July 29, 2024

Ah, for the closures (before we add higher-order functions and lambdas etc which you seem to be describing a syntax for), I imagined we could just keep the current syntax, e.g.:

transformed data {
  real x = 42;
  void an_example_of_a_closure() { // here we define it
    print(x);
  }
  x = 17;
  an_example_of_a_closure(); // here we use it, still prints 42
}

Of course, the semantic check to make sure the return type matches the declaration needs to happen, but the semantic check is currently written in such a way that that should still be true if function definitions occur elsewhere in code than in the functions block.

In my mind they should be allowed anywhere in the program where a statement is currently allowed.
For example, we should also be able to have locally defined functions like

transformed data {
  real x = 42;
  {
    void an_example_of_a_closure() { // here we define it
      print(x);
    }
    an_example_of_a_closure(); // here we use it
  }
  an_example_of_a_closure(); // error here as it is no longer in scope.
}

from stanc3.

bob-carpenter avatar bob-carpenter commented on July 29, 2024

from stanc3.

VMatthijs avatar VMatthijs commented on July 29, 2024

Yes, that's what I was thinking. This could be quite useful and wouldn't be super hard to implement, I hope, as we could just use C++'s closures for code generation.

The higher-order functions and lambdas seem like a separate issue. (Even though they often appear together with closures in languages.) There, we'd definitely need to think carefully about a spec.

from stanc3.

bob-carpenter avatar bob-carpenter commented on July 29, 2024

Yes, that's what I was thinking. This could be quite useful and wouldn't be super hard to implement, I hope, as we could just use C++'s closures for code generation.

Right. That's been on the table since we opened up C++11.

The higher-order functions and lambdas seem like a separate issue. (Even though they often appear together with closures in languages.) There, we'd definitely need to think carefully about a spec.

I think they're very closely related because we can think of a function definition with static lexical scope, such as the following to capture y,

real foo(real x) { return x^3 - y; }

as syntactic sugar for for the more explicit closure form

(real):real foo = (real x).{ return x^3 - y; }

This way, higher-order functions are an orthogonal concern

from stanc3.

VMatthijs avatar VMatthijs commented on July 29, 2024

Ah, right! I see what you mean. You could also theoretically keep the three notions of closures (i.e. functions which store the values of variables from their enclosing scope), lambdas (i.e. anonymous functions) and higher-order functions (functions which take functions as arguments) separate. I can imagine having a language which has any of these features independently of the others. Personally, my feeling is that closures and higher-order functions would be very useful for Stan, while I am not dead set on having lambdas (seeing that I cannot imagine people using functional programming so heavily in Stan that it becomes cumbersome to name functions, especially as we do not have type inference so people will still need to type the types of the arguments on the lambdas).

Personally, I was thinking about the notations
(real) -> real foo = fun (real x) -> { return x^3 - y; }
for function types and lambdas.
That is to be somewhat consistent with common notations.

Notations I've seen for function types (let's do a multi-argument function for generality):
(real, vector) -> int (SML/NJ, OCaml, Coq, Rust)
(real, vector) => int (Haskell, Agda, Scala)
Func<(real, vector), int> (C#)
Function<(real, vector), int> (Java)
function<int(real, vector)> (C++)

Notations that I've seen for lambdas:
fun (x, z) -> x^3 - y (OCaml, Coq)
(x, z) => { return x^3 - y} (Scala)
(x, z) -> { return x^3 - y} (Java)
[]( real x, vector z) { return x^3 - y} (C++)
\(x, z) -> x^3 - y (Haskell, Agda)
fn (x,z) -> { x^3 - y (Rust)
fn [x,z] -> (- (^ x 3) y) (Clojure)

I'm sure there are many more relevant ones, but these are the first that come to mind.

Generally, I have a preference for self-explanatory syntax that is easy to Google, e.g. fun rather than just using some symbol like []. When it comes to the types, I am a bit torn between something like -> and Fun or Func as the latter two can become hard to read when you start nesting them, like for the signature of ODE solvers.
`
I'd like to decide on a syntax for higher order types before we release the new compiler, so the type error messages for functions can already use the function type syntax.

We should probably treat lambdas à la Church rather than Curry (i.e. type annotations on the variable binders) as that would make type checking much easier.

from stanc3.

bob-carpenter avatar bob-carpenter commented on July 29, 2024

from stanc3.

seantalts avatar seantalts commented on July 29, 2024

I think you're right that this belongs somewhere else. I'd propose we use the design-docs repo (and maybe rename it to RFCs to follow Rust?) to post proposals for additions to the Stan language and allow users to comment.

from stanc3.

seantalts avatar seantalts commented on July 29, 2024

I'm going to close this issue for now; @VMatthijs if you or @bob-carpenter (or whoever) want to make a proposal for closure / lambda syntax additions to Stan, please add an RFC for it in the design-docs repo (instructions and template live in that repo).

from stanc3.

nhuurre avatar nhuurre commented on July 29, 2024

The closure design-doc was accepted a while ago. Should we reopen this?

from stanc3.

seantalts avatar seantalts commented on July 29, 2024

from stanc3.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.