lukasb 5 days ago

I always associated INTERCAL with COME FROM but it turns out that was "invented" separately (although its first implementation was in C-INTERCAL.)

3
anyfoo 5 days ago

COBOL has an almost-COME-FROM, its called “ALTER” and it changes the destination of a GO TO, but it’s “discouraged” nowadays.

skissane 4 days ago

Historically, COBOL has had some rather fascinatingly unusual features-my favourite is OPEN INPUT REVERSED, which opens files for reading backwards-not sure if this was ever in any of the COBOL standards, but it exists in IBM mainframe COBOL, and many implementations on other platforms have copied it from there.

It usually only works for files with fixed length records, and reads the records in reverse sequential order, but the bits/bytes within the record in forward order. In theory, it could be made to work for variable-length record files as well, but I’m not aware of any implementation which does.

The original motivation was to support reading magnetic tapes backwards, so you could write data to a tape, then read it back in without a time-consuming rewind - which was important in the early years of computing, when memory and disk sizes were so small, magnetic tapes were commonly used for temporary storage / work files.

Most tape drives nowadays don’t support reading tapes backwards, even though there are standard SCSI commands defined to do so-but I believe IBM 3592 tape drive series still supports this, as do virtual tape servers targeted at mainframes. The drive physically reads the bits off the tape in reverse order, but then reverses the data before sending it to the computer.

I’m not aware of any other language which supports reading files backwards, other than COBOL. Well, mainframe assembly does, and you can invoke the relevant mainframe IO calls from languages such as C-but COBOL is the only language I know of which has it as a language feature.

rbanffy 1 day ago

> I’m not aware of any other language which supports reading files backwards, other than COBOL.

You can always use seek() and read(). Won’t work for variable length records, but open(file).readlines()[::-1] should work in Python (even though it’s cheating under the hood).

skissane 1 day ago

Those are ways of emulating reading files backward using other language features, not explicit language features for reverse-reading of files.

Actually now I realise z/OS stdio has support for backwards-reading of VSAM files: you can fopen with mode “r,type=record,acc=bwd” and “acc=bwd” sets file read direction to reverse. And you can put an open type=record file in reverse reading mode by calling flocate() with __KEY_LAST, __KEY_EQ_BWD, etc

But going just by the docs, that only works for VSAM not BSAM. Whereas COBOL’s OPEN INPUT REVERSED definitely works for BSAM, but not sure if it works for VSAM

rbanffy 1 day ago

Fair, but reading files backwards doesn't make much sense on random access media. I wonder if anyone still uses it.

skissane 1 day ago

I don’t know who uses the COBOL feature or the z/OS stdio feature

But relational databases do it all the time… it is very common for certain queries (especially those involving ORDER BY DESC) to be compiled into query plans which do reverse table/index scans… stdio VSAM acc=bwd is just the same thing at a much lower level - VSAM is pretty close to the storage engine layer of a standard relational database, to the point that relational databases for z/OS sometimes end up using VSAM instead of the custom storage engines they use on other platforms

> Fair, but reading files backwards doesn't make much sense on random access media.

On the contrary, it actually makes more sense. A tape drive has a standard direction, and reverse reading is rarely supported (especially nowadays) and requires special circuitry if it is supported. Floppy disks, hard disks and optical disks also have an inherent direction of rotation, but they are really random-sequential not pure random access devices. But true random access devices-DRAM, flash, SSD, etc-don’t have any inherent direction, so reading backwards (decreasing sequential block addresses) is just as valid as reading forwards (increasing sequential block addresses)

rbanffy 1 day ago

> compiled into query plans which do reverse table/index scans…

But are they implemented as reading files backwards? Reading datasets in any direction is very normal because all our media is, for all practical purposes, random-access. Stepping through data backwards is just a special case of random access.

skissane 2 hours ago

> But are they implemented as reading files backwards? Reading datasets in any direction is very normal because all our media is, for all practical purposes, random-access. Stepping through data backwards is just a special case of random access.

Well, of course they are reading the file backwards, in terms of making successive calls to pread/preadv/preadv2/aio_read/lio_listio/io_uring/etc with decreasing file offsets, or successive reads to an mmap-ed file with decreasing memory addresses.

And of course, you can't read a file backwards with fseek/fread (or lseek/read), except on a very limited number of platforms that support that – but a serious database is unlikely to be using seek+read begin with, except in unusual circumstances such as VSAM under z/OS (z/OS pread/etc only work with file descriptors, which are only supported for UNIX files, not MVS datasets)

Sesse__ 4 days ago

Many languages have exceptions, which are essentially COME FROM.

vnorilo 5 days ago

The recent C# feature called interceptors [1] pretty much looks like comefrom from where I stand. Yet everyone talking about it has either been serious, or very good at trolling.

1: https://khalidabuhakmeh.com/dotnet-8-interceptors

skissane 5 days ago

From your link:

[InterceptsLocation("/Users/khalidabuhakmeh/RiderProjects/ConsoleApp12/ConsoleApp12/Program.cs", line: 3, character: 3)]

they added a language feature which is sensitive to precise line/character offsets in your source code, so the tiniest change to the source code invalidates your code…

I’m speechless. Whatever they are aiming to achieve here, surely there is a more elegant, less ugly way

poizan42 5 days ago

You are not supposed to use interceptors in code you write yourself. The feature exists for Roslyn Source Generators that runs every time you build the code.

ninkendo 4 days ago

I’m still confused though, if you’re generating the code anyway, why do you need an interceptor? Can’t you just generate the code to match what you want to redirect to, directly inline?

poizan42 4 days ago

Yes if all the code was generated. The problem is when you want to modify the behavior of user-supplied code - Roslyn Source Generators are additive so you cannot make modifications directly to user-supplied code.

You can read about how they work here: https://github.com/dotnet/roslyn/blob/main/docs/features/inc...

Basically they get the files (and ambient metadata) that are part of the compilation, filter to the parts it depends on, transforms to a in-mem representation of the data needed for the code generation, and then finally adds new files to the compilation. Since they can only add new files they cannot e.g. add code to be executed before or after user code is executed like with AOP. Interceptors are a solution to that problem.

ninkendo 4 days ago

Interesting, so you’re saying generated code can change the behavior of user code with no indication this is happening from directly reading the user code… that sounds pretty horrifying. I guess AOP in general is pretty horrifying to me though. Maybe it’s useful if you restrict its use to very specific things like logging or something.

poizan42 4 days ago

Well yes, hopefully you know what you are doing when you reference a source generator. This could ofc. also be done with custom msbuild task that modfies the code sent to the compiler or the assembly after compilation (like Fody), Source Generators just makes the process more streamlined and integrates with things like IntelliSense.

ninkendo 4 days ago

> Well yes, hopefully you know what you are doing when you reference a source generator

I don't think there's much that's scary about generating source code in general. If it's self-contained and you have to actually call the generated code to use it, it's not really much different than any other code. But the idea of having code A change the behavior of code B is what's horrifying, regardless of whether code A is generated or not. If I'm reading code B I want to be able to reason about what I see without having to worry about some spooky action at a distance coming from somewhere else.

jayd16 4 days ago

> that sounds pretty horrifying.

Things are constantly doing this. Frameworks use reflection or markup or all other kinds of things that count as magic if you don't bother to understand what's going on.

pjmlp 5 days ago

I am completly against them, I think they have re-invented Microsoft Fakes, and PostSharp, only badly.

MangoToupe 5 days ago

I thought come-from was an early scheme primitive. It's pretty trivial to implement and it's a fun trick.

Edit: i am very wrong. i also had no clue it was meant as a joke. I just figured someone had a use case.