Open weswigham opened 10 years ago
Namely, a function should be aware of its context and be able to modify it.
Is it really a good idea to have mutable functions?
Firstly, a function should have a method by which it can call itself, anonymous fn or otherwise. (it's certainly more clear if the method is the same)
This I'm inclined to agree with. Though, arguably named functions are to be referenced by name / label. It would be very useful to either have a generic variable which is automatically populated with a reference to the closest closing function or some syntax to assign a local name as in clojure which handles this with an optional name argument in the anonymous function definition which is populated into the scope of the function, not above it.
(fn name? [params* ] exprs*)
(fn name? ([params* ] exprs*)+)
Secondly, a function should probably have access to it's :before's and :after's; ie: ... This is to simply allow for dynamically adding and removing before and after hooks.
This carries the same reservation as above. Why would we want mutability in our functions. Especially in the wrapping methods as they are generally used (in my understanding) to implement "mandatory functionality"
It would also be useful to have a function's type signature available to the function, and maybe even a copy of the arguments it was passed.
How is this beneficial? The types are essentially irrelevant at run-time as the compiler gurantees correctness.
It would also be nice to extend the syntax (^^^^^'s!) to let a function get these same attributes of its caller (and therefore its caller's caller, and its caller's caller's caller, etc...)
What is the use case for manually unrolling the stack? What benefit is there? You have access to values which are properly scoped.
What is the use case for manually unrolling the stack? What benefit is there? You have access to values which are properly scoped.
The first and foremost benefit is being able to pass your parent anonymous function as a callback, situations arise where it would be convenient to do this in JS all that time. For example:
function () { //Outer anonymous function
$.ajax("http://api.example.com?data=junk", {
statusCode: {
502: function() { //Then try again...
//I want to call the outer anonymous function, what do I do?
//I could name it, but I don't think I should have to... what if the outer function is a callback itself?
}
}
})
}
How is this beneficial? The types are essentially irrelevant at run-time as the compiler gurantees correctness.
Not usually at all to the function the signature belongs to; however, if I have a construct like
HashMap<Hashable, Func<Object>>
, it could certainly be reasonable for me to want be able to check the type of the function result and alter my execution based on it.
This carries the same reservation as above. Why would we want mutability in our functions. Especially in the wrapping methods as they are generally used (in my understanding) to implement "mandatory functionality"
Before/after hooks can be so much more than just "mandatory functionality". Let's suppose that I have an event driven library; I export functions named message_send
and message_receive
. Any other library in the application or top-level code may end up calling these functions. Let's now suppose that I'm adding a UI to my application here, and I want to make a sound on each message we receive. Since the syntax is available to do so, it would be convenient for me to simply go
fn message_receive:after
do_sound()
Now suppose that my message_receive
library function gets a "bad" message, something that it wants to discard and pretend like it never happened; is there a way for it to stop the execution of its after-hooked functions? Is there a way to temporarily 'mute' the hooks? The mutable list isn't the only solution for sure, it just made sense from my dynamic programming background.
This I'm inclined to agree with. Though, arguably named functions are to be referenced by name / label. It would be very useful to either have a generic variable which is automatically populated with a reference to the closest closing function or some syntax to assign a local name as in clojure which handles this with an optional name argument in the anonymous function definition which is populated into the scope of the function, not above it.
I've considered this quite a bit... it would certainly be useful to have it be a language keyword that references the current function, it would probably more clear than introducing a sigil that does it, too. The reason I was clinging to the '^' was because then you could chain '^''s as a cool way to reference parent closures, BUT it would probably be more clear if it was instead something like keyword.parent.parent.parent ...
. The sigil is more concise, while a keyword is more clear.
That would bring us to the discussion of what the keyword could be... I'll immediately toss out this
and self
, since those holdovers from other languages don't quite convey that it's a closure
you're accessing and not a plain object (plus, a method on an object would have both a concept of itself and the closure you're operating in).
Another reason I'd like to have a 'current closure' keyword is that since functions/blocks are first-class, it would make sense if that class had member functions, no? So without the keyword, how would you access those functions from within the function you're currently defining (assuming its anonymous)?
I know you're reserved on using the this
keyword, but I feel that it would do want we want, without the parsing ambiguity of the caret. self
is used for the running object inside of a method. But this
can refer to the running context.
I've always wanted Brick to be as verbose as possible, so I prefer the this.caller.caller
style, as this explicitly states that the caller
is a property of the context, and this simplifies reading.
If we decide that this
carries too much weight from other languages (which it really does, but that's not insurmountable), what about our
?
Functions will have runtime type annotations associated with them, the way that all objects will have types to check at runtime, which is what permits pattern-matching. You can pattern match a function based on its' types.
our
is fairly good, I like it, anyways.
How about something like this_function
instead of our
? I like the idea of using our
instead of this
to avoid overusing this
, but I think meaning of our
is too similar to this
, which could get confusing. People might accidentally assume that they are just aliases to each other.
Namely, a function should be aware of its context and be able to modify it.
Firstly, a function should have a method by which it can call itself, anonymous fn or otherwise. (it's certainly more clear if the method is the same)
Which would output
Secondly, a function should probably have access to it's :before's and :after's; ie:
This is to simply allow for dynamically adding and removing before and after hooks.
It would also be useful to have a function's type signature available to the function, and maybe even a copy of the arguments it was passed.
It would also be nice to extend the syntax (^^^^^'s!) to let a function get these same attributes of its caller (and therefore its caller's caller, and its caller's caller's caller, etc...)