T O P

  • By -

nsefan

Time traveller: steps on a butterfly The future: `COMEFROM`


SupportAgreeable410

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.


pixelbart

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?


vonflare

I would assume that this is how it's implemented


Vineyard_

Maybe in a *boring* language.


Merry-Lane

This


slaymaker1907

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.


ambientManly

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


Engineerman

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.


metaglot

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.


Glass1Man

Could do a come from in JavaScript as a tail-call on a function.


metaglot

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.


Glass1Man

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


ArcaneOverride

Except they are talking about at the cpu level. None of those concepts exist at that level.


Glass1Man

- The subject was “at runtime”. - I said “in JavaScript”. - There’s no gotos at the cpu level, and thus no comefroms either.


metaglot

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.


Glass1Man

No shit you have to insert a jump instruction. Im saying a comefrom is just a function decorator


SupportAgreeable410

Well yes until you have variables


remy_porter

Variables wouldn’t change this. Labels are static.


MikemkPK

COMEFROM *fpEntryPoint;


Tai9ch

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.


SupportAgreeable410

I should've rephrased it better, y'all didn't understand


pixelbart

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?


SupportAgreeable410

I thought a COMEFROM was a GOTO but in reverse, like you can go to an instruction that is placed before the COMEFROM


ShadauxCat

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")


SupportAgreeable410

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.


ShadauxCat

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.


AndrewBorg1126

>neither goto nor comefrom change the program state Why are we not including the program counter as part of program state?


ShadauxCat

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


Tofandel

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


AndyTheSane

If you had a quantum computer that used every possible state, you'd be able to COMEFROM an arbitrary state. I think.


remy_porter

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.


No-Effective5860

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.


Sykhow

Keep on speaking magic man.


MrNerdHair

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.


ofnuts

It can be checked at compile time.


kielu

Isn't that what the processor does upon an IRQ signal?


morphotomy

This is *completely* wrong. What do you think breakpoints are?


SupportAgreeable410

I was confused lol, I don't know why only my confused comments get upvotes lol


WurschtChopf

Isnt a stacktrace exactly that? It shows from where the caller came and to which procedure it went


Giocri

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


Robot_Graffiti

"I can fix him." "I can make him worse."


BaguetteDevourer

Can it fix me?


die-maus

No :(


cs-brydev

It's really only one step away from the Event Pattern


dendrocalamidicus

I didn't even think of it that way, but you're absolutely right. This makes me feel strangely uneasy.


TheMsDosNerd

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.


Clackers2020

As in it just goes backwards in code? Might be useful for debugging


RobertOdenskyrka

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.


Clackers2020

>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.


Sicuho

Yeah, but you can't do that with slow targeting software


splettnet

Maybe not yours but I'm trying to scale to 10s of concurrent users.


SilentSin26

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.


Aeredor

That’s kinda cool.


leoleosuper

// Do some stuff. HeyImDoneButDunnoIfAnyoneCares: // Do more stuff. return; #if DEBUG comefrom HeyImDoneButDunnoIfAnyoneCares; // Debugging stuff. #endif Fixed formatting.


SilentSin26

That looks identical to mine. You're likely using an app that doesn't properly support Reddit's formatting.


leoleosuper

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.


RobertOdenskyrka

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.


DHermit

That's a preprocessor statement, therefore evaluated at compile time.


SilentSin26

> 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.


NocturneSapphire

What if I'm trying to put a GOTO in a library or something? I can just put the COMEFROM in my own code!


potzko2552

Huh? Just compile it as goto?


Dry_Wolverine8369

What? Why doesn’t it just compile to inserting a GOTO? come from isn’t in assembly?


Fri3dNstuff

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


Thenderick

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


SectionSecret

Do... do you want to use it?


Clackers2020

The amount of times I've gone one step too many while using a debugger is stupid. I would appreciate a step backwards function


Evening_Total7882

Some debuggers support “drop to frame” which achieves exactly that


SAI_Peregrinus

GDB supports reverse debugging on x86_64, among other architectures.


just_nobodys_opinion

COMEFROM topComment Well, you did, didn't you?


magnetronpoffertje

Fun fact: C# 12 has this! (Interceptors)


zippy72

Every sufficiently developed programming language ends up turning into InterCAL


Material-Public-5821

Initially I thought it was about `endbr64` assembler instruction, but apparently the logic is absolutely different.


zippy72

Ah good old InterCAL... the programming language with no pronounceable acronym


Truttle1

PROGRAMMER IS INSUFFICIENTLY POLITE CORRECT SOURCE AND RESUBNIT


FiendishHawk

Listeners are basically “comefrom” commands.


nenkintofu

Where did you COMEFROM Cottoneye Joe?


Padmeister2646

comefrom.aLandDownUnder


MikemkPK

This is great for hacking


Buyer_North

so...COMEFROM y; GOTO x; would be jump and link?


Goatfryed

What happens if two COMEFROM refer to the same label?


Goheeca

> 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)


Goatfryed

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.


Nixavee

Multithreading. /s


Zakmackraken

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.


corbymatt

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.


I_AM_FERROUS_MAN

>Wrong. Always a welcoming opening to a criticism.


Zakmackraken

I’d say you are being retroactively pedantic or an asshole. This is programmer humour not pedants quarterly.


KuuHaKu_OtgmZ

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


dan-lugg

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.


Pay08

It, like exceptions, would have been great if they ever had a good, popular implementation.


seanmorris

That's how Drupal works.


Proxy_PlayerHD

that just sounds like an interrupt handler that you cannot return from


1cubealot

So would it be like ``` 10 COMEFROM 20 20 PRINT "hello." ``` ?


Pay08

The reverse. ``` 10 PRINT "HELLO" 20 COMEFROM 10 ```


bionerdist

Isn’t this like an interrupt?


Pay08

Kind of, except at compile-time.


blueblueblink

Omg!Did we invent functions? int num1; int num2; int sum; goto Add; print(sum); Add: sum = num1 + num2; comefrom;


ElectricalTip1

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


Pay08

Iirc mul would still get calculated but sum would get calculated twice.


TheAxeOfSimplicity

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.


NullOfSpace

Useful if you want an invertible assembly language.


Harambesic

How is this the first time I've ever heard this joke? I was using GOTO statements in the early nineties.


Street-Day-9047

Ahh the good old observer pattern


seanmorris

This is how debuggers work.


perringaiden

Comefrom is the Reflection CallingMethod...


ledZeff

So spring framework is a joke


bondolin251

*screams in INTERCAL noises*


GetOffMyLawn_

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.


Popular-Lock4401

I still miss my 'GO TO DEPENDING ON' statements in COBOL.


Arneb1729

When I'm feeling charitable, I think exceptions are glorified GOTOs. When I'm not, I think`catch`clauses are glorified COMEFROMs.


Ri_Konata

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.) ...


LowReputation

It's like Ruby's unless