Skip to content

Instantly share code, notes, and snippets.

@od0x0
Created June 24, 2011 02:28
Show Gist options
  • Save od0x0/1044107 to your computer and use it in GitHub Desktop.
Save od0x0/1044107 to your computer and use it in GitHub Desktop.
Ideas I want to see in ooc
Features (I don't care about the syntax for this at this point):
1. Ignore the underlying ABI that is compiled to
Reasoning: Portability. A good example of how to handle things like this is with .NET/C#, where any name can be used as an identifier, but if it has other syntax nastiness around it (like being a keyword or having spaces in between) it can be prefixed with a @ or surrounded with []. Obviously we'd have to go with something different, but the same concept can be applied. This would allow compatibility with other languages that may (will!) have a different set of keywords than the ones we use in ooc
Alternative: We could just ignore the idea of a direct name mapping of structures/functions and create a JSON "interface" file, blah, blah, blah or do really nasty name mangling.
2. GC built into the language as a language triggered automatic reference counting system
Reasoning: GC is nice, but for applications where it's crucial to make sure that no sudden pauses of any duration occur, such as high performance games, we can't afford to have a collector in the BoehmGC fashion. The key would to be have the GC as a language handled feature that operates without a runtime. A hybrid reference counted system that works similarly to the Apple blocks mechanism, where it starts on the stack but can be copied and then refcounted if it gets moved "upwards" can help, and the language implementation can step in to handle the reference counting so no manual calls need to be made. Of course, if we target a system with gc built in, like the JVM or CLR, we don't need to worry about this.
3. Classes: bye-bye! Prototypes + Interfaces: Hello! (This is major language change, and I doubt it will get implemented for ooc.)
Example:
Readable: interface {
readByte: Func -> Byte
}
Writable: interface {
writeByte: Func(Byte)
}
dummyfile := object (ObjectBaseClassBlahBlahBlah){ //In the C under layer, this would look like a closure would, with it being a structure of refcount, context, message handler, and superclass (classes would be generated by the language, not the programmer)
someProperty := 0
readByte := func(){0}
writeByte := func(byte){}
}
writeMeALlamaLetter := func(out: Writable){out writeByte('l' as Byte)}
writeMeALlamaLetter(dummyfile) //Compile time check, if dummyfile does not implement the methods required of it by Writable, this fails
//Interfaces can only contain methods or setters/getters, no direct access to fields allowed
Reasoning: This allows closures, generics, interfaces, and classes to be unified. It would also potentially simplify the refcounting gc, by only having one type of natively allocatable structure.
4. Anonymous types
Before, we had
Writable: interface {
writeByte: Func(Byte)
}
writeMeALlamaLetter := func(out: Writable){out writeByte('l' as Byte)}
But, what if we only wanted the interface for that particular function and didn't want a whole new identifier used.
We could do this:
writeMeALlamaLetter := func(out: interface {writeByte: Func(Byte)} ){out writeByte('l' as Byte)}
We could then define types similarly as in C with typedefs by using "type"
Writable: type interface {
writeByte: Func(Byte)
}
"cover" would be removed, and replaced with "struct"
Vec3: type struct {
x, y, z: Float
}
Vec2: type struct {
x, y: Float
}
Reasoning: To go along with the prototype idea, and avoid the use of identifiers for one time cases.
Obviously, a lot of these features would create potential for massive coding abuses, but they would be helpful and more consistent than the current magic!
@od0x0
Copy link
Author

od0x0 commented Jul 17, 2011

The point is that other than the code required to raise and lower the reference count, there is no runtime that can possibly be spawned. 0 collectors. Of course there will be overhead (roughly equivalent to manual reference counting), but it is likely that it will be the same or, in the more likely case, better than the cost of having a collector thread. As far as the other things, it's all a matter of implementation and goals from what I've seen, and we should be able to handle those issues as we come across them.

Also, taking this another step further, we could even have cases such as:

doSomething: func {
for(i in 0...100) Vec3 new(i, i, i) toString() println()
}

optimized by having the compiler recognize the code and switch allocation methods to a stack for Vec3, and an optimistically small sized stack for the string which can switch to malloc'd memory if it turns out that toString.returns a string too large.

@od0x0
Copy link
Author

od0x0 commented Jul 17, 2011

Basically, it's a refernce counting GC (similar to the one that python uses), but with added smartness that we gain from ooc's static typing. See http://en.m.wikipedia.org/wiki/Reference_counting

@phest
Copy link

phest commented Jul 17, 2011

So when can we start playing with this? ;)

What are the biggest challenges in your opinion to get a GC-free ooc?

Side question - how doable and sane is it today - with Rock 0.9.2 - to make ooc99 code play nice with other languages, for instance an ooc99 library used in a objC project?

@od0x0
Copy link
Author

od0x0 commented Jul 17, 2011

The biggest challenge I see would be to have a very clean compiler design that promotes aggressive optimizations. This would probably be something left to oc rather than rock for that reason. I really have no clue how doable it is today, as even though you can create an sdk that doesn't use a garbage collector (as I have done before), the compiler still calls the gc for things like generics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment