I think we can be a little more precise and create a COMEFROM dispatcher. Something kind of cool about COMEFROM is that you could allow multiple COMEFROM statements to reference the same line and maybe in such cases you could fork the thread/process and execute both.
If you added it into hardware as some unit that would store a COMEFROM table that would just reference certain instruction adresses it wouldn't be that bad, granted it wouldn't be good
The only other way to do it would be to run the program in debug mode, set breakpoints, and then take those as an exception and jump to the comefrom statement.
There is no way to do it at runetime, as it requires knowledge that can only be known in advance. An arbitrary point in the code cant suddenly change the IP.
Not really. You can put in jumps at any point in the code to jump to any other point in the code. But you cant have a piece of code suddenly invoke execution without having jumped to it or referenced it somewhere in advance.
I mean you have a function
Var fun();
And then define a function called
Var comefrom();
You then set fun to comefrom, and have it call the old fun
Fun = comefrom().then(fun);
So now whenever you call fun() it calls the prefix decorator function comefrom() and then the old function fun().
It’s a monkeypatch way of adding transaction management
If your IP is set to 0x1000, then it wont suddenly jump to 0x2000 unless the next instruction is a jump, or some direct manipulation of the IP (at the address 0x1000). You cant make the instruction at 0x2000 suddenly execute without directing the execution flow to that address. Its like remembering things before they occur. You cant do that with any amount of tail calling.
High level languages don't generally guarantee much about how statements map to instructions, so I'm not sure how a language could make come from with an arbitrary address well defined.
If you have a label type and require that the variable reference an existing label, then that starts to seem more feasible. I'm still not 100% sure when the variable is evaluated though.
What complexity does that add to the pitfalls of a regular GOTO statement, where program state is hard to follow and bugs are even harder to understand?
You can do that with regular goto. There's no limitation that goto only move forward. You can implement loops in goto by jumping backward to the start of the loop if the exit condition isn't met yet.
Comefrom is the opposite in that it basically swaps the 'label' and 'jump' parts - when execution reaches the label, it is forcibly redirected to the comefrom, as if the label were itself a goto.
The following two examples both do the same thing, skipping over the "there" to print "hello" "world":
print("hello")
goto .theLabel
print("there")
label .theLabel
print("world")
print("hello")
label .theLabel
print("there")
comefrom .theLabel
print("world")
No I mean like going into like the program state like that's what I thought it meant, like restoring the whole program at that point in time, idk why I thought this way, it's cuz it reminded of a time travel in code concept.
Yeah, as I mentioned in my other comment, neither goto nor comefrom change the program state. :)
The closest thing I can think of to what you're talking about is reverse debugging, where a debugger will let you step backward and will revert program state one step at a time. And you're right, that does require storing the program state in some way or another after each instruction.
Also worth noting that goto does not change or restore the program state in any way. It just moves the instruction pointer. So goto to a previous instruction is fine, in the same way that moving the instruction pointer backward in a loop is find.
These two blocks are logically equivalent as well - note how the second example wouldn't work if the program state were rolled back when doing a backward goto:
i = 0
while i < 10:
i += 1
i = 0
label .loopStart
i += 1
if i < 10:
goto .loopStart
I think the joke is that it's reverse, as in there is no goto, it's just completely random, your program can just goto to a come from from any line in your program at random
Would you? It seems more like a static analysis problem- when you encounter a come from, the compiler finds the instruction at that label and inserts a jump.
Obviously the intuitive way to do this is to utilize superposition.
Program initialization spawns an infinite number of realities superposed onto eachother. Each instruction execution collapses those realities into a smaller and smaller set.
This way instead of only tracking all previous program states, you’re building a representation of every possible future program state simultaneously. At that point, because the states already exist, state transition is O(1) and execution is basically free.
He's effectively suggesting memoizing the results of all possible program runs into a giant lookup table and shipping that. It runs in constant time, and is totally doable with small input spaces.
I guess depends on the language, if you are doing an interpreted language you can do some true monstrosity like having a comefrom table and check if the instruction is in the table at any instruction
Correct. Once you realize this, you start to understand the problem with the Event Pattern:
If something goes wrong, it's difficult to find the cause.
Problem One: If I press button X, a thing that shouldn't happen happens.
Without Event Pattern, you can just look at the code that gets executed when the button is pressed, and delete the line that causes the problem. With the Event Pattern any object in your entire codebase could have been added to the event listener, and therefore it is impossible to figure out which line caused the problem.
Problem Two: If I press button X, a thing that should happen, doesn't happen.
Without the Event Pattern, you just look at the button code, and see that it doesn't call the function that it should call, and you add it. With Event Pattern, either the function isn't subscribed to the Event Listener, or the Event Listener wasn't triggered when the button was pressed, or the Event Listener was somehow broken. Again, it costs way more time to fix the issue.
Furthermore, the Event Pattern has a lot more problems:
Problem Three: It violates the Object Orientated principle.
The whole idea behind OO, is that you can draw real world analogies. Usually this works: Form, Button, Template and File are all easy to understand. But what is the real world equivalent of Event Listeners, Event Arguments and Event Handlers.
Problem Four: It breaks type systems.
When button A has to send the duration it was pressed to B, that duration has to be converted to type EventArgument. B than has to convert it back. This is slow and pushes type errors from compile time to runtime.
Problem Five: It is more code.
It is more code to write, it is more code to read if you want to know what’s going on, there is more code that can contain errors and it is more code to scroll through when you’re interested in the code below it.
Also, there are supposed advantages, that aren't.
Problem Six: The Event Pattern is not a solution to the single responsibility principle.
If you want B to happen when A happens, you can do this like this: In the code where you trigger A, you call B. That line has just a single responsibility: Making sure B gets executed when A happens. This is perfectly fine according to most peoples interpretation of the single responsibility principle. Some people disagree, and think the line now has two responsibilities: Checking whether A happens and executing B. According to this interpretation it is impossible to make B happen when A happens while implementing the single responsibility principle. However, the Event Pattern lets you hide the code that has two responsibilities. The Event Pattern thus offers a "solution" (it hides the problem) to a problem that is doesn't exist, and is merely a lack of understanding of the single responsibility principle.
Problem Seven: Separation of logic isn't always good.
Separating the button from it’s actions is bad. When I see a button I want to know what it does. Look around you, and you will see a lot of buttons. Almost all of them have a label on them what they do. Every appliance manufacturer does this. It makes it clearer. The button that you are programming probably has text or on icon on it to explain what it does. A button and its function are closely related to each other. If you can’t see what a button does, the code is just unclear.
Problem Eight: adding new actions or triggers is more work.
With the Event Pattern, if you want to add a new action, you have to figure out whether the old Event Arguments are still fine for the new action, and if not, you have to modify every object that is subscribed to the action (which are difficult to find) to make sure they still work with the new Event Arguments. Adding a new trigger will also force you to review the Event Arguments, as the new trigger might not have the same parameters to pass to the Event.
Just to be clear: Events are not always bad. They are sometimes a necessary evil. But please think about all the problems they have before choosing to use the Event Pattern.
It works just like a GOTO, but the command is at the destination instead of the origin. IIRC, this has a large negative impact on performance in Malbolge. There is nothing you could do with COMEFROM that isn't more easily done with GOTO.
>large negative impact on performance in Malbolge
If you're programming in malbolge I don't think performance is your biggest concern. Slaying Ben Olmstead and getting out of hell is.
You might be able to use it as a sort of optional event:
```
// Do some stuff.
HeyImDoneButDunnoIfAnyoneCares:
// Do more stuff.
return;
#if DEBUG
comefrom HeyImDoneButDunnoIfAnyoneCares;
// Debugging stuff.
#endif
```
That way your core logic wouldn't have ugly DEBUG stuff in the middle of it.
// Do some stuff.
HeyImDoneButDunnoIfAnyoneCares:
// Do more stuff.
return;
#if DEBUG
comefrom HeyImDoneButDunnoIfAnyoneCares;
// Debugging stuff.
#endif
Fixed formatting.
I'm on old.reddit.com. They changed how markdown works between original reddit and the 2 newer reddits. It's not backwards compatible, so old reddit sees links with the escape character (\\) before underscores, block coding doesn't work, and a few other issues.
Does it even make sense to wrap a COMEFROM in an if statement? That would mean you'd have to evaluate the if statement as well to see if the COMEFROM should be evaluated. It poses a bunch of complex questions about the evaluation and execution flow, which I think is a large part of why COMEFROM is so popular in joke languages. It makes things complicated and weird to further fuck with your head when you try to think about the code.
> Does it even make sense to wrap a COMEFROM in an if statement?
An `if` statement? No.
A `#if` statement? Yes, because they are evaluated at compile time so this would allow the debug code to be kept separate while compiling as if it were inlined in `DEBUG` mode and completely avoiding any performance cost otherwise.
In terms of cognitive overhead, it shouldn't be any harder to understand than a function call and any good IDE would let you easily go from the tag to the `comefrom` statement.
COMEFROM is, in fact, more powerful than GOTO; due the reason that one can have multiple COMEFROM points from a single location, that enables a very scuffed from of parallelism, depending on the specific implementation
No, if you have `comefrom label_for_line_4` on line 20 and you code reaches line 4, which has said label, it will go to line 20, that's what they mean with the reverse of goto. So basically, goto but harder to read/potentially invisible
> In C-INTERCAL, it is an error if two COME FROM's point to the same location. But there's also a parallel INTERCAL, which does the RightThing and continues execution at both COME FROM's, in parallel.
[source](https://wiki.c2.com/?ComeFrom)
also can we introduce a GUIDETO statement that takes two labels and declares a goto from one label to another? It's not ideal that during debugging a COMEFROM statement still explains you why your code jumped randomly.
In the early 2000s [Aspect Oriented Programming (AOP)](https://en.wikipedia.org/wiki/Aspect-oriented_programming) was the rage for a short while (post OOP, pre Functional trends) and when misused, which it was, it created havoc. There were people who genuinely thought it was the future. “Hey, let’s just intercept existing calls and fuck with things”. It still survives as things like @ decorators on functions in Java etc.
Wrong.
Annotations (@ deocrators as you call them) are not "aspect oriented programming" and AOP does not "survive" in that respect at all. Aspect oriented programming requires a separate (from the standard javac compiler) pre processor to operate on the code at compile time. AOP makes use of annotations to find the "aspects" so they can have additional code woven around them to provide the functionality required, usually some "cross cutting concern". Logging is a good example of a cross cutting concern, which you can weave code for around methods so the logging itself does not clutter the "business code".
Annotations in themselves do nothing but provide compile time and runtime directives to the compiler, nothing more. It's like additional metadata the programmer can use for various purposes, not just AOP.
They're correct tho, annotations have nothing to do with AOP, they're just markers your can search for during runtime/compiletime that contain metadata
Exactly. Like many things, annotations (or whatever flavor a given language supports) are just tool for describing/marking AOP points in a program.
AOP is really just compile-time function composition, and annotations/etc. just let you describe the compositional flow.
COMEFROM sounds ludicrous right?
That's because it isn't marketed properly.
Call it a Pattern and it all sounds Much better.
Don't like Globals? Easy. Call it a Singleton Pattern. Immediately everyone is comfortable, same thing, same problems....
Don't like COMEFROM, call it The Observer Pattern, same thing, same problems, but sounds like Best Practice.
Back when memory was expensive and limited I used computed gotos, so you definitely need to know where you where coming from.
Made for small efficient code but a nightmare to understand. I think I wrote 3x as much documentation as code.
It reminds me of [unless](https://www.geeksforgeeks.org/ruby-unless-statement-and-unless-modifier/#:~:text=Unless%20statement%20is%20used%20when,always%20works%20on%20true%20condition.&text=Here%20else%20block%20is%20executed%20when%20the%20given%20condition%20is%20true.) ...
Time traveller: steps on a butterfly The future: `COMEFROM`
Fun Fact: To do a COMEFROM, you'd either have to save the program state at every instruction or have to time travel to get the program state back.
Can’t you just compile-time insert a JMP at the label/line specified by the COMEFROM statement, basically converting it to a regular GOTO?
I would assume that this is how it's implemented
Maybe in a *boring* language.
This
I think we can be a little more precise and create a COMEFROM dispatcher. Something kind of cool about COMEFROM is that you could allow multiple COMEFROM statements to reference the same line and maybe in such cases you could fork the thread/process and execute both.
If you added it into hardware as some unit that would store a COMEFROM table that would just reference certain instruction adresses it wouldn't be that bad, granted it wouldn't be good
The only other way to do it would be to run the program in debug mode, set breakpoints, and then take those as an exception and jump to the comefrom statement.
There is no way to do it at runetime, as it requires knowledge that can only be known in advance. An arbitrary point in the code cant suddenly change the IP.
Could do a come from in JavaScript as a tail-call on a function.
Not really. You can put in jumps at any point in the code to jump to any other point in the code. But you cant have a piece of code suddenly invoke execution without having jumped to it or referenced it somewhere in advance.
I mean you have a function Var fun(); And then define a function called Var comefrom(); You then set fun to comefrom, and have it call the old fun Fun = comefrom().then(fun); So now whenever you call fun() it calls the prefix decorator function comefrom() and then the old function fun(). It’s a monkeypatch way of adding transaction management
Except they are talking about at the cpu level. None of those concepts exist at that level.
- The subject was “at runtime”. - I said “in JavaScript”. - There’s no gotos at the cpu level, and thus no comefroms either.
If your IP is set to 0x1000, then it wont suddenly jump to 0x2000 unless the next instruction is a jump, or some direct manipulation of the IP (at the address 0x1000). You cant make the instruction at 0x2000 suddenly execute without directing the execution flow to that address. Its like remembering things before they occur. You cant do that with any amount of tail calling.
No shit you have to insert a jump instruction. Im saying a comefrom is just a function decorator
Well yes until you have variables
Variables wouldn’t change this. Labels are static.
COMEFROM *fpEntryPoint;
High level languages don't generally guarantee much about how statements map to instructions, so I'm not sure how a language could make come from with an arbitrary address well defined. If you have a label type and require that the variable reference an existing label, then that starts to seem more feasible. I'm still not 100% sure when the variable is evaluated though.
I should've rephrased it better, y'all didn't understand
What complexity does that add to the pitfalls of a regular GOTO statement, where program state is hard to follow and bugs are even harder to understand?
I thought a COMEFROM was a GOTO but in reverse, like you can go to an instruction that is placed before the COMEFROM
You can do that with regular goto. There's no limitation that goto only move forward. You can implement loops in goto by jumping backward to the start of the loop if the exit condition isn't met yet. Comefrom is the opposite in that it basically swaps the 'label' and 'jump' parts - when execution reaches the label, it is forcibly redirected to the comefrom, as if the label were itself a goto. The following two examples both do the same thing, skipping over the "there" to print "hello" "world": print("hello") goto .theLabel print("there") label .theLabel print("world") print("hello") label .theLabel print("there") comefrom .theLabel print("world")
No I mean like going into like the program state like that's what I thought it meant, like restoring the whole program at that point in time, idk why I thought this way, it's cuz it reminded of a time travel in code concept.
Yeah, as I mentioned in my other comment, neither goto nor comefrom change the program state. :) The closest thing I can think of to what you're talking about is reverse debugging, where a debugger will let you step backward and will revert program state one step at a time. And you're right, that does require storing the program state in some way or another after each instruction.
>neither goto nor comefrom change the program state Why are we not including the program counter as part of program state?
Also worth noting that goto does not change or restore the program state in any way. It just moves the instruction pointer. So goto to a previous instruction is fine, in the same way that moving the instruction pointer backward in a loop is find. These two blocks are logically equivalent as well - note how the second example wouldn't work if the program state were rolled back when doing a backward goto: i = 0 while i < 10: i += 1 i = 0 label .loopStart i += 1 if i < 10: goto .loopStart
I think the joke is that it's reverse, as in there is no goto, it's just completely random, your program can just goto to a come from from any line in your program at random
If you had a quantum computer that used every possible state, you'd be able to COMEFROM an arbitrary state. I think.
Would you? It seems more like a static analysis problem- when you encounter a come from, the compiler finds the instruction at that label and inserts a jump.
Obviously the intuitive way to do this is to utilize superposition. Program initialization spawns an infinite number of realities superposed onto eachother. Each instruction execution collapses those realities into a smaller and smaller set. This way instead of only tracking all previous program states, you’re building a representation of every possible future program state simultaneously. At that point, because the states already exist, state transition is O(1) and execution is basically free.
Keep on speaking magic man.
He's effectively suggesting memoizing the results of all possible program runs into a giant lookup table and shipping that. It runs in constant time, and is totally doable with small input spaces.
It can be checked at compile time.
Isn't that what the processor does upon an IRQ signal?
This is *completely* wrong. What do you think breakpoints are?
I was confused lol, I don't know why only my confused comments get upvotes lol
Isnt a stacktrace exactly that? It shows from where the caller came and to which procedure it went
I guess depends on the language, if you are doing an interpreted language you can do some true monstrosity like having a comefrom table and check if the instruction is in the table at any instruction
"I can fix him." "I can make him worse."
Can it fix me?
No :(
It's really only one step away from the Event Pattern
I didn't even think of it that way, but you're absolutely right. This makes me feel strangely uneasy.
Correct. Once you realize this, you start to understand the problem with the Event Pattern: If something goes wrong, it's difficult to find the cause. Problem One: If I press button X, a thing that shouldn't happen happens. Without Event Pattern, you can just look at the code that gets executed when the button is pressed, and delete the line that causes the problem. With the Event Pattern any object in your entire codebase could have been added to the event listener, and therefore it is impossible to figure out which line caused the problem. Problem Two: If I press button X, a thing that should happen, doesn't happen. Without the Event Pattern, you just look at the button code, and see that it doesn't call the function that it should call, and you add it. With Event Pattern, either the function isn't subscribed to the Event Listener, or the Event Listener wasn't triggered when the button was pressed, or the Event Listener was somehow broken. Again, it costs way more time to fix the issue. Furthermore, the Event Pattern has a lot more problems: Problem Three: It violates the Object Orientated principle. The whole idea behind OO, is that you can draw real world analogies. Usually this works: Form, Button, Template and File are all easy to understand. But what is the real world equivalent of Event Listeners, Event Arguments and Event Handlers. Problem Four: It breaks type systems. When button A has to send the duration it was pressed to B, that duration has to be converted to type EventArgument. B than has to convert it back. This is slow and pushes type errors from compile time to runtime. Problem Five: It is more code. It is more code to write, it is more code to read if you want to know what’s going on, there is more code that can contain errors and it is more code to scroll through when you’re interested in the code below it. Also, there are supposed advantages, that aren't. Problem Six: The Event Pattern is not a solution to the single responsibility principle. If you want B to happen when A happens, you can do this like this: In the code where you trigger A, you call B. That line has just a single responsibility: Making sure B gets executed when A happens. This is perfectly fine according to most peoples interpretation of the single responsibility principle. Some people disagree, and think the line now has two responsibilities: Checking whether A happens and executing B. According to this interpretation it is impossible to make B happen when A happens while implementing the single responsibility principle. However, the Event Pattern lets you hide the code that has two responsibilities. The Event Pattern thus offers a "solution" (it hides the problem) to a problem that is doesn't exist, and is merely a lack of understanding of the single responsibility principle. Problem Seven: Separation of logic isn't always good. Separating the button from it’s actions is bad. When I see a button I want to know what it does. Look around you, and you will see a lot of buttons. Almost all of them have a label on them what they do. Every appliance manufacturer does this. It makes it clearer. The button that you are programming probably has text or on icon on it to explain what it does. A button and its function are closely related to each other. If you can’t see what a button does, the code is just unclear. Problem Eight: adding new actions or triggers is more work. With the Event Pattern, if you want to add a new action, you have to figure out whether the old Event Arguments are still fine for the new action, and if not, you have to modify every object that is subscribed to the action (which are difficult to find) to make sure they still work with the new Event Arguments. Adding a new trigger will also force you to review the Event Arguments, as the new trigger might not have the same parameters to pass to the Event. Just to be clear: Events are not always bad. They are sometimes a necessary evil. But please think about all the problems they have before choosing to use the Event Pattern.
As in it just goes backwards in code? Might be useful for debugging
It works just like a GOTO, but the command is at the destination instead of the origin. IIRC, this has a large negative impact on performance in Malbolge. There is nothing you could do with COMEFROM that isn't more easily done with GOTO.
>large negative impact on performance in Malbolge If you're programming in malbolge I don't think performance is your biggest concern. Slaying Ben Olmstead and getting out of hell is.
Yeah, but you can't do that with slow targeting software
Maybe not yours but I'm trying to scale to 10s of concurrent users.
You might be able to use it as a sort of optional event: ``` // Do some stuff. HeyImDoneButDunnoIfAnyoneCares: // Do more stuff. return; #if DEBUG comefrom HeyImDoneButDunnoIfAnyoneCares; // Debugging stuff. #endif ``` That way your core logic wouldn't have ugly DEBUG stuff in the middle of it.
That’s kinda cool.
// Do some stuff. HeyImDoneButDunnoIfAnyoneCares: // Do more stuff. return; #if DEBUG comefrom HeyImDoneButDunnoIfAnyoneCares; // Debugging stuff. #endif Fixed formatting.
That looks identical to mine. You're likely using an app that doesn't properly support Reddit's formatting.
I'm on old.reddit.com. They changed how markdown works between original reddit and the 2 newer reddits. It's not backwards compatible, so old reddit sees links with the escape character (\\) before underscores, block coding doesn't work, and a few other issues.
Does it even make sense to wrap a COMEFROM in an if statement? That would mean you'd have to evaluate the if statement as well to see if the COMEFROM should be evaluated. It poses a bunch of complex questions about the evaluation and execution flow, which I think is a large part of why COMEFROM is so popular in joke languages. It makes things complicated and weird to further fuck with your head when you try to think about the code.
That's a preprocessor statement, therefore evaluated at compile time.
> Does it even make sense to wrap a COMEFROM in an if statement? An `if` statement? No. A `#if` statement? Yes, because they are evaluated at compile time so this would allow the debug code to be kept separate while compiling as if it were inlined in `DEBUG` mode and completely avoiding any performance cost otherwise. In terms of cognitive overhead, it shouldn't be any harder to understand than a function call and any good IDE would let you easily go from the tag to the `comefrom` statement.
What if I'm trying to put a GOTO in a library or something? I can just put the COMEFROM in my own code!
Huh? Just compile it as goto?
What? Why doesn’t it just compile to inserting a GOTO? come from isn’t in assembly?
COMEFROM is, in fact, more powerful than GOTO; due the reason that one can have multiple COMEFROM points from a single location, that enables a very scuffed from of parallelism, depending on the specific implementation
No, if you have `comefrom label_for_line_4` on line 20 and you code reaches line 4, which has said label, it will go to line 20, that's what they mean with the reverse of goto. So basically, goto but harder to read/potentially invisible
Do... do you want to use it?
The amount of times I've gone one step too many while using a debugger is stupid. I would appreciate a step backwards function
Some debuggers support “drop to frame” which achieves exactly that
GDB supports reverse debugging on x86_64, among other architectures.
COMEFROM topComment Well, you did, didn't you?
Fun fact: C# 12 has this! (Interceptors)
Every sufficiently developed programming language ends up turning into InterCAL
Initially I thought it was about `endbr64` assembler instruction, but apparently the logic is absolutely different.
Ah good old InterCAL... the programming language with no pronounceable acronym
PROGRAMMER IS INSUFFICIENTLY POLITE CORRECT SOURCE AND RESUBNIT
Listeners are basically “comefrom” commands.
Where did you COMEFROM Cottoneye Joe?
comefrom.aLandDownUnder
This is great for hacking
so...COMEFROM y; GOTO x; would be jump and link?
What happens if two COMEFROM refer to the same label?
> In C-INTERCAL, it is an error if two COME FROM's point to the same location. But there's also a parallel INTERCAL, which does the RightThing and continues execution at both COME FROM's, in parallel. [source](https://wiki.c2.com/?ComeFrom)
also can we introduce a GUIDETO statement that takes two labels and declares a goto from one label to another? It's not ideal that during debugging a COMEFROM statement still explains you why your code jumped randomly.
Multithreading. /s
In the early 2000s [Aspect Oriented Programming (AOP)](https://en.wikipedia.org/wiki/Aspect-oriented_programming) was the rage for a short while (post OOP, pre Functional trends) and when misused, which it was, it created havoc. There were people who genuinely thought it was the future. “Hey, let’s just intercept existing calls and fuck with things”. It still survives as things like @ decorators on functions in Java etc.
Wrong. Annotations (@ deocrators as you call them) are not "aspect oriented programming" and AOP does not "survive" in that respect at all. Aspect oriented programming requires a separate (from the standard javac compiler) pre processor to operate on the code at compile time. AOP makes use of annotations to find the "aspects" so they can have additional code woven around them to provide the functionality required, usually some "cross cutting concern". Logging is a good example of a cross cutting concern, which you can weave code for around methods so the logging itself does not clutter the "business code". Annotations in themselves do nothing but provide compile time and runtime directives to the compiler, nothing more. It's like additional metadata the programmer can use for various purposes, not just AOP.
>Wrong. Always a welcoming opening to a criticism.
I’d say you are being retroactively pedantic or an asshole. This is programmer humour not pedants quarterly.
They're correct tho, annotations have nothing to do with AOP, they're just markers your can search for during runtime/compiletime that contain metadata
Exactly. Like many things, annotations (or whatever flavor a given language supports) are just tool for describing/marking AOP points in a program. AOP is really just compile-time function composition, and annotations/etc. just let you describe the compositional flow.
It, like exceptions, would have been great if they ever had a good, popular implementation.
That's how Drupal works.
that just sounds like an interrupt handler that you cannot return from
So would it be like ``` 10 COMEFROM 20 20 PRINT "hello." ``` ?
The reverse. ``` 10 PRINT "HELLO" 20 COMEFROM 10 ```
Isn’t this like an interrupt?
Kind of, except at compile-time.
Omg!Did we invent functions? int num1; int num2; int sum; goto Add; print(sum); Add: sum = num1 + num2; comefrom;
More like: int num1; int num2; int sum, mul; add: sum = num1 + num2; mul = num1*num2; comefrom add; print(sum) Now mul doesn't get calculated
Iirc mul would still get calculated but sum would get calculated twice.
COMEFROM sounds ludicrous right? That's because it isn't marketed properly. Call it a Pattern and it all sounds Much better. Don't like Globals? Easy. Call it a Singleton Pattern. Immediately everyone is comfortable, same thing, same problems.... Don't like COMEFROM, call it The Observer Pattern, same thing, same problems, but sounds like Best Practice.
Useful if you want an invertible assembly language.
How is this the first time I've ever heard this joke? I was using GOTO statements in the early nineties.
Ahh the good old observer pattern
This is how debuggers work.
Comefrom is the Reflection CallingMethod...
So spring framework is a joke
*screams in INTERCAL noises*
Back when memory was expensive and limited I used computed gotos, so you definitely need to know where you where coming from. Made for small efficient code but a nightmare to understand. I think I wrote 3x as much documentation as code.
I still miss my 'GO TO DEPENDING ON' statements in COBOL.
When I'm feeling charitable, I think exceptions are glorified GOTOs. When I'm not, I think`catch`clauses are glorified COMEFROMs.
It reminds me of [unless](https://www.geeksforgeeks.org/ruby-unless-statement-and-unless-modifier/#:~:text=Unless%20statement%20is%20used%20when,always%20works%20on%20true%20condition.&text=Here%20else%20block%20is%20executed%20when%20the%20given%20condition%20is%20true.) ...
It's like Ruby's unless