ooc-lang / rock

:ocean: self-hosted ooc compiler that generates c99
http://ooc-lang.org/
MIT License
401 stars 40 forks source link

Funcs should behave as Closures with extra type information. #997

Open alexnask opened 8 years ago

alexnask commented 8 years ago

Concretely, you should be able to access Closure fields and methods without having to cast a Func into a Closure.

Func should really just be used to specify the type of the raw function pointer (thunk) stored by the Closure.

In the bundled sdk, this change has two small effects:


f: func (c: Closure) {}

g: Func(...) -> Int
// This is now allowed, Func types are compatible with Closure
f(g)

low_level_c_func: extern func (thunk, userData: Pointer) -> Int
doLowLevelStuff: func (f: Func) -> Int {
    // No need to cast f to Closure to retrieve thunk and context
    low_level_c_func(f thunk, f context)
}

In ooc-kean, this helps with cleaning up closures, since you can call free() without casting all your Funcs into Closures.

All in all, I believe this is the kind of small features that should be acceptable, since it is just a small quality of life improvement regarding two baked-in types that have been known to be a hassle to work together, while they effectively represent the same thing.

marcusnaslund commented 8 years ago

call free() without casting all your Funcs into Closures.

This would make so, so, happy. :)

alexnask commented 8 years ago

@marcusnaslund
I guessed so, and I see no reason why it shouldn't work when Func types are already baked in and considered as Closure by rock.

marcusnaslund commented 8 years ago

I'm curious, what is the underlying difference between a Closure and a Func, and why are they two different types?

alexnask commented 8 years ago

@marcusnaslund

As far as I am aware, there is no actual difference between the types in the C output.
The two types are exactly the same, which is why you can cast from one to another without issues in ooc.

Using Func types assumes a Closure type with a thunk and context Pointer is defined by the SDK and that is about it.

Now, Func types are needed to keep type information about the closure and ensure typechecking, since a Closure is simply a pair of Pointers (casting a Func to a Closure means you don't know how to call it anymore).

alexnask commented 8 years ago

In other words, Func types are not actually defined anywhere (as opposed to pretty much every other type in ooc), they behave as (and expect) Closures but are a necessity for typecheking and calling the functions correctly.

marcusnaslund commented 8 years ago

Interesting, thanks. Sounds like an easy fix, then.

alexnask commented 8 years ago

Shouldn't be too difficult, especially making the types compatible.
The access stuff could be a little bit more tricky but I do think it's pretty straightforward.

I will be trying to fix #998 today and then I'll be on this one.