chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.78k stars 418 forks source link

compiler error when REALLY treating functions as first class citizens #15234

Open omar-3 opened 4 years ago

omar-3 commented 4 years ago

Summary of Problem

I was trying to have a minimal example for function currying, It seems like Chapel can't return function objects from a function, it can only accept them as arguments.

Steps to Reproduce

Source Code: This doesn't work.

proc curry(f) {
    proc firstFunction(x) {
        return f(x,10);
    }
    return firstFunction;
}

proc adding(a : int, b : int){
    return a + b;
}

var a = curry(adding);
var b = a(5);
writeln(b); 

This works.

proc curry(f) {
    // proc firstFunction(x) {
        return f(20,10);
    // }
    // return firstFunction;
}

proc adding(a : int, b : int){
    return a + b;
}

var a = curry(adding);
writeln(a);

Compile command: chpl script.chpl Error script.chpl:5: internal error: RES-PRE-OLD-1938 chpl version 1.20.0 Note: This source location is a guess.

Internal errors indicate a bug in the Chapel compiler ("It's us, not you"), and we're sorry for the hassle. We would appreciate your reporting this bug -- please see https://chapel-lang.org/bugs.html for instructions. In the meantime, the filename + line number above may be useful in working around the issue.

Configuration Information

bradcray commented 4 years ago

Thanks for reporting this, though I'm afraid it isn't terribly surprising. Our current first-class function support was implemented by an intern, and has received very little attention since then due to competing priorities. As a result, it's considered an unstable feature at best (and the program above generates a warning indicating this when compiled with --warn-unstable).

omar-3 commented 4 years ago

there is another issue in which I can't pass generic function, like that

proc curry(f) {
    return f(12,10);
}

proc adding(a, b){
    return a + b;
}

var a = curry(adding);
writeln(a); 

Error

script.chpl:9: error: 'adding' cannot be captured as a value because it is a generic function
script.chpl:1: In function 'curry':
script.chpl:2: error: illegal access of first class function
script.chpl:9: Function 'curry' instantiated as: curry(f: borrowed _fcf_error)

but here it seems that the compiler is aware of what I'm doing wrong here, but why is it preventing me from passing generic function?

bradcray commented 4 years ago

why is it preventing me from passing generic function?

This challenge relates to Chapel being a statically-typed language and the current implementation of first-class functions. If you think of a Chapel first-class function as a function pointer in C (not that it is, but that's a fair point of comparison), the implementation needs an explicit function to refer to. A generic function is essentially a family of potential function instantiations rather than a single, specific function; as a result it's not clear what "function pointer" should be passed in. With additional effort (like interprocedural analysis and propagation of first-class functions from callers to callees), it could be possible to support cases like this, but this hasn't historically been a goal of Chapel's first-class function support.

jabraham17 commented 2 months ago

The code in the OP is no longer an internal error, but it still doesn't work as first class functions are not a fully baked Chapel feature yet.