Example of using Lambda to store and call a C3 method

#1

I’m having trouble assigning a function to a field of a C3 Object, and then invoking the function later. My simple example in the Javascript console (complete with error messages) is as follows:

// This works
> MachineLearningClassificationMetric.accuracy([1, 2], [1, 0])
0.5

> var x = MachineLearningPerformanceMetric.make({score: MachineLearningClassificationMetric.accuracy, higherIsBetter: true})
undefined

> x.score([[1, 2], [1, 0]])
VM46396:1 Uncaught TypeError: x.score is not a function
    at <anonymous>:1:3
(anonymous) @ VM46396:100:
 
> x.score.call([[1, 2], [1, 0]])
VM46263:5 Uncaught TypeError: this._call is not a function
    at anonymous (eval at applyJS (eval at getLocalImpl (all.js?env=browser&compat:642)), <anonymous>:5:15)
    at Object.applyJS (eval at getLocalImpl (all.js?env=browser&compat:642), <anonymous>:7:17)
    at Object.callLocalImpl (all.js?env=browser&compat:707)
    at Object.call (all.js?env=browser&compat:537)
    at c3Call (all.js?env=browser&compat:99)
    at Object._call (all.js?env=browser&compat:2704)
    at Object.eval (eval at get (all.js?env=browser&compat:3204), <anonymous>:5:22)
    at Object.value (all.js?env=browser&compat:6918)
    at <anonymous>:1:9
anonymous @ VM46263:5
applyJS @ VM45556:7
callLocalImpl @ all.js?env=browser&compat:707
call @ all.js?env=browser&compat:537
c3Call @ all.js?env=browser&compat:99
_call @ all.js?env=browser&compat:2704
(anonymous) @ VM45518:5
value @ all.js?env=browser&compat:6918
(anonymous) @ VM46262:1

> MachineLearningClassificationMetric.accuracy
ƒ anonymous(truth,prediction
/*``*/) {
  if (arguments.length > 2)
    throw new C3.typesys.Error('Function "accuracy" on MachineLearningClassificationMetric takes 2 arguments.', "InvalidInputParam");

> z = c3Make('Lambda<function(truth: [double], prediction: [double]): double>', {
       language: "javascript",
       implementation: MachineLearningClassificationMetric.accuracy
      })
{language: "javascript", implementation: "function anonymous(truth,prediction↵/*``*/) {↵  if…cy", { truth: truth, prediction: prediction });↵}", environment: C3.t…s.Map, appliedArgs: C3.t…s.Map, apply: ƒ, …}

> z.call([[1, 2], [1, 0]])
VM46379:5 Uncaught TypeError: this._call is not a function
    at anonymous (eval at applyJS (eval at getLocalImpl (all.js?env=browser&compat:642)), <anonymous>:5:15)
    at Object.applyJS (eval at getLocalImpl (all.js?env=browser&compat:642), <anonymous>:7:17)
    at Object.callLocalImpl (all.js?env=browser&compat:707)
    at Object.call (all.js?env=browser&compat:537)
    at c3Call (all.js?env=browser&compat:99)
    at Object._call (all.js?env=browser&compat:2704)
    at Object.eval (eval at get (all.js?env=browser&compat:3204), <anonymous>:5:22)
    at Object.value (all.js?env=browser&compat:6918)
    at <anonymous>:1:3

> z([[1, 2], [1, 0]])
VM46408:1 Uncaught TypeError: z is not a function
    at <anonymous>:1:1
…

// Try to create a lambda another way
> test = Lambda.fromAction(MachineLearningClassificationMetric.myReferenceType, "accuracy")
all.js?env=browser&compat:19964 POST http://localhost:8080/api/1/machineLearning/prod/Lambda?action=fromAction 400 (Bad Request)
C3.client.sendRequest @ all.js?env=browser&compat:19964
request @ all.js?env=browser&compat:860
call @ all.js?env=browser&compat:566
c3Call @ all.js?env=browser&compat:99
_call @ all.js?env=browser&compat:2704
(anonymous) @ VM46999:5
(anonymous) @ VM47332:1
all.js?env=browser&compat:569 Uncaught C3.client.ActionError {name: "ActionError", message: "Invalid field name typeName for type Type at JSON document at 1:22", error: C3.t…s.Obj, stack: "Error: Invalid field name typeName for type Type a…14:20), <anonymous>:5:15)↵    at <anonymous>:1:15"}

// This seems to work... can I use it?
> TypeRef.fromType(MachineLearningClassificationMetric)
{typeName: "MachineLearningClassificationMetric", __noSuchMethod__: ƒ, toType: ƒ}

> test = Lambda.fromAction(TypeRef.fromType(MachineLearningClassificationMetric), "accuracy")
all.js?env=browser&compat:19964 POST http://localhost:8080/api/1/machineLearning/prod/Lambda?action=fromAction 400 (Bad Request)
C3.client.sendRequest @ all.js?env=browser&compat:19964
request @ all.js?env=browser&compat:860
call @ all.js?env=browser&compat:566
c3Call @ all.js?env=browser&compat:99
_call @ all.js?env=browser&compat:2704
(anonymous) @ VM46999:5
(anonymous) @ VM47501:1
all.js?env=browser&compat:569 Uncaught C3.client.ActionError {name: "ActionError", message: "Invalid field name typeName for type Type at JSON document at 1:22", error: C3.t…s.Obj, stack: "Error: Invalid field name typeName for type Type a…14:20), <anonymous>:5:15)↵    at <anonymous>:1:15"}error: C3.typesys.Obj {id: "6459.10", key: "c3.love.typesys.obj.pipe.ObjValueIteratorBase_badField", template: "Invalid field name {} for type {} at {}", parameters: Array(3), codes: Array(1), …}message: "Invalid field name typeName for type Type at JSON document at 1:22"name: "ActionError"stack: "Error: Invalid field name typeName for type Type at JSON document at 1:22↵    at new C3.client.ActionError (http://localhost:8080/typesys/1/all.js?env=browser&compat:1129:13)↵    at Object.request (http://localhost:8080/typesys/1/all.js?env=browser&compat:881:15)↵    at Object.call (http://localhost:8080/typesys/1/all.js?env=browser&compat:566:27)↵    at c3Call (http://localhost:8080/typesys/1/all.js?env=browser&compat:99:20)↵    at Object._call (http://localhost:8080/typesys/1/all.js?env=browser&compat:2704:20)↵    at Object.eval (eval at get (http://localhost:8080/typesys/1/all.js?env=browser&compat:3114:20), <anonymous>:5:15)↵    at <anonymous>:1:15"__proto__: Error
call @ all.js?env=browser&compat:569
c3Call @ all.js?env=browser&compat:99
_call @ all.js?env=browser&compat:2704
(anonymous) @ VM46999:5
(anonymous) @ VM47501:1

The relevant fields of MachineLearningPerformanceMetric are:

type MachineLearningPerformanceMetric {
  score: !Lambda<function(truth: !?[double], prediction: !?[double]): !double>  schema suffix 'SCR'
  higherIsBetter: !boolean
}

And the relevant fields of MachineLearningClassificationMetric:

entity type MachineLearningClassificationMetric mixes MachineLearningPerformanceMetric schema name "MLCLFMTRC"{
  accuracy : function(truth: !?[double], prediction: !?[double]): !double
}

You can see I’m desperately trying different combinations toward the end. Can anyone point me to a working example?

0 Likes

#2

try something like:

MachineLearningPerformanceMetric.make({score: function(arg1, arg2) {
  return MachineLearningClassificationMetric.accuracy(arg1, arg2);
}, higherIsBetter: true})
0 Likes

#3

The second JavaScript error looks like a bug to me. While the lambda is not a JavaScript function, calling call or apply on it should invoke the lambda logic.

0 Likes

#4

Thanks, bachr. Your example works, but I have trouble adapting it to my final use case.

// Working example
> var test = MachineLearningPerformanceMetric.make({score: function(arg1, arg2) {
  return MachineLearningClassificationMetric.accuracy(arg1, arg2);
}, higherIsBetter: true})

> test.score.call([1, 2], [1, 0])
0.5

I would like to do the above inside of a Javascript function, to reuse the code for different methods defined on MachineLearningClassifcationMetric (or MachineLearningRegressionMetric). So I’m trying:

> var funcField = MachineLearningClassificationMetric.accuracy
undefined
> var test = MachineLearningPerformanceMetric.make({score: function(arg1, arg2) {
  return funcField(arg1, arg2);
}, higherIsBetter: true})
undefined
> test.score.call([1, 2], [1, 0])
VM45272:5 Uncaught TypeError: this._call is not a function
    at eval (eval at get (all.js?env=browser&compat:3114), <anonymous>:5:15)
    at eval (eval at applyJS (eval at getLocalImpl (all.js?env=browser&compat:642)), <anonymous>:2:10)
    at Object.applyJS (eval at getLocalImpl (all.js?env=browser&compat:642), <anonymous>:7:17)
    at Object.callLocalImpl (all.js?env=browser&compat:707)
    at Object.call (all.js?env=browser&compat:537)
    at c3Call (all.js?env=browser&compat:99)
    at Object._call (all.js?env=browser&compat:2704)
    at Object.eval (eval at get (all.js?env=browser&compat:3204), <anonymous>:5:22)
    at Object.value (all.js?env=browser&compat:6918)
    at <anonymous>:1:12
0 Likes