Hacking on the odin compiler

Another day, another adventure! Today I managed to hack a procedure short hand syntax into the odin compiler. Question for the maintainers: Is this against the philosophy of the odin?

package main

import "core:fmt"

add :: proc(x: i32, y: i32) -> i32 = return x + y

test :: proc() -> proc() {
	inner :: proc() = fmt.println("Inner")
	return inner
}

multi_return :: proc() -> (int, int, bool) = return 10, 20, true

main :: proc() {
	fmt.println("=", add(10, 20))
	x, y, b := multi_return()
	inner := test()
	inner()
}

I compiles and works as expected btw:
Odin

  • Why? - To simplify procedures that only perform one task and reducing the code size

I’m really enjoying odin :smiley:

Well there is a reason why it’s not in the Odin compiler. I can’t tell you about the decision to not include this syntactic sugar into the compiler, because I wasn’t the one who made it, nor I was there when it was made, but it’s probably something along the lines of “it doesnt solve any real problem except for providing a syntax sugar”. But also, if you wanted to do something like this you could have also removed the return keyword and went with something along the lines of:

add :: proc(x, y: int) -> int => x + y
1 Like

Holy molly, I should’ve tried => . Anyway it was fun to “Hack” the compiler a bit, off to the next odin adventure!

1 Like

I guess the other thing is that you don’t need the return type in this case as it’s trivially deduceable. One thing you can do is to make it optional.

1 Like

Im not really active in Odin anymore lately but this kind of thing if it has few side effect should definitely be allowed. The only case against it is adding more complex conditional logic in the compiler for very little benefit.

1 Like

You mean like Maybe($T)?

Odin did actually have shorthand for one-line procedures with do for a while. This was removed because it turns out it is 100% ambiguous to parse with multiple return values.

Remember to view this from a purely syntax standpoint (context free grammar); I’ll write the basic example:

foo :: proc() -> bool do return true, 10

So from the parser’s standpoint, which is correct?

foo :: (proc() -> bool do return true), 10
// or
foo :: (proc() -> bool do return true, 10)

The commas in the multiple return values is what makes it ambiguous to parse and know what is meant to be the valid intent. This might sound like less of a problem in this case but it becomes one when used as a procedure argument:

foo(proc() -> bool do return true, 10)

Which is this now? (REMEMBER CONTEXT FREE GRAMMAR AGAIN)

foo((proc() -> bool do return true), 10)
// or
foo((proc() -> bool do return true, 10))

Just enforcing braces for procedure bodies removes this ambiguity entirely.

Also, it’s not actually any less to type in practice either. {} vs do are the same amount of characters after all.

7 Likes