Yves
Yves

Reputation: 12371

julia: a function object

I want to use an object in Julia, which can be initialized by a function. It's like a function pointer in C.

Here is my goal:

I have a julia script and a julia module.

In this script, I have an array.
The module needs to be able to add some elements into this array.

#script
liste = Int64[]
function addElement(e)
   liste.push(e)
end
include("path/mymodule.jl")
myModule.setAddElementFunc(addElement)
myModule.execute() # error: wrong number of parameter



#mymodule.jl

module myModule
export setAddElementFunc
export execute

addElementFunc = ()->()

funciton setAddElementFunc(fn)
   addElementFunc = fn
end

function execute()
   addElementFunc(3)
end

end

Basically, my idea is:
in the module, we can't do anything BUT add. I need to do such a structure because my job is to code the julia script and some other people will code the module. So I want to limit his right to keep the liste safe, in this case, he can just add elements.

Upvotes: 2

Views: 826

Answers (4)

David P. Sanders
David P. Sanders

Reputation: 5325

A "function pointer" is just a complicated C construction that is necessary because there is no other way of having a different name that you can use to refer to functions.

In Julia, you just literally create another name that refers to the same function object, as I had already done in my first answer, e.g.

hello() = "hi"
goodbye() = "ciao"

f = hello   # f is a "function pointer"
f()

f = goodbye
f()

You can easily put functions inside other data structures, e.g. a dictionary:

greeting = Dict("hello" => hello, "goodbye" => goodbye)

f = greeting["hello"]
f()

Upvotes: 0

David P. Sanders
David P. Sanders

Reputation: 5325

To generate a new type in Julia we can do something like

type MyArray{T}
    elements::Vector{T}
    my_value::Int
end

This automatically makes a couple of default constructors for you. You can make an object of your type by feeding it the initial values for each of its fields.

v = MyArray([3, 5], 17)

In Julia, functions do not live inside objects, but rather are methods defined outside the objects. In this sense, objects in Julia are similar to structs in C, except that they can (and, usually, should) be parametrised by type, as in this example (the {T}).

In this case, for example, you can simply define your own method of the generic function push! from base Julia, to act on objects of your new type:

push!(x::MyArray, value) = push!(x.elements, value)

Now you can do

push!(v, 4)

to add the value 4 to your object.

You should read the Julia manual and have a look at some tutorials for more information on defining types. Let us know if anything is not clear.

Upvotes: 3

Reza Afzalan
Reza Afzalan

Reputation: 5746

Although @David is compliantly right, I would like to point out the usefulness of global keyword. I like to think of it here as an CPP this alike keyword in Julia-Lang.

module test
  addMsgFunc=()->()
  function getAddMsgFunc(fn)
    global addMsgFunc = fn
  end
  function show()
    println("xxxxx")
  end
end
julia> addMsgFunc
ERROR: UndefVarError: addMsgFunc not defined
julia> test.addMsgFunc();
julia> test.getAddMsgFunc(test.show);
julia> test.addMsgFunc()
xxxxx
julia> addMsgFunc # Its in global but in another scope
ERROR: UndefVarError: addMsgFunc not defined
julia> test.addMsgFunc=()->() # You cant assign to it normally
ERROR: cannot assign variables in other modules

Upvotes: 1

David P. Sanders
David P. Sanders

Reputation: 5325

It is not completely clear what you want to do. One possibility is the following:

function getAddMsgFunc(fn)
  fn  # just return the function that is passed in
end

function my_show()
  println("xxxxx")
end

addMsgFunc = getAddMsgFunc(my_show)

addMsgFunc()

Functions are first-class objects in Julia, which means that you can just pass them around by name.

Upvotes: 1

Related Questions