Something like the following:
// Usage
ProcInfo(Object, ProcName)
ProcInfo(ProcRef)
// Example
/datum/proc/ExampleProc(atom/foo=1, obj/bar=2)
set waitfor = FALSE
[...]
/datum/proc/GetProcArgs()
return ProcInfo(src, "ExampleProc")
/datum/proc/AltGetProcArgs()
return ProcInfo(.proc/ExampleProc)
As for what it returns, the minimum would be the argument names and their types, which could fit within a keyed list. However, ideally it would be good if this could return default argument values and anything that has been set, like set waitfor and such. To get full information out like that you probably need to implement a new type entirely to hold all the info.
// The returned object for the previous example
/datum/procinfo
var/list/arg_types = list("foo"=/atom, "bar"=/obj)
var/list/arg_defaults = list("foo"=1, "bar"=2)
var/list/settings = list("waitfor"=FALSE)
Alternatively multiple procs could be used for this.
ProcArgTypes(src, "ExampleProc")
ProcArgDefaults(src, "ExampleProc")
ProcSettings(src, "ExampleProc")
This ties prety closely with previous requests to make it so you could use initial(thing.args) to be able to get all arg names on uninstanced types and initial(thing.parent_type) which when all combined would allow variable debug tools to display vars grouped by the type they're defined on and could also allow us to do the same for all procs on the object being debugged. The feature in this post alone though would allow for some nice improvements regardless.
This would allow us to store and retrieve custom metadata about procs for testing purposes, or some kinds of generic systems. Perhaps define new settings like:
/proc/setting/nonstandard_setting = FALSE