Function call vs field access vs local variable access syntax ============================================================= It would be nice to have different syntax for all of these: * Types * Local variables * Function calls - on `this` - on other objects * Fields - in `this` - in other objects Option 1: Type localvar globalfunc x y (ambiguous. skip bare top-level functions?) methodcall this x y methodcall obj x y .thisfield obj.field Option 2: Type localvar globalfunc x y methodcall x y obj.methodcall x y _thisfield obj._field Option 3: Type $localvar globalfunc $x $y methodcall $x $y $obj.methodcall $x $y this.$field obj.$field Option 4: Type localvar globalfunc x y this.methodcall x y obj.methodcall x y this._field obj._field Option 5: Type localvar globalfunc x y -> res methodcall x y -> res obj.methodcall x y -> res this.field obj.field method_with_0_args -> res void_method Option 6: Type localvar res <- globalfunc x y res <- methodcall x y res <- obj.methodcall x y this.field obj.field res <- call method_with_0_args res <- get localvar void_method Option 7 (traditonal syntax): Type localvar res = globalfunc(x, y) res = methodcall(x, y) res = obj.methodcall(x, y) this.field obj.field res = method_with_0_args() res = localvar void_method() Option 8: Type localvar res <- globalfunc: x y res <- methodcall: x y res <- obj.methodcall: x y this.field obj.field res <- method_with_0_args: res <- localvar void_method: Option 9: Type localvar call globalfunc x y -> res call methodcall x y -> res call obj.methodcall x y -> res this.field obj.field call method_with_0_args res <- localvar call void_method Option 10: Type localvar res = ::globalfunc x y res = :methodcall x y res = obj:methodcall x y this.field obj.field res = :method_with_0_args res = localvar :void_method Option 11: Type localvar res <- !globalfunc x y res <- !methodcall x y res <- obj.!methodcall x y this.field obj.field res <- !method_with_0_args res <- localvar !void_method Option 12: Type localvar res [globalfunc] x y res [methodcall] x y res [obj.methodcall] x y this.field obj.field res [method_with_0_args] res localvar void_method Option 13: Type localvar res (globalfunc x y) res (methodcall x y) res (obj.methodcall x y) this.field obj.field res (method_with_0_args) res localvar void_method Option 14: Type localvar set res (globalfunc x y) set res (methodcall x y) set res (obj.methodcall x y) set rv1 rv2 (obj.methodcall x y) this.field obj.field set res (method_with_0_args) set res localvar void_method Option 15: Type localvar res GlobalFunc x y res MethodCall x y res obj.MethodCall x y this.field obj.field res MethodWith0Args res localvar VoidMethod # won't work with global functions because: IsThisAGlobalFunctionOrAType ambuigity Option 16: Type localvar globalfunc x y this.methodcall x y obj.methodcall x y this._field obj._field # use prefixes such as "do_", "make_", "create_", "new"_ to # distinguish between calls and fields # (i.e. all 0-arg functions MUST begin with any of them) # (and "do" make" "create" "new" on their own, without "_", should also be allowed) do_method_with_0_args do_void_method Option 17: Type localvar globalfunc x y -> res # 1. but what if someone refactors the code and adds a line between # the function call line and the result line? # 2. how common is it to assign a function return value to a variable? # maybe it's more often used in if/while? # maybe many call-and-assign statements are too long to # fit on a single line anyway? methodcall x y -> res obj.methodcall x y -> res this.field obj.field method_with_0_args -> res localvar <- 10 void_method Option 18: Type localvar globalfunc x y r <- result methodcall x y r <- result obj.methodcall x y r <- result this.field obj.field method_with_0_args r <- result localvar <- 10 void_method Option 19: Type localvar res <- globalfunc x y res <- methodcall this x y res <- methodcall obj x y this.field obj.field # method_with_0_args migth not be necessary in this case, # 0-arg functions can be either constructors or methods instead # (but 0-arg constructors might be tricky depending on the exact syntax) res <- localvar # Constructor syntax? # See: constructor_call_syntax.txt list <- new List str <- fromInt String i # How about "long" function calls? (do_stuff_with_many_params list=new item=get_item ) Require `void` for 0-arg function calls inside expressions? # no `void` required at statement level void_method # no `void` required for constructor identifier tokens list <- new connBuilder <- fromDefaults # `void` required ok <- process_items void # ...however, this isn't necessary if `this` is required ok <- process_items this How to avoid `this` keyword in method calls? Note that it is possible to call a method multiple times, on both the `this` object and on other objects within the same function! So both must work at the same time (i.e. it can't be decided at the function level, per identifier). # ambuigity! res <- methodcall x y res <- methodcall obj x y # this gets worse with generic names: # example: this is problematic if `add` is a local method that # takes a list and a number: add list num # Could make the `this` symbol shorter: res <- methodcall _ x y add _ list num _.field = 123 # Or use a different syntax res <- :methodcall x y res <- methodcall obj x y :add list num :field = 123 ok <- :process_items void # Or this - but unfortunately looks like a typeident/enum value :( res <- .methodcall x y res <- methodcall obj x y .add list num .field = 123 print_number .field Tricky parts, maybe also for a human reader: # This one is simple a <- f x # in this one, x is a value a <- [x y] # but is a function call again: a <- (f x) Syntax test. Maybe the parameters should be explicit? name = memzdup --str li.string --len li.len name = memzdup --str li.* --len li.* name = memzdup --str li... --len li... name = memzdup