How to call two functions and use their results as arguments for each other? - recursion

I have code:
let join a ~with':b ~by:key =
let rec a' = link a ~to':b' ~by:key
and b' = link b ~to':a' ~by:(Key.opposite key) in
a'
and compilation result for it is:
Error: This kind of expression is not allowed as right-hand side of
`let rec' build complete
I can rewrite it to:
let join a ~with':b ~by:key =
let rec a'() = link a ~to':(b'()) ~by:key
and b'() = link b ~to':(a'()) ~by:(Key.opposite key) in
a'()
It is compilable variant, but implemented function is infinitely recursive and it is not what I need.
My questions: Why is first implementation invalid? How to call two functions and use their results as arguments for each other?
My compiler version = 4.01.0

The answer to your first question is given in Section 7.3 of the OCaml manual. Here's what it says:
Informally, the class of accepted definitions consists of those definitions where the defined names occur only inside function bodies or as argument to a data constructor.
Your names appear as function arguments, which isn't supported.
I suspect the reason is that you can't assign a semantics otherwise. It seems to me the infinite computation that you see is impossible to avoid in general.

Related

Multiple dispatch in julia with the same variable type

Usually the multiple dispatch in julia is straightforward if one of the parameters in a function changes data type, for example Float64 vs Complex{Float64}. How can I implement multiple dispatch if the parameter is an integer, and I want two functions, one for even and other for odd values?
You may be able to solve this with a #generated function: https://docs.julialang.org/en/v1/manual/metaprogramming/#Generated-functions-1
But the simplest solution is to use an ordinary branch in your code:
function foo(x::MyType{N}) where {N}
if isodd(N)
return _oddfoo(x)
else
return _evenfoo(x)
end
end
This may seem as a defeat for the type system, but if N is known at compile-time, the compiler will actually select only the correct branch, and you will get static dispatch to the correct function, without loss of performance.
This is idiomatic, and as far as I know the recommended solution in most cases.
I expect that with type dispatch you ultimately still are calling after a check on odd versus even, so the most economical of code, without a run-time penatly, is going to be having the caller check the argument and call the proper function.
If you nevertheless have to be type based, for some reason unrelated to run-time efficiency, here is an example of such:
abstract type HasParity end
struct Odd <: HasParity
i::Int64
Odd(i::Integer) = new(isodd(i) ? i : error("not odd"))
end
struct Even <: HasParity
i::Int64
Even(i::Integer) = new(iseven(i) ? i : error("not even"))
end
parity(i) = return iseven(i) ? Even(i) : Odd(i)
foo(i::Odd) = println("$i is odd.")
foo(i::Even) = println("$i is even.")
for n in 1:4
k::HasParity = parity(n)
foo(k)
end
So here's other option which I think is cleaner and more multiple dispatch oriented (given by a coworker). Let's think N is the natural number to be checked and I want two functions that do different stuff depending if N is even or odd. Thus
boolN = rem(N,2) == 0
(...)
function f1(::Val{true}, ...)
(...)
end
function f1(::Val{false}, ...)
(...)
end
and to call the function just do
f1(Val(boolN))
As #logankilpatrick pointed out the dispatch system is type based. What you are dispatching on, though, is well established pattern known as a trait.
Essentially your code looks like
myfunc(num) = iseven(num) ? _even_func(num) : _odd_func(num)

DelimitedFiles.readdlm(source, ....) modifies source, is that really intended and where in the documentation/definition is this explained?

surprised to find that DelimitedFiles.readdlm(source, ...) changes the source input parameter. surprised because Ι could find no indication hereof in the official documentation https://docs.julialang.org/en/v1/stdlib/DelimitedFiles/index.html. is this just a standard assumption about mutability in julia? i thought that somefunction that might change an input parameter would indicate this with somefunction! (adding ! to the function name)?
Ι used the function as follows:
out = DelimitedFiles.readdlm(source,',',header=true)
before the call, source has type Array{UInt8,1} and has several elements. after the call, out has type Tuple{Array{Any,2},Array{AbstractString,2}}, source has type Array{UInt8,1} (unchanged) and source is empty (changed).
The reason is that String(vec::Vector{UInt8}) does not perform a copy but takes ownership of vec (and mutates it).
For now you should write:
out = DelimitedFiles.readdlm(copy(source),',',header=true)
I have asked a question here to clarify what is the intended target behavior (copying or non-copying).

What does the "Base" keyword mean in Julia?

I saw this example in the Julia language documentation. It uses something called Base. What is this Base?
immutable Squares
count::Int
end
Base.start(::Squares) = 1
Base.next(S::Squares, state) = (state*state, state+1)
Base.done(S::Squares, s) = s > S.count;
Base.eltype(::Type{Squares}) = Int # Note that this is defined for the type
Base.length(S::Squares) = S.count;
Base is a module which defines many of the functions, types and macros used in the Julia language. You can view the files for everything it contains here or call whos(Base) to print a list.
In fact, these functions and types (which include things like sum and Int) are so fundamental to the language that they are included in Julia's top-level scope by default.
This means that we can just use sum instead of Base.sum every time we want to use that particular function. Both names refer to the same thing:
Julia> sum === Base.sum
true
Julia> #which sum # show where the name is defined
Base
So why, you might ask, is it necessary is write things like Base.start instead of simply start?
The point is that start is just a name. We are free to rebind names in the top-level scope to anything we like. For instance start = 0 will rebind the name 'start' to the integer 0 (so that it no longer refers to Base.start).
Concentrating now on the specific example in docs, if we simply wrote start(::Squares) = 1, then we find that we have created a new function with 1 method:
Julia> start
start (generic function with 1 method)
But Julia's iterator interface (invoked using the for loop) requires us to add the new method to Base.start! We haven't done this and so we get an error if we try to iterate:
julia> for i in Squares(7)
println(i)
end
ERROR: MethodError: no method matching start(::Squares)
By updating the Base.start function instead by writing Base.start(::Squares) = 1, the iterator interface can use the method for the Squares type and iteration will work as we expect (as long as Base.done and Base.next are also extended for this type).
I'll grant that for something so fundamental, the explanation is buried a bit far down in the documentation, but http://docs.julialang.org/en/release-0.4/manual/modules/#standard-modules describes this:
There are three important standard modules: Main, Core, and Base.
Base is the standard library (the contents of base/). All modules
implicitly contain using Base, since this is needed in the vast
majority of cases.

julia introspection - get name of variable passed to function

In Julia, is there any way to get the name of a passed to a function?
x = 10
function myfunc(a)
# do something here
end
assert(myfunc(x) == "x")
Do I need to use macros or is there a native method that provides introspection?
You can grab the variable name with a macro:
julia> macro mymacro(arg)
string(arg)
end
julia> #mymacro(x)
"x"
julia> #assert(#mymacro(x) == "x")
but as others have said, I'm not sure why you'd need that.
Macros operate on the AST (code tree) during compile time, and the x is passed into the macro as the Symbol :x. You can turn a Symbol into a string and vice versa. Macros replace code with code, so the #mymacro(x) is simply pulled out and replaced with string(:x).
Ok, contradicting myself: technically this is possible in a very hacky way, under one (fairly limiting) condition: the function name must have only one method signature. The idea is very similar the answers to such questions for Python. Before the demo, I must emphasize that these are internal compiler details and are subject to change. Briefly:
julia> function foo(x)
bt = backtrace()
fobj = eval(current_module(), symbol(Profile.lookup(bt[3]).func))
Base.arg_decl_parts(fobj.env.defs)[2][1][1]
end
foo (generic function with 1 method)
julia> foo(1)
"x"
Let me re-emphasize that this is a bad idea, and should not be used for anything! (well, except for backtrace display). This is basically "stupid compiler tricks", but I'm showing it because it can be kind of educational to play with these objects, and the explanation does lead to a more useful answer to the clarifying comment by #ejang.
Explanation:
bt = backtrace() generates a ... backtrace ... from the current position. bt is an array of pointers, where each pointer is the address of a frame in the current call stack.
Profile.lookup(bt[3]) returns a LineInfo object with the function name (and several other details about each frame). Note that bt[1] and bt[2] are in the backtrace-generation function itself, so we need to go further up the stack to get the caller.
Profile.lookup(...).func returns the function name (the symbol :foo)
eval(current_module(), Profile.lookup(...)) returns the function object associated with the name :foo in the current_module(). If we modify the definition of function foo to return fobj, then note the equivalence to the foo object in the REPL:
julia> function foo(x)
bt = backtrace()
fobj = eval(current_module(), symbol(Profile.lookup(bt[3]).func))
end
foo (generic function with 1 method)
julia> foo(1) == foo
true
fobj.env.defs returns the first Method entry from the MethodTable for foo/fobj
Base.decl_arg_parts is a helper function (defined in methodshow.jl) that extracts argument information from a given Method.
the rest of the indexing drills down to the name of the argument.
Regarding the restriction that the function have only one method signature, the reason is that multiple signatures will all be listed (see defs.next) in the MethodTable. As far as I know there is no currently exposed interface to get the specific method associated with a given frame address. (as an exercise for the advanced reader: one way to do this would be to modify the address lookup functionality in jl_getFunctionInfo to also return the mangled function name, which could then be re-associated with the specific method invocation; however, I don't think we currently store a reverse mapping from mangled name -> Method).
Note also that (1) backtraces are slow (2) there is no notion of "function-local" eval in Julia, so even if one has the variable name, I believe it would be impossible to actually access the variable (and the compiler may completely elide local variables, unused or otherwise, put them in a register, etc.)
As for the IDE-style introspection use mentioned in the comments: foo.env.defs as shown above is one place to start for "object introspection". From the debugging side, Gallium.jl can inspect DWARF local variable info in a given frame. Finally, JuliaParser.jl is a pure-Julia implementation of the Julia parser that is actively used in several IDEs to introspect code blocks at a high level.
Another method is to use the function's vinfo. Here is an example:
function test(argx::Int64)
vinfo = code_lowered(test,(Int64,))
string(vinfo[1].args[1][1])
end
test (generic function with 1 method)
julia> test(10)
"argx"
The above depends on knowing the signature of the function, but this is a non-issue if it is coded within the function itself (otherwise some macro magic could be needed).

generic duck typing in F#?

using let inline and member constraints I'll be able to make duck typing for known members but what if I would like to define a generic function like so:
let duckwrapper<'a> duck = ...
with the signature 'b -> 'a and where the returned value would be an object that implemented 'a (which would be an interface) and forwarded the calls to duck.
I've done this in C# using Reflection.Emit but I'm wondering if F# reflection, quotations or other constructs would make it easier.
Any suggestions on how to accomplish this?
EDIT
after reading Tims answer I thought I'd give a bit more details
What I was thinking of when I wrote about using quotations to help was something like:
{new IInterface with member x.SayHello() = !!<# %expr #>}
!! being an operator translating the quotation to a function and %expr being the unit of work for the method. I'd be able to translate the expression to a function (I guess) but wouldn't know how to
of course this wouldn't do the trick completely either since IInterface would be 'a which is where I hope F# reflection might have some handy functions so that I could construct a type based on a type object and some function values
EDIT
As an update to Tomas Petricek answer I'll give some code to explain my needs
type SourceRole =
abstract transfer : decimal -> context
and context(sourceAccount:account, destinationAccount) =
let source = sourceAccount
let destination = destinationAccount
member self.transfer amount =
let sourcePlayer =
{new SourceRole with
member this.transfer amount =
use scope = new TransactionScope()
let source = source.decreaseBalance amount
let destination = destination.increaseBalance amount
scope.Complete()
context(source,destination)
}
sourcePlayer.transfer(amount)
which is a try at porting "the" textbook example of DCI in F#. The source and destination are DCI roles. It's the idea that any data object that adhere's to a specific contract can play those. In this case the contract is simple. source needs a memberfunction called decreaseBalance and destination needs a member function called increaseBalance.
I can accomplish that for this specific case with let inline and member constraints.
But I'd like to write a set of functions that given an interface and an object. In this case it could be source (as the object) and
type sourceContract =
abstract decreaseBalance : decimal -> sourceContract
as the type. The result would be an object of type sourceContract that would pipe method calls to a method with the same name on the source object.
F# reflection (Microsoft.FSharp.Reflection) is an F#-friendly wrapper around the plain System.Reflection APIs, so I don't think it would add anything here.
Quotations can't define new types: (you'd need to define a new type to do your interface-based duck typing)
> <# { new IInterface with member x.SayHello = "hello" } #>;;
<# { new IInterface with member x.SayHello = "hello" } #>;;
---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stdin(7,4): error FS0449: Quotations cannot contain object expressions
> <# type Test() = class end #>;;
<# type Test() = class end #>;;
---^^^^
stdin(8,4): error FS0010: Unexpected keyword 'type' in quotation literal
Reflection.Emit is still the way to go with this.
Edit:
I hope F# reflection might have some handy functions so that I could construct a type based on a type object and some function values
I'm afraid it doesn't. Here's the documentation on F# reflection: http://msdn.microsoft.com/en-gb/library/ee353491.aspx
You can compile F# quotations using components from F# PowerPack. So I think you could use quotations to generate and execute code at runtime. If you write a quotation representing a function & compile it you'll get a function value that you could use to implement an interface. Here is a trivial example:
#r "FSharp.PowerPack.Linq.dll"
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.QuotationEvaluation
// Create a part using "Expr." calls explicitly
let expr = Expr.Value(13)
// Create a part using quotation syntax
let expr2 = <# (fun x -> x * %%expr) #>
// Compile & Run
let f = expr2.Compile()()
f 10
You can mix quotation syntax and calls to Expr, which makes it easier to compose code from basic blocks. The compilation is a bit stupid (currently) so the generated code won't be as efficient as usual F# code (but you'll need to measure it in your case).
I'm not quite sure I understand what exactly are you trying to do, so if you can provide more details, I can give more specific answer.

Resources