如何在不使用 eval 的情况下从符号中获取函数? [英] How to get a function from a symbol without using eval?

查看:20
本文介绍了如何在不使用 eval 的情况下从符号中获取函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I've got a symbol that represents the name of a function to be called:

julia> func_sym = :tanh

I can use that symbol to get the tanh function and call it using:

julia> eval(func_sym)(2)
0.9640275800758169

But I'd rather avoid the 'eval' there as it will be called many times and it's expensive (and func_sym can have several different values depending on context).

IIRC in Ruby you can say something like:

obj.send(func_sym, args)

Is there something similar in Julia?

EDIT: some more details on why I have functions represented by symbols:

I have a type (from a neural network) that includes the activation function, originally I included it as a funcion:

type NeuralLayer
  weights::Matrix{Float32}
  biases::Vector{Float32}
  a_func::Function
end

However, I needed to serialize these things to files using JLD, but it's not possible to serialize a Function, so I went with a symbol:

type NeuralLayer
  weights::Matrix{Float32}
  biases::Vector{Float32}
  a_func::Symbol
end

And currently I use the eval approach above to call the activation function. There are collections of NeuralLayers and each can have it's own activation function.

解决方案

@Isaiah's answer is spot-on; perhaps even more-so after the edit to the original question. To elaborate and make this more specific to your case: I'd change your NeuralLayer type to be parametric:

type NeuralLayer{func_type}
  weights::Matrix{Float32}
  biases::Vector{Float32}
end

Since func_type doesn't appear in the types of the fields, the constructor will require you to explicitly specify it: layer = NeuralLayer{:excitatory}(w, b). One restriction here is that you cannot modify a type parameter.

Now, func_type could be a symbol (like you're doing now) or it could be a more functionally relevant parameter (or parameters) that tunes your activation function. Then you define your activation functions like this:

# If you define your NeuralLayer with just one parameter:
activation(layer::NeuralLayer{:inhibitory}) = …
activation(layer::NeuralLayer{:excitatory}) = …
# Or if you want to use several physiological parameters instead:
activation{g_K,g_Na,g_l}(layer::NeuralLayer{g_K,g_Na,g_l} = f(g_K, g_Na, g_l)

The key point is that functions and behavior are external to the data. Use type definitions and abstract type hierarchies to define behavior, as is coded in the external functions… but only store data itself in the types. This is dramatically different from Python or other strongly object-oriented paradigms, and it takes some getting used to.

这篇关于如何在不使用 eval 的情况下从符号中获取函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆