Now that we're stabilizing the language, we need to decide as soon as possible if the long planned 'func' keyword makes it into the language or not. Func should be a shortcut for 'proc {.noSideEffect, locks: 0.}', however the current plan is to make it extensible.
Basic idea:
(In system.nim):
# special syntax to declare the semantics of the 'func' keyword
template `func` = {.noSideEffect, locks: 0.}
func foo(x, y: int): int = x+y
But you can override this for convienence in wrappers:
template `func` = {.importc: "Tcl_$1", dynlib: "foo.dll", cdecl.}
type Interpreter = object
func runInterpreter(x: var Interpreter)
func open(x: var Interpreter): bool
func close(x: Interpreter)
Essentially replacing the slightly error prone pragma '.push' way of doing things.
Opinions?
IMHO, func keyword doesn't look like a killer feature. It adds a new notion to the language with a strange template definition syntax, that users have to learn, but the functionality it offers seems somewhat rudimentary to me. What I would really like to play with is some sort of parser interrupt macros, that take control of the parser, whenever parser meets them. E.g.
macro `func`(p: parser): stmt =
assert(p.input[p.location - 4 .. p.location] == "func")
let procHeader = p.parseProcHeader()
let procBody = p.parseProcBody()
result = ... # rewrite the code somehow
p.location = ... # change parser location if needed
func myFunc() =
# ^ - the interrupt is called here. It will consume the rest of the proc
discard
It's not about whether it's a killer feature or how to really define it. The primary question is if we should make it a keyword now before it's too late and code will break when we decide it's necessary.
@LeFF: I don't really mind if 'func' becomes a keyword or not, but the number of keywords is a very poor indicator for a language's complexity.
The primary question is if we should make it a keyword now before it's too late and code will break when we decide it's necessary.
I agree that number of keywords is not good metric and aware that there is mechanism to achieve func's feature, but, imho, I believe that having 'func' keyword is worth to have in order to emit good signals about the language for users which like to see FP features in a language...if the price for one more keyword is not too expensive.
My first thought was that func isn't really needed because it can be expressed in other ways, and it can be prone to misuse because it hides the noSideEffect pragma, so some people will accidentally use it for code that breaks the assumptions that pragma introduces.
But then again this may have a use since most people won't bother with pragmas.
What I would really like to play with is some sort of parser interrupt macros, that take control of the parser, whenever parser meets them.
Not gonna happen. The current way that the parser can operate completely without any symbol table is superior.
It would be cooler though if one day we could just "import func" to use it
That's something that we should really consider: from future import func.
I don't really like the idea of allowing overloading of a keyword. In my opinion, the second example you provide is exactly the sort of misuse that should be avoided.
Do people really have trouble with {.push.} and {.pop.}? In my experience they've been very straightforward to use.
If the goal is to get rid of them, perhaps the better solution would be fir the user to make a macro that applies a pragma on every proc inside it, like so:
cdeclProcs:
proc foo(): cint
proc bar(a: cstring, b: csize): cint
pwernersbach ... most people won't bother with pragmas.
I think there's a bit of truth to that. Pragmas seem like a necessary evil, but something I wish I could do without.
flaviu If the goal is to get rid of them, perhaps the better solution would be for the user to make a macro that applies a pragma on every proc inside it
I like this approach for pragmas.
I'm a pretty hardcore fp fan and the choice of 'proc' doesn't bother me. IMO 'func' is just gilding the lilly. Still, making it a keyword just in case is no big deal. People can use fn or fun or whatever if they use func now.
If I understand well Araq's idea, the point of making func a private keyword is to make sure that people will not start using it as a variable/procedure name in their code. (And this is very likely, given the genericity of such a name!)
In general, if Araq or anybody has ideas about how to implement func, reserving the keyword seems a good idea. I am sure I have read in the past more than one language specification which contained sentences like, "...this keyword is reserved for future use". Perhaps, if there is no agreement about how to implement func in Nim 1.0, we could just mark it as reserved and leave its implementation for Nim 1.1, 1.2, or 2.0...
# doesn't really work:
macroActingLikeProc foo(a: int): int =
result = a
But ok, one step after the other, I will make 'func' a keyword first and after 1.0 we'll figure out what to do with it. ;-)
flaviu: If the goal is to get rid of them, perhaps the better solution would be fir the user to make a macro that applies a pragma on every proc inside it, like so:
Just have a 'push' pragma that takes a list of pragmas to apply