See the following picture (worth a thousand words):

Code:
local First = first()
if (!First)
{
print("First: " + First)
# It is not first run. myFunc "should have a go"..?
myFunc() # Syntax highlighting works. But, validation still says "No such function".
}
else
{
print("First: " + First)
# !(!first()) == first()
# It is first run.
function myFunc() { }
}
I know a possible workaround is to make call myFunc using quotes, like so:
"myFunc"()
Inline edit: I was wrong about UDFs on types. Skip the rest of my comment here. Thanks @bigdogmat.
But, this is doesn't work on user-defined functions (UDF) on types (afaik), for example:

Now that dropped syntax highlighting, and also this workaround doesn't work on UDF on types (on picture's scenario "entity", the function entity:myFunc(void), but I mean it is regardless of type, so this applies to any UDF on any type [angle, array, bone, complex, effect, entity, gtable, matrix, matrix2, matrix4, quaternion, ranger, string, table, vector, vector2, vector4, wirelink] but number/normal of course can't define UDF on that type).
Code:
local First = first()
if (!First)
{
print("First: " + First)
"myFunc"() # Syntax highlighting no longer works. Validation successful.
# It is not first run. entity:myFunc "should have a go"..?
entity():myFunc() # ... syntax highlighting works ... No such function.
}
else
{
print("First: " + First)
# !(!first()) == first()
# It is first run.
function myFunc() { }
function entity:myFunc() { }
}
@bigdogmat
Also you really shouldn't be creating UDFs outside of if(first()) as that's when the editor expects them to be.
(I know that.)
It is defined in the code-block that is run first. Don't you understand code logic?
Edit:
@bigdogmat Why have you deleted your comment..?
I thought you were talking about a completely different issue, as for why I removed my comment. And this issues stems from the fact that the validator wants UDFs to be created before called.
When I say that I mean created line wise before called.
Also you can still do it with callable strings,
function number entity:test(T:string) {return T:toNumber()}
print("test"(owner(), "1")[number])
@bigdogmat
Also you can still do it with callable strings,
function number entity:test(T:string) {return T:toNumber()} print("test"(owner(), "1")[number])
Oh right, there is a workaround for UDFs on types! Ah, but it is still an issue..
Thanks for reminding me.
To give a little insight on how it works, or at least how I remember it working.
The validator goes through the script and checks to make sure everything is valid, when it comes to a UDF definition it adds it to a lookup so when it comes to a function call it can check against it. The issue comes into play when the definition comes after the call.
The only fix I can think of for this would be to go through the script once and take all function errors and compare them against the list of defined functions.
Edit: The big issue here is that the validator kind of treats functions like variables, even though functions are global when declared no matter what. _Sadly_ the validator isn't smart enough to know when something should exist.
Because the syntax highlighter is much dumber than the compiler. Would be a
pain to fix.
On Tue, Apr 5, 2016 at 3:25 AM, CaptainPRICE [email protected]
wrote:
See the following picture (worth a thousand words):
[image: No such function]
https://camo.githubusercontent.com/4ac49b5cf2292b1477d895bed77159f7077c11b8/68747470733a2f2f692e696d6775722e636f6d2f4465504c6741312e706e67—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/wiremod/wire/issues/1117
Yeah, verifying whether E2 functions exist at a particular point in the code is equivalent to solving the halting problem. The entire function system's a mess, they should be statically defined and you shouldn't have to fuck around with the if (first()) shit that goes on.
Verification could mark a function as existing if a definition of it exists anywhere in the file. That would mean we'd correctly succeed on your example, correctly fail when we use a function name that's never defined, and assume the code is correct if it defines it somewhere. That's probably the best we can do for now.
Consider function definition behavior in JavaScript:
foo(); //"bar"
function foo() {
console.log("bar");
}
This is a function declaration.
It will work regardless of the position in body:
foo(); //"bar"
if(false) {
function foo() {
console.log("bar");
}
}
However, ECMA strict typing discourages use of function declaration and instead prefers function definitions:
foo(); //"bar"
if(false) {
foo = function() {
console.log("bar");
}
}
This works due to hoisting. It's complicated.
However this definitely doesn't:
foo(); //Uncaught TypeError: foo is not a function
if(false) {
var foo = function() {
console.log("bar");
}
}
The point is that UDFs should be differentiated between those that are only defined when they pass a point in the code (as if they were variables) or are automatically defined at runtime regardless of where they are.
@oldmud0 E2 doesn't have function variables (which is the reason we have
callable strings at all), so doing that seems pretty pointless. But idk I'm
no expert on syntax design
On Tue, Apr 5, 2016 at 3:24 PM, oldmud0 [email protected] wrote:
Function definition is similar to the behavior in JavaScript:
foo(); //"bar"
function foo() {
console.log("bar");
}This is a function declaration.
It will work regardless of the position in body:
foo(); //"bar"
if(false) {
function foo() {
console.log("bar");
}
}However, ECMA strict typing discourages use of function declaration and
instead prefers function definitions:foo(); //"bar"
if(false) {
foo = function() {
console.log("bar");
}
}This works due to hoisting. It's complicated.
However this definitely doesn't:
foo(); //Uncaught TypeError: foo is not a function
if(false) {
var foo = function() {
console.log("bar");
}
}The point is that UDFs should be differentiated between those that are
only defined when they pass a point in the code (as if they were variables)
or are automatically defined at runtime regardless of where they are.—
You are receiving this because you commented.
Reply to this email directly or view it on GitHub
https://github.com/wiremod/wire/issues/1117#issuecomment-205803184
That's really weird, callable strings.
So could you do
function asdf() {print("foo")}
function ghjk() {print("bar")}
local Foo = "asdf"
Foo() #"foo"
Foo = "ghjk"
Foo() #"bar"
?
@oldmud0 Yeah
Wow that's almost as bad as eval.
~snip/ignore this~
Hidden promotion