Функции обратного вызова в Chapel

У меня есть следующий код часовни.

proc update(x: int(32)) {
  return 2*x;
}

proc dynamics(x: int(32)) {
  return update(x);
}

writeln(dynamics(7));

Я хотел бы отправить обратный вызов dynamics, например

proc update(x: int(32)) {
  return 2*x;
}

proc dynamics(x: int(32), f: ?) {
  return f(x);
}

writeln(dynamics(7, update));

Это возможно? Есть ли примеры, которые я мог бы просмотреть?


person Brian Dolan    schedule 23.05.2020    source источник


Ответы (2)


У Chapel есть первоклассные функции . Они находятся в стадии разработки, в то же время успешно используются (подробности ускользают от меня).

Ваш пример работает, если вы либо удалите :?, либо укажете тип функции как func(int(32), int(32)):

proc dynamics(x: int(32), f) // or proc dynamics(x: int(32), f: func(int(32), int(32)))

person Vass    schedule 23.05.2020
comment
Функциональные объекты являются разумной альтернативой первоклассным функциям — сделайте запись и определите для нее proc this(args). myRecord(args) вызовет это. - person mppf; 25.05.2020

То же намерение может быть выполнено с передачей lambdified "обратного вызова", потенциально с ассоциативно сопоставленной ALAP-оболочкой обратного вызова.

var f = lambda(n:int){ return -2 * n;};
writeln( f( 123 ) );                                        // lambda --> -246

proc update( x: int(32) ) {                                 // Brian's wish
  return 2*x;
}

proc dynamics( x: int(32), f ) {                            // Vass' solution
  return f( x );
}
// ---------------------------------------------------------------------------    
writeln( dynamics( 7, f ) );                                // proof-of-work [PASS] --> -14

var A = [ lambda( n:int ){ return 10 * n; },                // associatively mapped lambdified-"callbacks"
          lambda( n:int ){ return 20 * n; },
          lambda( n:int ){ return 30 * n; }
          ];
// ---------------------------------------------------------------------------    
writeln( dynamics( 8, lambda(i:int){ return    f(i); } ) ); // proof-of-work [PASS] --> -16
writeln( dynamics( 8, lambda(i:int){ return A[1](i); } ) ); // proof-of-work [PASS] -->  80
// ---------------------------------------------------------------------------
forall funIDX in 1..3 do
       writeln( dynamics( 8, A[funIDX] ) );                 // proof-of-work [PASS] -->  80 | 160 | 240

The whole TiO.run online-IDE mock-up здесь.

person user3666197    schedule 23.05.2020