[Question]
  [
**Closed**. This question needs to be more [focused](/help/closed-questions). It is not currently accepting answers.
 
 
---
**Want to improve this question?** Update the question so it focuses on one problem only by [editing this post](/posts/126326/edit).
Closed 6 years ago.
[Improve this question](/posts/126326/edit) 
Write a function (not a full program), so that if the function is called with a single global variable (or your language's closest equivalent) as its argument, it outputs (i.e. prints or returns) the name of that variable. If the argument is not a variable, output a falsey value instead. (You don't have to handle the case where the argument is a variable, but not global.)
There must not be a compile-time connection between the function call and function definition (notably, the function definition cannot be a macro or similar construct that receives arguments in the form of a literal fragment of source code, neither in text nor abstract syntax tree form). That is: in languages which support separate compilation, the program must work even if the function call is compiled first (with no knowledge of the function definition but possibly a type signature or equivalent), then the function definition is compiled afterwards. If the language doesn't have separate compilation, you must nonetheless aim for a similar separation between the call and definition.
If using a compiled language, you may read the compiled form of the complete program from disk, and may assume that the program was compiled with debug information. (Thus, solutions that work by attaching a debugger from a program to itself are allowed.)
Note that this task may not be possible in every language.
## Examples:
```
var apple = "Hello"
p(apple) // apple
var nil = "Nothing"
p(nil) // nil
var SOMETHING = 69
p(SOMETHING) // SOMETHING
function foo(){}
p(foo) // foo
p(3.14159) // false
p(function foo(){}) // false
```
  
[Answer]
# Java
```
String getParamName(String param) throws Exception {
    StackTraceElement[] strace = new Exception().getStackTrace();
    String methodName = strace[0].getMethodName();
    int lineNum = strace[1].getLineNumber();
    String className = strace[1].getClassName().replaceAll(".{5}$", "");
    String classPath = Class.forName(className).getProtectionDomain().getCodeSource().getLocation().getPath() + className + ".class";
    StringWriter javapOut = new StringWriter();
    com.sun.tools.javap.Main.run(new String[] {"-l", "-c", classPath}, new PrintWriter(javapOut));
    List<String> javapLines = Arrays.asList(javapOut.toString().split("\\r?\\n"));
    int byteCodeStart = -1;
    Map<Integer, Integer> byteCodePointerToJavaPLine = new HashMap<Integer, Integer>();
    Pattern byteCodeIndexPattern = Pattern.compile("^\\s*(\\d+): ");
    for (int n = 0;n < javapLines.size();n++) {
        String javapLine = javapLines.get(n);
        if (byteCodeStart > -1 && (javapLine == null || "".equals(javapLine))) {
            break;
        }
        Matcher byteCodeIndexMatcher = byteCodeIndexPattern.matcher(javapLine);
        if (byteCodeIndexMatcher.find()) {
            byteCodePointerToJavaPLine.put(Integer.parseInt(byteCodeIndexMatcher.group(1)), n);
        } else if (javapLine.contains("line " + lineNum + ":")) {
            byteCodeStart = Integer.parseInt(javapLine.substring(javapLine.indexOf(": ") + 2));
        }
    }
    int varLoadIndex = -1;
    int varTableIndex = -1;
    for (int i = byteCodePointerToJavaPLine.get(byteCodeStart) + 1;i < javapLines.size();i++) {
        if (varLoadIndex < 0 && javapLines.get(i).contains("Method " + methodName + ":")) {
            varLoadIndex = i;
            continue;
        }
        if (varLoadIndex > -1 && javapLines.get(i).contains("LocalVariableTable:")) {
            varTableIndex = i;
            break;
        }
    }
    String loadLine = javapLines.get(varLoadIndex - 1).trim();
    int varNumber;
    try {
        varNumber = Integer.parseInt(loadLine.substring(loadLine.indexOf("aload") + 6).trim());
    } catch (NumberFormatException e) {
        return null;
    }
    int j = varTableIndex + 2;
    while(!"".equals(javapLines.get(j))) {
        Matcher varName = Pattern.compile("\\s*" + varNumber + "\\s*([a-zA-Z_][a-zA-Z0-9_]*)").matcher(javapLines.get(j));  
        if (varName.find()) {
            return varName.group(1);
        }
        j++;
    }
    return null;
}
```
This currently works with a few gotchas:
1. If you use an IDE to compile this it might not work unless it is run as Admin (depending on where the temporary class files are saved)
2. You must compile using `javac` with the `-g` flag. This generates all debugging information including local variable names in the compiled class file.
3. This uses an internal Java API `com.sun.tools.javap` which parses the bytecode of a classfile and produces a human readable result. This API is only accessible in the JDK libraries so you must either use the JDK java runtime or add tools.jar to your classpath.
This should now work even if the method is called multiple times in the program. Unfortunately it does not yet work if you have multiple invocations on a single line. (For one that does, see below)
[Try it online!](https://tio.run/##nVdrb9s2FP1s/wpOGAqqjhi76IYtTjIEnYd1SFsDCTZgcVbQMmPToUSNpPJo6r9e75LU01aHbECQ2Pd9zz28ZNb0jkYyY@l6cbvd8iSTyqA1CAmXZKp4av5Q3DA17u/oLgwol13K3HBBzpSij7pD8SvVq3c069Ccc206xN3Gii3ZA@hMvOrM7/VTaqC8dNzvx4JqjSboqd/L8rngMdKGGvhzJ/kCJZSn2Hd0dY2oWurQWvYmiKETlLJ7NMHhGATeBnwVyAPD9GXQFr/6ivx1S27Uo4vfu3jUhiVE5oZkFmyRYkaWzEyposl7mjAMvqFL/TzbV//F@HVhzMjcf32mKyMxDr3vBsV2BnjyELPMcJkiNvLY9djI@18YGt9eKhozj@Gmb3/6JTityIUss4IQmZWS9zC1KvaTw7QMNxEsYamBiUHx8L0cVWmOQ1v2bvoiRcLMSi5sUnDz/lfDa@vwrtJ4B2gBCZ6y93lSm46c6bkXz5nypnV4x7d2dO/yplRAdYplAjRnQuCAPH23@TY4QEHQrNKFARavIIzzJDdSOe8qgWtyqqRhsW36Z@nI7KRv5IJdyFzZ1l25EoZVAWPD4hANGrUOUEDct6DVjT/l7nRlH3JT4NzU@fZjmRCdp8RIKTRx5nBEeUpUnuLaBQb2FETCNhvF8LtqcnPgAjfWDi5zerbZFXHsg5z6cuwENBTk9w2h2ppUXlCJt4aOdSa4wcFspn6azdIgrGY7fzTMIWWosr1FI6uBtXP8NjWwRtQBKj6cVrZTCZ5MXcrfINPUFlGAUqy3fVePULGQqjhv0wV7KIUnqPhEAMiMC4aDv2Yz/RLPZotBeIQ8M4AACNu6rcNwnKLjBhJE80@WtulgUJzCgkiVCTg1zIEGOPXHnt8g3IbiFKBAL14g3HCGLnMh0OfPQFTC/s6p0LUadoJP2psrRm9d2I39Vezpdtul8KQTDZJ4dSP6XpnNMOSGpwtcF/DVQZEsN7iYCoFFoyGM6Q65VDLP8CgMgZc@@wYxoRmyRVR1wbRSAyzXOLBrAgVwjMp9AQfqKNgrqmTaXhV1TJ3PtWduLeO2tg83OLBUgNDlrt@4pVqw@Y6qc0kXro@KzIXiks4Fa2sqNvHGHDpAs0RplW8LGI15J/t4xT4LVKuiYzS0lNqhIA8bIPr962BsLOk2kjtdcodDz8bgac5q4nXWUPL634qwq1L8ThW3kDnc2tlbUBbp26TftO4DAdm7j1@rtAiNQgIeSX31gN5fMa2HQyXtolGZrMGiSlSRiFqR49H3ZcrmjY6wj/@LVHASG9d7AYJiJoedZbdBcam7atdQTxse4Kk1uF/ZhfZNx9bwMKyr5VHuBduiv0D31qLdipYfNQpAD7cqr2j06Sz68@N18WEY/fjx@mUYhPv7pMo7btLEptzZJUWrpbLcCjXL1oNBiUEbFvfOcS/M@bOeNvsvr9bryPuG4/YDCt5izrtIbV@ZJnA2m@32S3wj6FJvo@U2irMtOTrMtToUfH64vksOLRbRiPxAhuX/AE5V3t/qi3TF6f/j@w8 "Java (OpenJDK 8) – Try It Online")
---
### Explanation
```
StackTraceElement[] strace = new Exception().getStackTrace();
String methodName = strace[0].getMethodName();
int lineNum = strace[1].getLineNumber();
String className = strace[1].getClassName().replaceAll(".{5}$", "");
String classPath = Class.forName(className).getProtectionDomain().getCodeSource().getLocation().getPath() + className + ".class";
```
This first part gets some general information about what class we're in and what the name of the function is. This is accomplished by creating an exception and parsing the first 2 entries of the stack trace. 
```
java.lang.Exception
    at E.getParamName(E.java:28)
    at E.main(E.java:17)
```
The first entry is the line that the exception is thrown on which we can grab the methodName from and the second entry is where the function was called from.
```
StringWriter javapOut = new StringWriter();
com.sun.tools.javap.Main.run(new String[] {"-l", "-c", classPath}, new PrintWriter(javapOut));
```
In this line we are executing the javap executable that comes with the JDK. This program parses the class file (bytecode) and presents a human-readable result. We'll use this for rudimentary "parsing".
```
List<String> javapLines = Arrays.asList(javapOut.toString().split("\\r?\\n"));
int byteCodeStart = -1;
Map<Integer, Integer> byteCodePointerToJavaPLine = new HashMap<Integer, Integer>();
Pattern byteCodeIndexPattern = Pattern.compile("^\\s*(\\d+): ");
for (int n = 0;n < javapLines.size();n++) {
    String javapLine = javapLines.get(n);
    if (byteCodeStart > -1 && (javapLine == null || "".equals(javapLine))) {
        break;
    }
    Matcher byteCodeIndexMatcher = byteCodeIndexPattern.matcher(javapLine);
    if (byteCodeIndexMatcher.find()) {
        byteCodePointerToJavaPLine.put(Integer.parseInt(byteCodeIndexMatcher.group(1)), n);
    } else if (javapLine.contains("line " + lineNum + ":")) {
        byteCodeStart = Integer.parseInt(javapLine.substring(javapLine.indexOf(": ") + 2));
    }
}
```
We're doing a couple different things here. First, we are reading the javap output line by line into a list. Second we are creating a map of bytecode line indexes to javap line indexes. This helps us later to determine which method invocation we want to analyze. Finally we are using the known line number from the stack trace to determine which bytecode line index we want to be looking at.
```
int varLoadIndex = -1;
int varTableIndex = -1;
for (int i = byteCodePointerToJavaPLine.get(byteCodeStart) + 1;i < javapLines.size();i++) {
    if (varLoadIndex < 0 && javapLines.get(i).contains("Method " + methodName + ":")) {
        varLoadIndex = i;
        continue;
    }
    if (varLoadIndex > -1 && javapLines.get(i).contains("LocalVariableTable:")) {
        varTableIndex = i;
        break;
    }
}
```
Here we are iterating over the javap lines one more time in order to find the spot where our method is being invoked and where the Local Variable Table starts. We need the line where the method is invoked because the line before it contains the call to load the variable and identifies which variable (by index) to load. The Local Variable Table helps us actually look up the name of the variable based on the index we grabbed.
```
String loadLine = javapLines.get(varLoadIndex - 1).trim();
int varNumber;
try {
    varNumber = Integer.parseInt(loadLine.substring(loadLine.indexOf("aload") + 6).trim());
} catch (NumberFormatException e) {
    return null;
}
```
This part is actually parsing the load call to get the variable index. This can throw an exception if the function isn't actually called with a variable so we can return null here.
```
int j = varTableIndex + 2;
while(!"".equals(javapLines.get(j))) {
    Matcher varName = Pattern.compile("\\s*" + varNumber + "\\s*([a-zA-Z_][a-zA-Z0-9_]*)").matcher(javapLines.get(j));  
    if (varName.find()) {
        return varName.group(1);
    }
    j++;
}
return null;
```
Finally we parse out the name of the variable from the line in the Local Variable Table. Return null if it isn't found although I've seen no reason why this should happen.
### Putting it all together
```
 public static void main(java.lang.String[]);
    Code:
...
      18: getstatic     #19                 // Field java/lang/System.out:Ljava/io/PrintStream;
      21: aload_1
      22: aload_2
      23: invokevirtual #25                 // Method getParamName:(Ljava/lang/String;)Ljava/lang/String;
...
    LineNumberTable:
...
      line 17: 18
      line 18: 29
      line 19: 40
...
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0      83     0  args   [Ljava/lang/String;
          8      75     1     e   LE;
         11      72     2   str   Ljava/lang/String;
         14      69     3  str2   Ljava/lang/String;
         18      65     4  str4   Ljava/lang/String;
         77       5     5    e1   Ljava/lang/Exception;
```
This is basically what we're looking at. In the example code the first invocation is line 17. line 17 in the LineNumberTable shows that the beginning of that line is bytecode line index 18. That is the `System.out` load. Then we have `aload_2` right before the method call so we look for the variable in slot 2 of the LocalVariableTable which is `str` in this case.
---
For fun, here's one which handles multiple function calls on the same line. This causes the function to not be idempotent but that's kind of the point. [Try it online!](https://tio.run/##nVhbb9s2FH7Pr@CEoZDqmImLbtjiJEOQtViHtDGQIAMWZwUtMzYd3UZSuTT1X693DnUxJdFGOj2oMc/9OzeqC3bP@mnGk8X0brUScZZKTRZwSEVKR1Ik@i8pNJfDnRbtQgNx5iLmWkT0REr2pByEP5iaf2SZg3ImlHYcu5kln/FHoOlw7rRf0EdMg3vJcGcnjJhS5Io87xB4snwSiZAozTT8c5@KKYmZSPwiqOsbwuRMBSUzPleEkyOS8Ady5QfD@rjgBz0SqJ7m6tJzEd9spb51ULV8sqwb/ieleUzTXNMM0xIlPqczrkdMsvgTi7kPqoJg@CK@N4EVxIu1v21LcTopzr9XGaehH9jaliTEVPrvHkOeaZEmhA@CFgJ8UKi70Cy8u5Qs5HYqljvrt3mVyYXyOSyw3iUfEg1lIY9JJBJ@yqJIlUkti7LDWBkok9WIoTzL8CAgei7TB0XW/j9bma78fRfxmCca6gtQg9@l9VrIDxAmd3yluZjreTpFB0C40HK9f4NiH2uKLQZ4mWg/5fFaYGAEzorjCZe2QNugaZymvUL8tCKA15JnEVBOosj36PNPyx@9XeJ5Xe@NMmjKOSgz8vQ2lUZHbcZAMJKp5iFC8ntqGtOcnqZTfpHmEoExAaRQNDVsqNYPSM/yuEc8an55bk8QAfCkIXDgwbtEzIFKWRkkzOWZVUR1QaEnfq3cTsQt8ZtCkPw8itpVvtaU5ZamXTJotAuPFH@pZMNsr6loU96LwW4Ganae67JSbZpdNGEaU5UnVKcpmDdCMJtFQmWe@GvB65tnrx9hbfRDeNfVsNw12q1141eG7SGBC6Js0ePCMwwL4S@2DWUKWWpZcKfghgJRWSS0743H8rfxOPGCVotMnjQ35aWZxGD7gzUdB0OZdmuEVBKjFOS5vEz/BKujsqLsmdIRtYErF1St7UMy5Y/V4VFFpoBvJiLue/@Mx@q1Px5Pe8EBsRsM@oj4GAmK7Q8TcmghRJX4glMh6fXa5Va2Q80L0pYcFnPSmu5YyE24jgEu8uoV8S0tRXGTr19hDlD@b84itSbD6G@5gc9EcnbXtLVs/Cq3fROs6vDIiSGNC7Jle3M0tj56K5Kp7/ZzY@ZN45VpprAYFKjUbvUzmeaZPwgCKP2WS2Vzo2e111ABiYaGUr6HbU6sIVUMra2eVlXdcW2tX@UTVfTK@kygw@e3voelBmY6t4alNUca7XTP5FnKpibiVjeV5Es2ifgmeoiT6jy5nItqRO87Kl1YOXfkAmu3AQCGMBgKZ2eIbmcg/o04Dsk@VnmrPURg5abYwSY71qLenCC00eu1wz3evE9cSvBpAS6GHa5l5wTdFknOt7XcdkSqxt8GCS7p6IpJgQk3Wd@ARbsoHDFsnRAbVxmJwGH3bGtE04fNSEEibt@fgKu4J227n9dMrj6rPLDarD6qu4zhkWm0nys/ujdk4hdW3qcSRpt1XW5DKrnOYYfgFHate4xrAa42UYceXzM/zHHl/OCY3wV4i@4Yr4YxglFcGTsbDBcY9scaL2gPs9WuWf/LSf/vzzflH/v9Xz/fvA68oDvEaweG7hJF41smeIlNxVjN4m2NsOj1XDB2ULY@QMxn5eQ7vhO6n02ND45CQ9CxU91ofTvU0jH8rtReJbJcrb6FtxGbqVV/tuqH2Yoe7OVK7kVisre4j/cQ4P6A/kL3q/8TMKTqWie/pcZp9X9k/wM "Java (OpenJDK 8) – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/)
This is about the most dirty code I've written but it works. ¯\\_(ツ)\_/¯ Throws an error on a non-existent variable as Python will immediately dislike you for calling the function with one. Also throws an error on non-variables but this can be fixed with a try/except if needed.
```
import inspect
import re
def name_of(var):
    for i in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
        return re.search(r'\bname_of\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', i).groups()[0]
```
[Try it online!](https://tio.run/##XU9Nb8IwDL3nV2SnxohWiO2ySTvsxj9AWltVoTg0WutETjoBf76ko@yAD/5479nW85fYOdpOkx284ygtBY9tFMvIKMQRjSQ9YOOM@tUMH0KmMI6lTfLHRnHCaDjJLBmnHmA7MiPdCQWFaQ66/YHytb4fmYMxjkypFAE1t53irDos/6qwqlRKqvzKv3V@beql2eTvTb2CmYdsLS0UJ3ajDwrKTT112PdOfspsNzdruXfcH18yEbweEvy2FcKzpfhv628BnsBZ/YyRIzzbEJMnmG4 "Python 2 – Try It Online")
If we're allowed to take the argument as a string, this satisfies the requirements of outputting a falsy value on an invalid input.
```
import inspect
import re
def name_of(var):
    # return var :P
    try:
        eval(var)
    except NameError:
        return False
    for i in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
        try:
            return re.search(r'\bname_of\s*\(\s*[\'"]([A-Za-z_][A-Za-z0-9_]*)[\'"]\s*\)', i).groups()[0]
        except AttributeError:
            return False
```
[Try it online!](https://tio.run/##ZVBNb8IwDL3nV2S7JEG04msHJu3AYdNOu05aW1WhuDRam0ROimB/vksLDAY@RPZ7fnae7cFXRs@6TjXWoKdKOwuFJ6cSgZANlFTLBnJT8p1E8UxoCI@HY9IH7GQ9cAMC@wKspx9B84po8NKH4FvU9E3WLgzukdIgVWHreXG8BV9iUCpdGn4GixYR9JHgIi7ztSy@RTLPLqP//edqF0LsQGJRcWTp@uQjdaOUhydJ2WPGk1X0JaOfPDslk2iZZyMxkH2nYGOqRLxF01rHRTLJLsaPVlfeo1q3/tbvreeugro29IWy9z4Z00@D9eaBEWdlE@DFjBCLSvu/g7NBwcQt3Avu0Xk8XUyflveENhr2yvlwRCa6Xw "Python 2 – Try It Online")
[Answer]
## Mathematica
```
f[x_] := ValueQ @ x && ToString @ HoldForm @ x
SetAttributes[f, HoldFirst]
```
The `HoldFirst` attribute prevents `f` from evaluating its argument before invoking the function. `ValueQ @ x` then checks whether the given argument is a variable that has been given a value. If not we just return `False` due to short-circuiting. Otherwise, we obtain the variable name with `ToString @ HoldForm @ x`.
[Answer]
# Mathematica
```
f~SetAttributes~HoldAll;
f[_] = False;
f[x_Symbol?ValueQ] := SymbolName@Unevaluated@x;
```
Mathematica likes to evaluate **everything**, so to make it stop, we have to fight against it. In its own language.
## How?
```
f~SetAttributes~HoldAll;
```
Tells Mathematica that whenever function `f` is called, its arguments shouldn't be evaluated (i.e. held).
---
```
f[_] = False;
```
When `f` is called with an argument, output `False`. (?!)
---
```
f[x_Symbol?ValueQ] := SymbolName@Unevaluated@x;
```
When `f` is called with a defined Symbol (which has a value), output the symbol name of the input.
The previous line does not take precedence, despite being defined earlier, because this definition is more specific. As the Wolfram Documentation states: Mathematica "tries to put specific definitions before more general definitions."
Mathematica is very stubborn and keeps trying to evaluate variables whenever possible. The extra `Unevaluated` takes care of that.
[Answer]
# C#
```
string n<T>(Expression<Func<T>>m) =>
    (m.Body as MemberExpression)?.Member?.Name ?? null;
```
Full/Formatted version:
```
using System;
using System.Linq.Expressions;
class P
{
    static void Main()
    {
        var apple = "Hello";
        var nil = "Nothing";
        var SOMETHING = 69;
        Console.WriteLine(n(() => apple));
        Console.WriteLine(n(() => nil));
        Console.WriteLine(n(() => SOMETHING));
        Console.WriteLine(n(() => 3.14159));
        Console.ReadLine();
    }
    static string n<T>(Expression<Func<T>>m)
        => (m.Body as MemberExpression)?.Member?.Name ?? null;
}
```
---
Another way to do this is by reflecting on the type like so:
```
public static string GetParameterName<T>(T item)
{
    var properties = typeof(T).GetProperties();
    return properties.Length > 0 ? properties[0].Name : null;
}
```
However, you have to call it like:
```
GetParameterName(new { apple });
```
It then also fails for `3.14159` by returning `Length` and for that you also have to call it like the following instead:
```
GetParameterName(new double[]{ 3.14159 });
```
---
In C# 6.0 we also have:
```
nameof
```
But this won't compile if you pass it something that isn't a variable e.g. `3.14159`. I believe it also evaluates the input at compile time so it seems like it fails that requirement as well.
[Answer]
# MATLAB
```
varname = @(x) inputname(1);
```
Within a function there are a few preset variables like `varargin` or `nargin`, among those we also have `inputname`.
[stolen from here](https://stackoverflow.com/a/11453337/2913106)
[Answer]
## R
```
function(x) if (identical(substitute(x), x)) FALSE else substitute(x)
```
`substitute` returns the parse tree for an unevaluated expression. The `identical` conditional makes sure that this unevaluated expression isn't identical to the expression itself; i.e. that the passed in parameter isn't a literal.
[Answer]
## Python 2
Some research has been done. And it seems to be possible in python, but I still expect some troubles to be found.  
Solution is not perfect, as it assumes some structure of the code. Yet I didn't break it still.
```
import inspect
import re
def get_name(var):
    called = inspect.getouterframes(inspect.currentframe())[1][4][0]
    return re.search('(?<=get_name\().*(?=\))', called).group().lstrip().rstrip()
```
This uses inspect to look at surround scope and find where function `get_name` is called. 
For example `inspect...[1]` will return 
> 
> `(< frame object at 0x01E29030>, 'C:/Users/---/PycharmProjects/CodeGolf/Name_var.py', 14, '< module>', ['print get_name( a )\n'], 0)` 
> 
> 
> 
And `inspect...[1][4]` will show us list with code, where function is called: 
> 
> `['print get_name( a )\n']`
> 
> 
> 
After that I used regex to retrieve name of the argument 
```
re.search('(?<=get_name\().*(?=\))', called).group()
```
And `.lstrip().rstrip()` to remove all whitespaces that may be placed into bracets.
[Example with some tricky input](https://tio.run/##ZY7bCoMwDIbv@xTe2YxR3NjVWPFBVEat8QBaS4yDPb3rRBnMQEjy5c/Bv7kd3XVZusGPxFHnJo@WxVYSClFhHTXIT2cGlC9DcBdRMGv6HqtI7yMqaMaZkWoKwknu2M5E6HilEiC7FNmtyJJiXULIM7kQ1ISGbCtjmT70fi2XoE4y1TlAfN4OgmponH3o9BNT901oSxajE1EGtzorRKWtEJ46x7/vDfyT8kDsgVSwfAA)
[Answer]
## PowerShell
```
function t($t){(variable($MyInvocation.Line.Split(' $'))[-1]-ea si).Name}
$apple = 'hi'
t $apple
apple
t 3.141
```
But it doesn't work reliably, it's rudimentary.
[Answer]
# [PHP](https://php.net/)
Needs that the variable value is unique in the array of the global variables
```
function v($i){echo"$".array_search($i,$GLOBALS);}
```
[Try it online!](https://tio.run/##K8go@G9jXwAk00rzkksy8/MUyjRUMjWrU5Mz8pVUlPQSi4oSK@OLUxOLkjOAEjoq7j7@To4@wZrWtf9VMlJzcvJtTay5gHrAbE3r/1/z8nWTE5MzUgE "PHP – Try It Online")
# [PHP](https://php.net/), 96 bytes
```
function v($i){
echo($i==end($g=$GLOBALS))?"$".key(array_slice($g,-1)):0;
}
$hello=4;
v($hello);
```
[Try it online!](https://tio.run/##K8go@G9jXwAk00rzkksy8/MUyjRUMjWruVKTM/KBLFvb1LwUDZV0WxV3H38nR59gTU17JRUlvezUSo3EoqLEyvjinMzkVKAKHV1DTU0rA2uuWi6VjNScnHxbE2suoGFgtqb1//8A "PHP – Try It Online")
Needs that the variable is initialized directly to the function call.
Checks if the last global variable is equal surrendering variable
[Answer]
# JavaScript (ES6)
For all property names in `window` (`Object.getOwnPropertyNames(w)`), attempt to define a getter for that property that returns the property name.
Then, add an entry to a Map `M` where the key is the (possibly overridden) value of the property, and the value is the name of the property.
The function `f` simply takes a variable (i.e. a property of `window`) and returns the entry in `M` for that value.
```
let
    w = window,
    M = new Map(),
    L = console.log,
    P = Object.getOwnPropertyNames(w),
    D = Object.defineProperty
for(const p of P){
    try {
        D(w, p, {
            get(){
                return p
            }
        })
    } catch(e){ L(e) }
    try {
        M.set(w[p], p)
    } catch(e){ L(e) }
}
let f = v => M.get(v)
```
This works for all built-in global variables except `window` itself, as there is no way to distinguish it from `top` (unless run in a frame):
```
L( P.filter(p => p !== f(w[p])) )
// -> ['window']
```
[Answer]
# Perl 5 + Devel::Caller
```
use 5.010;
use Devel::Caller qw/caller_vars/;
use Scalar::Util qw/refaddr/;
sub v {
   # find all operands used in the call, formatted as variable names
   my @varsused = caller_vars(0,1);
   scalar @varsused == 1 or return; # exactly one operand, or return false
   $varsused[0] =~ s/^\$// or return; # the operand actually is a variable
   # it's possible we were given an expression like "~$test" which has only
   # one operand, but is not a variable in its own right; compare memory
   # addresses to work this out
   refaddr \ ($_[0]) == refaddr \ (${$varsused[0]}) or return;
   return '$' . $varsused[0];
}
# some test code
our $test = 1;
our $test2 = 2;
our $test3 = 3;
say v($test2);
say v(2);
say v(~$test3);
say v($test);
say v($test + 1);
say v(++$test);
say v($test3);
```
We use Devel::Caller (a debugger-like module) to walk the call stack, looking for the call to the function, and return all the operands within the argument, returning them as variable names. If there's more (or less) than one operand, we weren't called with a variable. If the operand wasn't a variable, it won't have a name and we can detect that too.
The trickiest case is if we get a one-operand expression involving a variable, such as `~$x`. We can figure out if this has occurred by taking a reference to the variable directly from the symbol table (using the `${…}` symbolic reference syntax) and comparing its memory address to the value we were passed as an argument (which is, conveniently, passed by reference). If they're different, we have an expression rather than a lone variable.
Note that if we call this function with a preincrement or predecrement expression on a single variable, as in `v(--$x)`, we get `$x` returned. This is because it's actually the variable itself that's being passed to the function in this case; it just gets incremented or decremented beforehand. I hope this doesn't disqualify the answer. (In a way, it makes it better, because it shows that we're checking the argument itself rather than just reading the source code.)
[Answer]
## PHP
While the other PHP submissions only test if the given value matches a value of a global, this version works by taking a reference to the value:
```
// take a reference to the global variable
function f(&$i){
  foreach(array_reverse($GLOBALS) as $key => $value)
    if($key != 'GLOBALS') {
      // Set the value of each global to its name
      $GLOBALS[$key] = $key;
    }
  foreach($GLOBALS as $key => $value)
    if($key != 'GLOBALS' && $key != $value) {
      // The values mismatch so it had a reference to another value
      // we delete it
      unset($GLOBALS[$key]);
      // and update the value to its name again
      $GLOBALS[$key] = $key;
    }
  echo '$', is_array($i) ? 'GLOBALS' : $i, "\n";
}
```
This should now work even if the global variable is a reference to another value at the time of calling.
Test it [here](http://sandbox.onlinephpfunctions.com/code/3b424a6c7bc1229359d37684983bf0e2bdea01cf).
[Answer]
# [Röda](https://github.com/fergusq/roda)
```
f(&a...) {
	a() | name(_) | for str do
		false if [ "<" in str ] else [str]
	done
}
```
[Try it online!](https://tio.run/##TY6xCsIwFEXn5CseGaRZAqIIio5iHayDbkUk0EQDaV5Ju9V@e00yGLd77zk8nsdGzrMuFlIIwWGkRBYcPuBkq4pnTBo99IOHBikhWtpegdFQA9szMC6hB6g41yE/KGnQKTrNrQw03us6q2B3AFYqa5FR0nnjBtBFIpwSSpyxyahweBv3@nMCScbtejney3N1it5mm4UfSJpGjMI4ZSFMnOa6Ess1z3WcePj1Cw "Röda – Try It Online")
Röda has a builtin function for this – `name`. Unfortunately, though, it doesn't return a falsy value when not given a variable.
This code abuses several features of reference semantics. Explanation line by line:
`f(&a...) {`
The function takes a variable number of reference arguments (`&a...`). This is the only way in Röda to create a list of references.
`a() | name(_) | for str do`
At the second line the elements of `a` are pushed to the stream (`a()`). These elements are references if the function was given variables and normal values otherwise.
The elements are iterated using an underscore loop. The underscore syntax is syntax sugar for `for` loops, so `name(_)` is equivalent to `name(var) for var`. The name of the variable used in the `for` loop is of form `<sfvN>` where N varies. (Ie. "`name(<sfv1>) for <sfv1>`") It is illegal for a user-defined variable to contain `<` or `>`, so the generated names don't collide with existing variable names.
The `name()` function returns the name of the given variable. If the element in `a` being iterated is a reference, then it is the variable given to `name`. Otherwise, if the element was a normal value, the variable given to `name` is the underscore variable `<sfvN>`. This is due to the semantics of references in Röda: if a function accepts a reference and the function is passed a reference variable, the passed value does not point to the reference variable but to the variable the reference variable points to.
`false if [ "<" in str ] else [str]`
At the third line we examine if the variable name in the stream contains a `<` character. If so, it is an underscore variable and the value passed to `f` was not a reference. Otherwise we output the name of the reference.
This solution does not work if the variable given to the function is a reference or an underscore variable. However, the question specifies that only global variables must be handled, and they can't be references or underscore variables in Röda.
[Answer]
# [Ruby](https://www.ruby-lang.org/), 46 bytes
Feels like the dirtiest code I've ever written for Ruby.
Requires that the global variables you call has a unique value that isn't on any other global variable, because the only way to do this challenge in Ruby is to do an search on all global variables and return the first match. OP says it's ok, and is free to judge if my solution is valid.
Note that global variables start with `$` in Ruby, for if you want to add extra test case stuff.
```
->v{global_variables.find{|n|eval(n.to_s)==v}}
```
[Try it online!](https://tio.run/##TY7NCsIwEITveYpQctCDhVqrWIh3D4IPIJTUbjSwbkv6h7R99hqtYg/L7nw7DGPr9DkKLS/j6tB0N8xThUmjrFEpQulrQ1nXUw@NwgX5VZ6USymbYRjFHRBzLrk3HW1uMfOYoPqRgnU8WIebaLtjojBOnVR1j@PzkbEMNCdok8IaqrjLrYFxUg9wLqH9q0L8UaO/D8nJIOO8mDZgCW9VV@XH4Ahl7D3snzwVnIOp2pwUZq70TIR@sAmi/fgC "Ruby – Try It Online")
[Answer]
# PHP
```
function f($v){foreach($GLOBALS as$n=>$x)$x!=$v?:die($n);}
```
if value is found, print variable name and exit. print nothing and don´t exit else.
**61 bytes** to return variable name or `NULL`:
```
function f($v){foreach($GLOBALS as$n=>$x)if($x==$v)return$n;}
```
It will not find named functions, only those assigned to variables.  
And a PHP function cannot detect wether a parameter was provided by reference or by value. The function will just return the first name where the value matches the function parameter value.
[Test it online](http://sandbox.onlinephpfunctions.com/code/e3b9cd0b166614552f0d7b9a9b7623be4c3d597a)
[Answer]
## PowerShell
New version but works starting from PowerShell 3.0
```
function p{[scriptblock]::create($myinvocation.line).ast.findall({$args[0]-is[Management.Automation.Language.VariableExpressionAst]},0)[0]|% v*h|% u*|%{($_,!1)[!$_]}}
```
[Try It Online!](https://tio.run/##PY9RS8MwFIXf@ys6yGg7Zmh1Ig76sIehgpsPE19KGbc1bYNpEpJ0Kll@e00Z7uVc@M45l3ul@CZKd4SxcWwGXhsqeChtoWtFpamYqL/K9bpWBAyJUf9L@UnUMKUwo5wkGLTBDeWfwFhsEahWF2l5Q3WxAw4t6Qk3eDMY0V9Kr8DbwXP8AYpCxcj2Ryqitfc22pRumSa@f56Hp0XndVic5zZGx@UsS4oZOpbOjTJAICUjeTSdLaJAhhcQIE5ZHu2F6ShvPY8nkATo8Lbbvj@/7J/y1W32kE7GFSXB9e1GCOv8Nj@93uFsld0/@rB1yUT/YxUo68Y/)
**Previous version**
```
function p{$t=[management.automation.psparser]::tokenize($myinvocation.line,[ref]@())|? type -match '^[cv]'|? start|% content;($t,!1)[!$t]}
```
[Try It Online!](https://tio.run/##PY9RS8MwEMff@ykyiKSBWaxOZBtFX0R9cD7Mt1IhhOsaTC8hvU1m189eUwd7@h@/3x13590PhK4Ba8ex3qMm45D5nlNRtgrVDlpAytSeXKsml/nOq9BBqFYrct@A5hdS3h4NHpw@d1iDMC8D1NVTKuXpkdHRA7uO87ph4qvUh0pE2pEKdLpi2iHFHeuU03yWy3LGqRpGrry3UIjpMicSn56BTDgaW4iNo8bg7l9EEPH24/358/Vt81IsbvOHm0lckEwur9XO9UOUMWWMuyxf5PfLqewHOf4B)
[Answer]
# tcl
```
proc p a {puts [subst $a]}
```
## [demo](http://rextester.com/ZOEWO55299)
[Answer]
# JavaScript (ES6)
Requires that the value of the variable passed to the function is unique to that variable. Returns `undefined` if a variable wasn't passed.
```
arg=>{
    for(key in this)
        if(this[key]===arg)
            return key
}
```
---
## Try it
For some reason, it throws a cross-origin error in a Snippet when a "literal" is passed.
```
var fn=
    arg=>{
        for(key in this)
            if(this[key]===arg)
                return key
    },
str="string",
int=8,
arr=[1,2,3],
obj={a:1}
console.log(fn(fn))
console.log(fn(str))
console.log(fn(int))
console.log(fn(arr))
console.log(fn(obj))
```
---
## Explanation
Loop through all the entries in the global object (`this`), checking if the value of each one is strictly equal to the value of the argument passed to the function. If a matching entry is found then its key (name) is returned, exiting the function.
---
]