Having fun with ooc
👋 This page was last updated ~12 years ago. Just so you know.
Unfortunately, the ooc language could have better documentation. In the meantime, I'd like to blog about about some features that might not be very well-known.
Nested functions
Here's a program that prints 1, 3, 5, 7, 9
:
import structs/ArrayList main: func { list := ArrayList<Int> new() addIfOdd := func (i: Int) { if (i % 2 != 0) list add(i) } for (i in 0..10) { addIfOdd(i) } list map(|i| i toString()) join(", ") println() }
If you're doing something repeatedly, and it won't be too readable with a closure, you can simply declare a nested function! Note that we don't make use of the GNUC extension here, the ooc compiler unwraps it as a proper closure, with a context and all.
Filter, map, join, backslash line continuations
That program prints exactly the same thing, but it does it in fewer lines:
import structs/ArrayList main: func { list := ArrayList<Int> new() for (i in 0..10) list add(i) list filter(|i| i % 2 != 0) \ map(|i| i toString()) \ join(", ") \ println() }
As in most languages, you can call the filter
(only retain element if the condition
is true) and map
(create a new list with elements returned by the function) methods on
lists.
join
also works on ListInt
to String
before
calling it.
Extending classes and covers
Always with the same output, this program is a bit more convoluted:
import structs/[ArrayList, List] extend Range { list: func -> ArrayList<Int> { list := ArrayList<Int> new() for (i in min..max) list add(i) list } } extend List<Int> { filterEven: func -> List<T> { filter(|i| i as Int % 2 != 0) } println: func { map(|i| i as Int toString()) join(", ") println() } } main: func { (0..10) list() filterEven() println() }
The point of this example is to show that even though ooc is a static language,
and even if you use types defined in external libraries, you can add methods to it.
They'll only be accessible from modules where you import the module containing
the extends
, and they aren't overloadable by subclasses, etc. etc.
They're basically syntactic sugar! Sweet, sweet syntactic sugar.
Note that in that example, we extend both a cover, ie. Range
, and a generic
class, ie. List<T>
. As a reminder, covers are by-value, and they usually have
a 1-1 mapping with underlying C types (e.g. Int, Float, Double are all covers),
or they define a structure (like Range, in this case).
As you can see, extending a cover works quite well, but for generic classes,
the compiler ignores the Int
in extend List<Int>
, so within filterEven
and println
we have to cast i to Int ourselves. Not very clean if you
ask me, but it does work.
Conclusion
You've seen three ways to have fun with ooc. It doesn't stop there of course, I might continue blogging about fun features you can benefit from in your ooc programs.
Here's another article just for you:
Long story short: a couple of my articles got really popular on a bunch of sites, and someone, somewhere, went "well, let's see how much traffic that smart-ass can handle", and suddenly I was on the receiving end of a couple DDoS attacks.
It really doesn't matter what the articles were about — the attack is certainly not representative of how folks on either side of any number of debates generally behave.