00:45:27 <esolangs> [[Special:Log/newusers]] create * SEGFAULT * New user account
00:46:44 -!- impomatic has quit (Quit: Client closed).
00:51:43 <esolangs> [[Esolang:Introduce yourself]] M https://esolangs.org/w/index.php?diff=171525&oldid=171399 * SEGFAULT * (+288) /* Introductions */
00:52:27 <esolangs> [[User:SEGFAULT]] N https://esolangs.org/w/index.php?oldid=171526 * SEGFAULT * (+47) Created page with "HII!!! IM MAKING AN ESOLANG CALLED COINLOCKER!!"
01:19:06 -!- pool has quit (Ping timeout: 256 seconds).
01:45:27 -!- amby has quit (Quit: so long suckers! i rev up my motorcylce and create a huge cloud of smoke. when the cloud dissipates im lying completely dead on the pavement).
01:47:11 -!- ais523 has quit (Quit: quit).
01:49:44 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] N https://esolangs.org/w/index.php?oldid=171527 * A() * (+777) Created page with "This language operates on memory by copying flipping bits in a text file by [[User:A()]] ==Commands== {| class="wikitable" |+ Caption text |- ! Header text !! Header text |- | _ || Copy bit to next bit |- | / || flip bit |- | \ || flip copy |- |
02:00:39 -!- somefan has joined.
03:04:18 <esolangs> [[Cat Program (language)]] M https://esolangs.org/w/index.php?diff=171528&oldid=163413 * Mun Hammer * (-20) made the python implementation actually work
03:07:42 <esolangs> [[Talk:Cat Program (language)]] N https://esolangs.org/w/index.php?oldid=171529 * Mun Hammer * (+204) Started the talk page
05:08:32 <esolangs> [[Baba]] https://esolangs.org/w/index.php?diff=171530&oldid=171489 * Akalysi * (+71)
05:11:48 <esolangs> [[Special:Log/newusers]] create * UnavgAustralian * New user account
06:13:31 <esolangs> [[Esolang:Introduce yourself]] https://esolangs.org/w/index.php?diff=171531&oldid=171525 * UnavgAustralian * (+254)
06:49:59 -!- impomatic has joined.
07:08:46 -!- somefan has quit (Quit: Client closed).
07:26:02 -!- Sgeo has quit (Read error: Connection reset by peer).
08:25:45 -!- ^[ has quit (Ping timeout: 245 seconds).
08:40:04 -!- tromp has joined.
09:46:12 <esolangs> [[User talk:RaiseAfloppaFan3925]] M https://esolangs.org/w/index.php?diff=171532&oldid=171501 * RaiseAfloppaFan3925 * (+62) /* I have 2 esolangs with long names */ don't worry, they'll be added right away
09:50:19 <esolangs> [[User:RaiseAfloppaFan3925]] M https://esolangs.org/w/index.php?diff=171533&oldid=171290 * RaiseAfloppaFan3925 * (+54) add link to rankings
09:50:38 <esolangs> [[User:RaiseAfloppaFan3925/Rankings]] M https://esolangs.org/w/index.php?diff=171534&oldid=171031 * RaiseAfloppaFan3925 * (+1353) Add two esolangs
10:08:26 -!- tromp has changed hostmask to ~textual@user/tromp.
10:12:46 <esolangs> [[User talk:Yoyolin0409]] https://esolangs.org/w/index.php?diff=171535&oldid=171442 * Yoyolin0409 * (+99)
11:09:27 -!- ^[ has joined.
11:09:51 <esolangs> [[Talk:Cat Program (language)]] https://esolangs.org/w/index.php?diff=171536&oldid=171529 * None1 * (+438) /* Python implementation */
11:10:54 <esolangs> [[User guessed]] https://esolangs.org/w/index.php?diff=171537&oldid=171414 * None1 * (+49) /* Commands */ guess
11:14:04 <esolangs> [[Do something]] N https://esolangs.org/w/index.php?oldid=171538 * Yoyolin0409 * (+619) Created page with "'''Do something''' is an esolang by [[User:Yoyolin0409]]. Its inspiration comes from a variety of other programming languages, including: [[INTERCAL]], [[Brainfuck]], [[Light Pattern]], [[Velato]], [[Malbolge]], [[Whitespace]], [[Piet]], [[Olympus]], [[Shakespea
11:58:11 <esolangs> [[User guessed]] https://esolangs.org/w/index.php?diff=171539&oldid=171537 * PrySigneToFry * (+65)
12:04:18 -!- amby has joined.
12:17:49 -!- ais523 has joined.
12:52:18 <esolangs> [[A Triple Sharp]] https://esolangs.org/w/index.php?diff=171540&oldid=171381 * PrySigneToFry * (+29)
13:14:39 <esolangs> [[Special:Log/upload]] upload * PrySigneToFry * uploaded "[[File:Tritone.png]]": It will be used to illustrate a 'tritone' and may be used by [[Fugue]] or its discussion page.
13:15:39 <esolangs> [[Talk:Fugue]] https://esolangs.org/w/index.php?diff=171542&oldid=153594 * PrySigneToFry * (+35)
13:27:28 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171543&oldid=171538 * Yoyolin0409 * (+2706)
13:28:08 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171544&oldid=171543 * Yoyolin0409 * (+8) /* Do something */
13:28:56 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171545&oldid=171544 * Yoyolin0409 * (-12) /* Do something */
13:31:02 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171546&oldid=171545 * Yoyolin0409 * (+20) /* Do something */
13:31:39 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171547&oldid=171546 * Yoyolin0409 * (+16)
13:37:56 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171548&oldid=171547 * Yoyolin0409 * (+795)
13:47:33 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171549&oldid=171548 * Yoyolin0409 * (+814)
13:51:43 -!- impomatic has quit (Ping timeout: 272 seconds).
13:58:24 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
13:58:44 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171550&oldid=171549 * Yoyolin0409 * (+1782) /* Do craft */
13:59:07 <esolangs> [[Do something]] https://esolangs.org/w/index.php?diff=171551&oldid=171550 * Yoyolin0409 * (+2) /* This section's Hello world! */
14:06:21 <esolangs> [[SETANDCOUNT]] https://esolangs.org/w/index.php?diff=171552&oldid=162256 * I am islptng * (-240)
14:13:59 <esolangs> [[SetIncrementor]] N https://esolangs.org/w/index.php?oldid=171553 * I am islptng * (+748) Created page with "<b>SetIncrementor</b> is an esolang derived from [[SETANDCOUNT]], made by islptng. == Data format == This esolang operates on a set(sorted) of positive integers. == Syntax == A list of tokens separated by spaces. If it is a number N, it increments the Nth n
14:22:25 -!- impomatic has joined.
14:42:43 <esolangs> [[User:/Harkan]] N https://esolangs.org/w/index.php?oldid=171554 * * (+1628) Created page with "{{WIP}} '''Harkan''' is an esolang made by [[User:]]. It currently does not have an interpreter, but you can make one! == Basis == Harkan is built with the following starting command: <pre> Harkan { } </pre> It is the main class where its contents are run. == Classes
14:43:10 <esolangs> [[Special:Log/move]] move * * moved [[User:/Harkan]] to [[Harkan]]
14:44:04 <esolangs> [[User:/esolangs]] https://esolangs.org/w/index.php?diff=171557&oldid=171499 * * (+74)
14:44:51 <esolangs> [[Harkan]] M https://esolangs.org/w/index.php?diff=171558&oldid=171555 * * (-18)
14:48:17 <esolangs> [[SetIncrementor]] https://esolangs.org/w/index.php?diff=171559&oldid=171553 * I am islptng * (+666)
14:55:39 <esolangs> [[SetIncrementor]] https://esolangs.org/w/index.php?diff=171560&oldid=171559 * I am islptng * (+541)
14:56:16 <esolangs> [[SetIncrementor]] https://esolangs.org/w/index.php?diff=171561&oldid=171560 * I am islptng * (-11)
14:57:39 -!- tromp has joined.
15:21:06 <esolangs> [[Abacus Computer]] https://esolangs.org/w/index.php?diff=171562&oldid=171052 * Timm * (+260)
15:27:15 -!- ais523 has quit (Quit: quit).
15:29:34 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
15:30:31 -!- tromp has joined.
15:32:28 -!- ais523 has joined.
15:54:25 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
16:27:19 <esolangs> [[Language list]] https://esolangs.org/w/index.php?diff=171563&oldid=171521 * A() * (+43) /* E */
16:27:53 <esolangs> [[User:A()]] https://esolangs.org/w/index.php?diff=171564&oldid=171496 * A() * (+42)
16:28:47 -!- tromp has joined.
16:48:44 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171565&oldid=171527 * A() * (+172)
17:07:41 -!- Yayimhere has joined.
17:18:27 <korvo> It's okay. I only stepped in to chill an edit war, and it seems that the warring stopped.
17:19:08 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171566&oldid=171565 * A() * (+269)
17:20:22 <korvo> ais523: I had a brain moment last night and I think that I have three computable models of linear logic. LMK if this is the sort of thing that you're hunting for, although I suspect that you already know all this.
17:21:04 <korvo> The models are FdVect_Q, Chu_2, and a novel values-and-boxes model that somewhat resembles the Rust pirating discussion.
17:21:20 <ais523> korvo: I think that this is a different level of abstraction from the one I've been focusing on
17:21:46 <ais523> OTOH, I've been actively working on a box-based model in order to try to explain Rust mutable references in terms of things the language already had, that's my plan for my next blog post
17:21:54 <korvo> Yeah, this is like "what if Cammy, but linear", not "how to improve Rust". But I didn't want to withhold it.
17:21:58 <ais523> but that's not linear-logic-related
17:22:39 <ais523> I guess my *current* point of view about the whole pirating thing is "oh good, I can stop worrying about shared references in my models any more, they have a simple type theory that I can just apply to my model"
17:22:54 <ais523> and just try to work on Rust-without-shared-references and add them back alter
17:23:30 <ais523> I think my biggest observation along these lines is that pirating a mutable reference gives you a shared reference, but pirating a Rust `Box` *also* gives you a shared reference
17:23:58 <ais523> which seems redundant but is incredibly useful when you're trying to create mutable references from scratch
17:24:09 <korvo> Ah, so mutation is primitive in your approach. That might be the biggest difference. I'm modeling mutation with "linear" implication.
17:25:02 <korvo> Like, it's not technically a problem for me if a non-linear operation on bits is part of a CPU's functionality. I can just pretend that the underlying storage for those bits is linear, like a row of light switches which just happen to encode classical bits,
17:25:09 <ais523> korvo: I *think* the mutation primitive in my approach is the "box overwrite" but it's one of the awkward parts of it
17:25:26 <ais523> or maybe even the box swap
17:25:38 <ais523> I think it's been observed before that Rust's underlying mutation primitive seems to be a swap
17:26:23 <korvo> Makes sense. You're able to see the locations of boxes too, right? Like, an address or a pointer? I'm imagining that the boxes are wholly opaque. Like there's a vast desert and occasionally I've cordoned off a little section of flat desert and said "this is a region" even though there's nothing there.
17:26:31 <ais523> in particular Cell::swap is interesting because all the normal the mutation operations in Rust can be defined in terms of it, but it can't be defined in terms of any of the others
17:26:40 <korvo> And then values are like raised sections of desert, or holes for negated values.
17:27:15 <ais523> actually it's the reverse, I'm pretty sure each box defines its own address space (but that has a relationship to the box it was borrowed from), and that this is where provenance comes from
17:27:19 <korvo> Whoa, that's actually pretty deep.
17:27:36 <korvo> Oh, like a hierarchy of boxes?
17:28:23 <ais523> it's subtle, pinning down this exact subtlety is important because as far as I can tell, pinning down the subtlety correctly defines the entire Rust aliasing model which is something that people have been trying to figure out for years
17:28:52 <ais523> but the basic approach I'm planning in my blog post is "instead of a mutable borrow, let's move part of this box into another box" and then having the boxes share memory is an optimisation
17:29:33 <ais523> but, in order to be able to model how Rust mutable references currently work, you need a "reclaim" information which forcibly moves values from the smaller box back into the bigger one, even if you don't have access to the smaller box
17:30:20 <ais523> the reclaim operation is mathematically a mess, and causes a lot of problems for Rust use in practice too, but it's implied to exist by how Rust &mut works – and I think this is the root cause of many (all?) of the problems observed with &mut in practice
17:30:55 <ais523> if you don't have reclaiming, the boxes could theoretically be entirely independent (but you'd still probably want to track a hierarchy of them to be able to optimise the code correctly)
17:32:26 <korvo> It's almost like versioned storage. I'm still mulling over how you put this before: because linear logic has disjunctions that operate in parallel, it's possible for mutations to involve one of *several* rows of versioned objects, depending on how the compiler chooses to interleave them.
17:33:07 <korvo> ...Which, by Galois-Yanofsky theory, seems like a broken symmetry that the compiler provides rather than a core part of the mathematical model.
17:33:21 <ais523> re: Cell::swap, I don't think it's the *actual* primitive – the actual primitive is something more like GhostCell::swap, but cells keyed to weird proofs of uniqueness don't exist in the standard library, you have to use external crates for those
17:33:34 <ais523> so Cell::swap is enough for the standard library types
17:35:02 <korvo> I'm imagining a little earth mover out in the desert. This is what a linear implication looks like; it's a little machine that moves stuff from one place to another. To assemble *any* non-negated value, just assemble stuff, one hunk of moved earth at a time.
17:35:41 <esolangs> [[Hello world program in esoteric languages (D-G)]] https://esolangs.org/w/index.php?diff=171567&oldid=163611 * A() * (+224)
17:35:46 <korvo> In FdVect_Q or any Vect-like category, there's basis vectors. Build up any value by expressing it along the basis. In Chu_2, there's the two Boolean values, and again there's basis spaces that can build any tableau.
17:36:04 <ais523> is the aim to produce a denotational semantics?
17:36:50 <korvo> So, if we assume that our values are discrete or otherwise set-like then swapping everything into place seems like a complete basis for constructions. You can build anything you want if it's made up of "move a 0 into place" and "move a 1 into place" mini-instructions.
17:37:51 <ais523> right, I've noticed the recursive nature of constructing values
17:37:54 <korvo> ais523: A little. I think any claimed model of linear logic should have a story for multiplicative disjunction, and I'm annoyed that it seems to trivialize in every model. I am coming to understand that, in linear logic, values don't exist on their own; instead, values are either *to consume* or *to produce*, with a polarity.
17:37:57 <b_jonas> I'm surprised that boxes even come into this
17:38:24 <ais523> the regress has to bottom out somewhere, 0 and 1 may be fine if you're working entirely at the value level
17:38:35 <ais523> at least from Rust's point of view, you also have to deal with constructing/moving zero-sized types
17:38:53 <korvo> b_jonas: They naturally show up as dual values. If a value is a bump of earth in the desert, a box for that value is a hole in the desert. We can receive a value into a box, we can dig a value out of a box and leave it empty, etc.
17:39:04 <ais523> but those are more part of the type system than they are part of a runtime semantics
17:41:51 <b_jonas> yes, the runtime rules are pretty chill about reading and writing zero-sized types.
17:43:42 <b_jonas> but they aren't really enough, we need to be able to read and write types that aren't zero-sized.
17:47:38 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171568&oldid=171566 * A() * (+0)
17:48:57 <ais523> b_jonas: this has actually frustated me a bit because I've been interested in making a typed asm with similar safety proofs to Rust
17:49:37 <ais523> but doing the safety proofs involves a lot of ZST manipulation, and while it's easy enough to add asm pseudo-instructions to read and write ZSTs so that you can use them in the type proof, actually modelling what a ZST is at runtime is much harder
17:50:12 <ais523> I *think* I have a working formalism in which they have infinitesimal rather than zero size (and non-ZSTs are made infinitesimally smaller to leave gaps to store the ZSTs in)
17:50:52 <ais523> but typical asms aren't designed to handle this sort of thing, and in particular it is hard to distinguish between two ZSTs at the same address
17:52:29 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171569&oldid=171568 * A() * (+90)
17:54:55 -!- Yayimhere has quit (Ping timeout: 272 seconds).
17:57:15 <korvo> I'm not sure whether I care about zero-sized values. In FdVect_Q, the smallest possible object is a singleton that still has to be passed around as a correctness token and (I think) cannot be erased.
17:57:38 <korvo> ZSTs are an instance of the phantom-type pattern, right? Or do they carry data at runtime too?
18:07:51 <ais523> in Rust they don't carry data at runtime
18:07:58 <ais523> they exist for type-level proof purposes
18:08:31 <ais523> in my typed-asm model they are capable of carrying provenance, which is needed to prove certain optimisations to be correct (i.e. you can't perform the optimisation without the ZST being present)
18:09:14 <ais523> so even though they still do nothing at runtime, they are needed to be able to do a correctness proof of the asm, which involves being able to (from the asm's point of view) read and write them
18:16:03 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171570&oldid=171569 * A() * (+318)
18:16:12 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
18:16:43 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171571&oldid=171570 * A() * (-1)
18:33:55 -!- tromp has joined.
18:35:13 <b_jonas> ais523: you could do that in your typed assembler model, but it would be incompatible with normal rust zero-sized types (not necessarily with provenance)
18:35:32 <ais523> b_jonas: yes, it wouldn't model unsafe uses of Rust ZSTs
18:35:52 <ais523> but, the typed asm would struggle to typecheck unsafe Rust anyway because the whole point is that it can't be typechecked…
18:36:04 -!- Yayimhere has joined.
18:36:15 <ais523> (the intention is to verify safety proofs post-compile, it's hard to produce a safety proof for unsafe code)
18:39:18 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171572&oldid=171571 * A() * (+529)
18:41:04 <Yayimhere> korvo: you mentioned this novel values and boxes model, care to elaborate? perhaps the name is self explanatory and im just too non versed in rust, but im interetsed
18:41:04 <Yayimhere> (if you wondering, I did look at you and ais's chat, but I didnt gain too much info, but it was enough to get me hooked)
18:42:06 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171573&oldid=171572 * A() * (+17)
18:42:58 <esolangs> [[I cannot understand that.]] https://esolangs.org/w/index.php?diff=171574&oldid=112448 * Mun Hammer * (+568) Added a compiler
18:47:15 <esolangs> [[]] https://esolangs.org/w/index.php?diff=171575&oldid=166489 * Yayimhere2(school) * (-445) /* >>= kinda */
18:47:30 <esolangs> [[]] https://esolangs.org/w/index.php?diff=171576&oldid=171575 * Yayimhere2(school) * (-123) /* commands and semantics */
18:48:19 -!- impomatic has quit (Quit: Ping timeout (120 seconds)).
18:52:23 -!- impomatic has joined.
18:52:40 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171577&oldid=171573 * A() * (+304)
18:53:42 <ais523> "box" has a specific meaning in Rust but I suspect korvo was using it differently (I'm not sure though)
18:55:02 <ais523> in current Rust, a Box is a memory allocation that contains a value (e.g. if I write «Box::<u64>::new(5)» then this corresponds to making a memory allocation that's big enough to hold an unsigned 64-bit integer and storing 5 in that allocation)
18:56:09 <ais523> although I think this is mixing together two concepts (that there is a memory allocation that belongs to the Box, and that the Box ensures the memory is holding a value while the Box exists and drops the value when the Box is dropped)
18:57:06 <ais523> most Rust users think that the important concept is the first one (the Box managing the allocation), but I think the second is more fundamental
18:57:41 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171578&oldid=171577 * A() * (+7)
19:03:19 <b_jonas> ais523: and there's a bit more of the first property, which is that the allocation can be identified by just the rust pointer to the contents of the box
19:04:09 <ais523> b_jonas: although that is true in current Rust, I'm not sure that it's inherent in a definition of Box or even guaranteed by the current Rust guarantees
19:04:35 <ais523> except inasmuch as a Box has the same representation as a pointer to its contents in FFI
19:05:30 <b_jonas> I don't know if it's guaranteed to have the same representation, but it can be losslessly converted to a pointer with the Box::into_raw function and back with the Box::from_raw function
19:06:41 <ais523> Rc's into_raw/from_raw used to change representation
19:07:05 <korvo> Yayimhere: Think of a row of light switches. On one hand, the light switches are in a position, and if we had eight switches then we could store a byte. That's a "value". We also have the light switches themselves! Those are a "box" which stores values.
19:07:12 <ais523> although recently the internals of Rc were changed so that it just stores the value that would be returned by into_raw rather than a pointer to the start of the allocation
19:07:28 <Yayimhere> korvo: yea that makes a lot of sense
19:07:41 <korvo> All of the rest of this is *linear logic*, the logic of how resources move through a system when they can't be created or destroyed. If we flip the light switches then we are reconfiguring the system without creating or destroying.
19:07:57 <Yayimhere> thats actually interesting to think about as a "mechanic" of a language.
19:08:08 <korvo> The reason I'm imagining this is because a stick of RAM has several billion microscopic light switches, mostly.
19:09:07 <Yayimhere> but thinking of these "boxes" as a mechanic, a thing you can modify is interesting
19:09:56 <ais523> Yayimhere: extremely interesting, I think it's the biggest unsolved problem in systems programming
19:09:58 <korvo> Yeah. To connect with what ais523 is saying, imagine *allocating* some RAM. We're saying that, out of the existing box of billions of switches, we want to choose a few hundred specific switches. A smaller box that is part of a larger box.
19:10:54 <ais523> Yayimhere: no – C and C++ and Rust are all struggling with the idea of when memory is just memory versus when memory is a box with defined behaviour
19:11:19 <ais523> if I have a box with eight switches in it, and flip the sixteenth switch, I am changing values outside the box
19:11:44 <ais523> trying to define when that's allowed/disallowed and when that even makes sense is very difficult
19:12:22 <ais523> but systems programming languages have a sort of dual view of memory, one view as just this continuous sequence of switches that you can move around as you like, and one as a set of nested boxes
19:12:32 <b_jonas> ais523: is the question whether overwriting the contents of a box like `*abox = value` can change the addres where the box is pointing to?
19:12:36 <ais523> and trying to reconcile these views is really difficult
19:13:06 <ais523> b_jonas: no, it's about when doing `box[offset] = value` is legal
19:13:09 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171579&oldid=171578 * A() * (+244)
19:13:39 <b_jonas> is that for like a boxed slice or boxed array?
19:13:54 <ais523> in most languages this is undefined behaviour if the offset goes outside the box, *but* that means you have to define what the box actually is
19:13:57 <Yayimhere> well, I guess ill be thinking about that for a while
19:13:58 <korvo> Oh yeah, in systems programming, we have values which *refer* to the locations of boxes. We have words like "referrer", "referent", and "reference". It's awful and I wish that there were a better way.
19:14:16 <ais523> b_jonas: boxed slice is a good way to think about it in Rust terms, but I meant the example to extend to C as well
19:15:55 <ais523> korvo: Rust has been trying to standardise terminology on "address" = where in memory the location is (independent of any rules for accessing it), "pointer" = address + provenance, "reference" = address + provenance + proof of access safety
19:16:21 <ais523> but it probably won't catch on in other languages
19:16:36 <b_jonas> I don't understand this `box[offset] = value` thing. if it's not a slice/array in the box then why could it work?
19:16:42 <ais523> (also I think there are actually four components rather than three)
19:17:00 <ais523> b_jonas: well, suppose you're using a model where you haven't defined what the box is
19:17:06 <int-e> b_jonas: it's a bit lower level than that so it includes accessing struct fields etc
19:17:20 -!- slavfox has quit (Ping timeout: 240 seconds).
19:17:27 <ais523> box[1] = 2 will write to the memory address after *box – how is a compiler going to prove that you can't do that, without defining what a box is first?
19:17:53 <korvo> b_jonas: Well, check this out. This is where my mind is currently struggling. Where's `value` come from? A register? How can we have values without boxes?
19:18:07 <b_jonas> why would the compiler have to prove that you can't do that, if you can only write it in unsafe code?
19:18:12 <ais523> re: four components: address, allocation, provenance, proof of access safety
19:18:24 <korvo> I think that if values and boxes are dual then it doesn't make sense to talk about a bare value or bare box. They're always connected via duality.
19:18:25 <ais523> b_jonas: because otherwise most optimisations aren't legal
19:18:26 <b_jonas> is it to eg. optimize an array access so it can assume the index is 0?
19:19:05 <b_jonas> I'm not sure the compiler is allowed such optimizations with rust Box currently
19:19:11 <ais523> you want to be able to prove that a write to one address can't overwrite unrelated addresses, but then you have to define "unrelated"
19:19:45 <ais523> the compiler is definitely allowed such optimizations with current Rust Box, it has (for accidental historical reasons) some of the strongest requirements of any type on using it unsafely
19:19:45 <b_jonas> even if the contents isn't zero-sized
19:20:37 <ais523> if you pass a Box to a function, the compiler can and does optimise on the basis that any reads/writes to the memory backing the Box must be through the Box, and any reads/writes through the Box must be to the memory backing it
19:21:27 <b_jonas> oh, *that* it can certainly optimize
19:21:39 <ais523> these requirements apply even to unsafe code, which causes problems sometimes because it's somewhat easy to violate them accidentally (e.g. by unsafely copying the box and then doing things through the copy)
19:21:49 <b_jonas> the box behaves like it has a mut reference to its contents
19:22:04 <int-e> this could become quite the volatile discussion and the keyword hasn't even been mentioned :P
19:22:18 <ais523> I would clarify that to "the box behaves like it has a mut reference to *the memory containing* its contents"
19:22:18 <b_jonas> so same requirements as with any mut reference
19:23:03 <ais523> int-e: this is because there's a consensus that (except in Java) volatile doesn't actually do anything from the allowing-otherwise-unsafe-code point of view, what would be UB without volatile is still UB even with volatile
19:23:55 <int-e> ais523: Yeah that would obviously be more about memory-mapped IO angle. But I'm pathologically attracted to puns.
19:24:20 <int-e> (going all the way back to the little light switches)
19:25:08 <ais523> my main use for volatile is for creating variables that can safely be written using a debugger
19:26:24 <ais523> (I use this for variables that request extra debug information to be printed, and use a debugger to turn the option to print it on)
19:29:56 <int-e> Hmm. Semi-relatedly, I *guess* /proc/self/mem can't be mmap-ped because of https://xkcd.com/878/
19:30:08 <korvo> ais523: Oh! I remember my issue now. I'm not sure if there's NNOs in the relevant categories. I think that FdVect_C (or _R I guess) can encode counting as a linear transformation like "multiply by 2" and the composite map is a logarithm, base 2, but I didn't work out whether it's correct.
19:30:20 <int-e> (I was reminded of https://docs.rs/totally-safe-transmute/latest/totally_safe_transmute/fn.totally_safe_transmute.html )
19:30:23 <ais523> what does NNO stand for here?
19:30:32 <korvo> And I was thinking that maybe the inability of linear logic to count is something deep.
19:31:16 <korvo> Oh, sorry. Natural Numbers Object. An object that behaves like N in Set. For every diagram 1 -> X -> X, there's a diagram made from zero : 1 -> N and succ : N -> N which can "count" in X.
19:31:37 -!- Yayimhere has quit (Quit: Client closed).
19:32:00 -!- Yayimhere has joined.
19:32:02 <ais523> well, practical programming languages usually don't have one of those in their semantics, because they don't expect to be able to store actually unlimited numbers
19:32:27 <korvo> Python does, but I get what you mean. Cammy's not practical, for example.
19:32:40 <ais523> although, one proposal I had for Rust would be numbers that can store bignums in finite size but are allowed to panic any time the number is out of the range that would be implied by the size
19:33:06 <ais523> from the operational semantics point of view, the high bits of the number are stored in the provenance
19:33:41 <ais523> the purpose of this would be to make it legal to optimize "x.increment_reference_count(); x.decrement_reference_count()" into a no-op
19:34:02 <ais523> (currently this optimization is not legal as the program semantically is supposed to panic on reference count overflow)
19:35:02 <ais523> int-e: /proc/self/mem not only can be memory mapped, IIRC it's designed to be – the trick is to mmap only a subset of it rather than the whole thing
19:35:37 <ais523> I'm not sure what happens if you map it in a way that the map contains part of itself at a slight offset, though
19:36:01 -!- Lord_of_Life has quit (Ping timeout: 264 seconds).
19:36:57 -!- Lord_of_Life has joined.
19:38:29 <korvo> Hall of mirrors, but with pointers.
19:40:37 <ais523> man proc_pid_mem doesn't help explain what happens in this situation (it's one of the shortest manpages I've ever seen)
19:40:45 <korvo> ...English WP deleted their hall-of-mirrors article. This one is pretty good: https://www.thealmightyguru.com/Wiki/index.php?title=Hall_of_mirrors_effect
19:41:07 <ais523> so finding out would require either checking kernel source or experimenting
19:41:58 <ais523> korvo: oh, I thought you were referencing an actual hall of mirrors (which can contain mirrors that reflect each other) rather than the rendering issue
19:42:22 <korvo> ais523: I'm thinking of them as all having the same underlying issue: some sort of spatiotemporal aliasing.
19:42:50 <ais523> the rendering issue is different because it's affected by the way that the camera has historically moved
19:42:56 <korvo> The aliasing causes a deference/bounce to point at the "wrong" target because something else has been mapped/interspersed in the way.
19:43:08 <korvo> Right, the visual effect is temporal aliasing.
19:43:30 <ais523> or a good way to think about it is that when rendering, the undefined areas hold pixels from a *previous* rendering, but if you mmap /proc/self/mem at an offset, it logically contains bytes from its own *current* value
19:44:01 <ais523> thus causing memory addresses separated by a multiple of the offset size to become aliases for each other
19:44:38 <korvo> I can't find any good examples offhand, but e.g. Super Mario 64 has spatiotemporal halls of mirrors due to how it rasterizes; when looking through an untextured/missing polygon it's possible to get a valid texel from a wrong texture rather than an invalid texel.
19:45:00 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171580&oldid=171579 * A() * (-1259)
19:45:19 <int-e> ais523: nope: https://elixir.bootlin.com/linux/v5.19.17/source/fs/proc/base.c#L928-L934 and contrast that with https://elixir.bootlin.com/linux/v5.19.17/source/drivers/char/mem.c#L647-L657 for /dev/mem (whose mmap is free of circularity because it creates virtual -> physical mappings)
19:45:22 <korvo> This normally can't happen on today's GPUs because of texture binding; each draw call is always done with the correct textures.
19:46:43 <ais523> korvo: isn't it effectively the equivalent of reading out-of-bounds texels? maybe not the same mechanic, but the same end result
19:46:58 <ais523> I suspect that could happen even nowadays because I doubt GPUs are doing bounds checks
19:47:06 <int-e> not sure why I'm looking at 5.x instead of 6.x
19:47:46 <korvo> ais523: I realize that I might be a little physics-brained about this. An IRL hall of mirrors, *under special relativity*, isn't instantaneous. I imagine that the kernel's page-management algorithm isn't deterministic, so that self-inspection of the memory map could interfere with mutation.
19:48:26 <ais523> korvo: hmm, I was thinking about golfing languages, which often go out of their way to do exactly what you asked for even when it's inconsistent with other uses of the same operation
19:48:31 <korvo> ais523: It's more like reading the texel that would have been correct, *if* the polygon had been textured a certain way; but it had no texture at all, so there's not really any correct color value.
19:48:54 <ais523> "make a[0..4] an alias for a[1..5]" is physically possible to do, although I didn't expect the kernel to actually implement it
19:49:12 <int-e> But it hasn't changed: https://elixir.bootlin.com/linux/v6.18.2/source/fs/proc/base.c#L992-L999 and https://elixir.bootlin.com/linux/v6.18.2/source/drivers/char/mem.c#L631-L642
19:49:49 <int-e> (apart from a new .fop_flags field that is irrelevant)
19:51:44 <b_jonas> ais523: doesn't mmapping /proc/$pid/mem already have to handle what to do if the mapping for the addresses that it's aliasing is changed?
19:52:04 <ais523> b_jonas: as int-e points out, it isn't actually allowed, but I guess it would
19:53:02 <int-e> ais523: so technically the manpage does help but you have to recognize that the given list of operations is exhaustive
19:53:06 <korvo> ais523: For Super Mario 64 and friends, it's because the N64 didn't have a full hardware TCL (Transform, Clipping, Lighting IIRC?) pipeline with "texture combiners" or what we now call shaders. Today, the GPU usually won't even consider a "fragment", a pixel prepared for coloring and lighting, unless it came from the hardware rasterizer. The sort of thing that is fixed by better architecture.
19:53:50 <int-e> anyway. happy I confirmed my theory :)
19:54:02 <int-e> or guess, I suppose
19:54:09 <ais523> korvo: well, I'm thinking along these lines: a very simple pixel shader just indexes into the memory holding the texture – but if that doesn't do a bounds check it might index out of bounds of the texture
19:55:54 <sorear> I'm scared enough of the lifetime management and locking for vm_area structs as they are, recursive would be so much worse
19:56:57 <korvo> ais523: Yeah. To make another tangent, it's like how each mmap comes with size and flags; the textures are always laid out in memory prior to rendering, and the process of laying it out, decompression, mip-mapping, etc. validates the bounds.
19:57:21 <int-e> sorear: And all that trouble would hardly serve any purpose.
19:57:54 <int-e> (snapshotting process memory without forking (cloning with CLONE_VM) would be nice I guess)
19:57:57 <ais523> korvo: the thing I'm unsure about is mostly as to whether that's a hardware feature of the GPU or whether that's just a thing that's commonly enforced in GPU software/drivers
19:58:35 <korvo> Hm. Texels are typed, there's a (FourCC) format, and texel access is always aligned. Even if it's OOB, I suppose, although OOB texel coordinates are hard to generate today.
19:59:29 <korvo> ais523: It's usually a hardware feature for discrete GPU boards that communicate over PCIe, but wholly in software for hybrid cores or APUs. It was only in hardware when it had to be.
19:59:34 <ais523> well, u/v coordinates noramlly wrap in practice
19:59:46 <ais523> I'm not sure whether they actually *have* to, but it's useful that they do
20:01:23 <korvo> But also, as soon as render-to-framebuffer came out, there was a big push to add fences to GPU drawing commands. Everybody wanted the result of intermediate draw calls to be well-defined; if I draw a scene to a texture then I want that first draw to finish before the texture's bound for the second draw.
20:01:42 <korvo> That's another good example. Or Z coordinates being auto-scaled when read from hardware Z buffer.
20:02:18 <korvo> BTW I'm hoping that my knowledge of GPU drivers here is helping to generate insights. I'm not trying to argue or to get anyplace specific.
20:03:16 <ais523> I was formally taught GPU programming twice, from two different points of view, but oddly textures weren't involved either time (or involved only very marginally)
20:03:24 <korvo> Like, if I have some weird way that my process's memory is bound, maybe like part of my memory is exported to Somebody Else's MMap, then both of our processes probably want some serialization for how I mutate vs how they read.
20:04:16 <korvo> Or e.g. SysV message queues have a similar sort of problem. On classic USA post/mail boxes, there's a little red flag that can be raised to indicate the presence of mail; there's no associated software mailbox for SysV MQ.
20:04:59 <ais523> <korvo> Like, if I have some weird way that my process's memory is bound, maybe like part of my memory is exported to Somebody Else's MMap, then both of our processes probably want some serialization for how I mutate vs how they read. ← I believe this is a currently unsolved problem, i.e. both runtimes and languages leave it up to the individual programs to come to an agreement and don't try to define what happens if they don't
20:05:08 <korvo> ais523: Oh, nice! I wasn't formally taught anything. I helped write some AMD/ATI drivers because I had bought a laptop and wanted to play some video games. Then I learned formal raytracing and decided that GPU drivers were not a fun career.
20:05:40 <ais523> the first time was a really old version of OpenGL, back when it was fixed-pipeline; the second time was CUDA
20:06:06 <korvo> Yes! I remember when Go came out. There was enormous noise about a CSP principle, "don't communicate by sharing memory; share memory by communicating." Lovely in principle but no idea how to actually glue that to POSIX.
20:06:37 <ais523> well, the POSIX non-shared-memory communication primitive is the pipe
20:08:40 <korvo> Yeah. If we go down that route, I'm basically 100% with Kell and Jakubovic on this; the process isn't the right unit of isolation for talking about a persistent object. You need something like a directory, which is really just a name that can hold multiple FIFOs.
20:08:44 <ais523> I've actually considered trying to come up with something that is to a pipe as a futex is to a mutex, i.e. it interoperates correctly cross-process and the kernel can be involved if necessary, but the common case works even with no context switches
20:08:47 <b_jonas> ais523: I thought it was PF_UNIX family sockets
20:08:58 <ais523> b_jonas: maybe, the two are extremely similar
20:09:05 <korvo> I think that there's no coincidence in e.g. s6's concept of "fifodir", where a directory of FIFOs is a central abstraction.
20:09:20 <int-e> but unix domain sockets add ancillary data
20:09:21 <b_jonas> pipes are what you use on Win32 as a poor man's replacement
20:09:55 * int-e remembers how DOS implemented "pipes"
20:11:13 <ais523> int-e: does it just run the programs one at a time, using a temporary file instead of a pipe?
20:12:14 <ais523> I remember porting a program I'd written from SunOS to Linux, the only change I needed to make was to fix one of my pipe system calls
20:12:38 <ais523> because I'd accidentally swapped the two ends of the pipe, apparently they're bidirectional on SunOS and unidirectional on Linux
20:13:08 <ais523> but this makes me wonder whether, if you do a | b on SunOS, the programs can communicate bidirectionally by writing stdin/reading stdout to do the reverse direction communication
20:13:31 <Yayimhere> hey peeps, could I perhaps employ your help in naming an esolang I have created? I know it is not the most
20:13:46 <sorear> someone decided that pipe was redundant with socketpair?
20:14:44 <b_jonas> ais523: bidirectional in what way? writing on either side writes to the same buffer, or in two separate buffers that can be read only from the other pipe handle?
20:16:20 <sorear> you need to be able to detect when all possible write handles have been closed so the reads will EOF
20:17:01 <ais523> b_jonas: I actually don't know, I never tried anything that would distinguish
20:17:10 <ais523> because I was mostly interested in getting the software working
20:18:00 -!- slavfox has joined.
20:21:00 <int-e> bah, the "OpenGL ES 3.2 Reference Pages" link on https://www.khronos.org/opengles/ is broken
20:21:47 <int-e> https://registry.khronos.org/OpenGL-Refpages/es3/ works
20:22:02 -!- DOS_User_webchat has joined.
20:23:42 <korvo> Yayimhere: What's up?
20:25:05 <zzo38> About memory sharing, I had a idea that I had mentioned before; only a read-only mapping can be shared; if you transfer a writable mapping then you will lose access to it (although you can change the access to read-only in order to make it shareable, you cannot then change it back to writable unless you ask someone for a memory allocation and tell the system to use the existing memory; the system will optimize it if possible)
20:27:13 <Yayimhere> korvo: assuming your talking about the language, its a string rewriting language where the only operation is based on overlapping (as in, when doing the only available operation, it chooses two substrings, but then the next substrings chosen, the last choice of the first operation will be the first of the second operation)
20:28:08 <korvo> Yayimhere: What motivated you to create it?
20:28:59 <korvo> zzo38: Have you read ais523's pirate post? http://ais523.me.uk/blog/logic-of-shared-references.html
20:29:49 <korvo> It sounds like you're thinking about the same problem. How can "the system" know whether a reference has been shared, and what does it actually have to track at runtime?
20:30:03 <Yayimhere> ok, so, ais523 had created a similar language, but in which that same thing happened in the programs reading instead of the strings
20:30:05 <zzo38> I had read it but I will read it again because I do not remember.
20:30:31 <Yayimhere> I go inspired by it slightly, and then later thought about bracketed expressions in which brackets arent nested, but next to each other
20:30:56 <Yayimhere> and then I wondered how to make a string written like that be able to interact without two brackets next to each other functioning as just one string
20:31:23 <zzo38> The kernel would know if a reference is shared because the kernel keeps track of the processes in the system, I think. (So, mine is at a level of the operating system rather than the level of the programming language)
20:32:24 <korvo> zzo38: Makes sense. I think seL4 does that sort of thing since all memory allocation is in the kernel, but I don't remember details.
20:32:32 <korvo> Yayimhere: No worries. Take it easy.
20:32:56 <b_jonas> but anyway, besides PF_UNIX sockets (including both ones created by socketpair and ones created by socket), posix also has message queues with the mq_open and similar functions https://man7.org/linux/man-pages/man7/mq_overview.7.html , as well as semaphores and shared memory, which are apparently made to replace the less flexible old SYSV message queue / semaphore / shared memory interfaces
20:34:00 <korvo> b_jonas: Yes. POSIX MQ is much nicer despite having nearly the same API.
20:37:12 <b_jonas> to be honest I don't understand what the use of message queue is these days, except for historical compatibility
20:39:35 -!- Yayimhere has quit (Ping timeout: 272 seconds).
20:47:04 <korvo> b_jonas: On their own, they kind of suck because of the mailbox problem I mentioned above. However, on Linux and a few other kernels, we can poll() or select() MQ descriptors as ordinary FDs. So, let's imagine a tree of processes that are doing some best-effort monitoring or computation. They each are reporting their current/intermediate results to a central integrator.
20:48:23 <korvo> Each reporter can put its results in an MQ. The integrator can select() on the MQs to figure out which reporters have updated. The integrator can mutate the MQ to talk to the reporter, with the understanding that not every command will be delivered due to races.
20:49:56 <korvo> The entire point is, quoting that man page, "if not removed by mq_unlink(), a message queue will exist until the system is shut down." So the integrator and reporters can both be restarted or upgraded in place, hot-swapping, without affecting the integrity of the tree.
20:50:52 <korvo> And MQs are subject to IPC namespacing on Linux, so it's possible to have *private* MQs that can't be inspected or attacked by anybody else. You don't have to do like s6 and park a fifodir where superusers can touch it.
20:52:21 <sorear> Why is CAP_DAC_OVERRIDE inherently more concerning than CAP_SYS_PTRACE?
20:54:30 -!- DOS_User_webchat has quit (Remote host closed the connection).
20:55:09 <korvo> Oo, I haven't heard this one. Why is DAC_OVERRIDE more concerning than SYS_PTRACE?
20:55:40 <int-e> they sound more or less equivalent to me, damage wise
20:56:06 <sorear> I don't know, I'm asking you. "superusers" can inspect or attack anything that happens by processes making syscalls, because they can inject syscalls into any process
20:57:21 <int-e> (ptrace will be more effort)
20:57:25 <zzo38> I don't really like that they had to put everything into namespaces like that; my own system design does not have any namespaces (and does not have file names).
20:58:57 <zzo38> Having global namespaces will have problems in my opinion; however, a program can implement a namespace if it is useful for that program, and can allow other programs to access it
21:02:53 <b_jonas> korvo: you can create PF_UNIX sockets on the file system, in which case on linux you can only access them through the controlling directory, so the permissions and file system namespacing of the directory can restrict it.
21:03:36 <b_jonas> but the other partthat you said may be an advantage of message queues
21:04:50 <zzo38> Creating unix sockets (and other stuff) in the file system is sometimes useful (even though a single global name space has some problems in my opinion), and my own "scorpiond" program takes advantage of this as an alternative of CGI programs (which has some advantages over CGI programs).
21:07:31 -!- impomatic has quit (Quit: Client closed).
21:11:34 <zzo38> About ais523's article: "T&T is equivalent to just a single T (it's an object that can be consumed as either a T or a T and the choice doesn't matter)" Does it doesn't matter, or could there be multiple views of the same type? (Rust and other programming languages might not be able to do that, but I mean theoretically)
21:13:06 <ais523> sorear: my understanding is that there are quite a few capabilities that are able, via one means or another, to break down security barriers in a way that makes anything possible; I suspect that both DAC override and ptrace are able to do that
21:13:23 <korvo> b_jonas: Yeah, that's definitely worth doing as well. I think that a good capability system for Unix will have all of these fine-grained defenses as part of a multi-layered strategy.
21:13:44 <korvo> sorear: Oh, I was ready to learn a new joke. I guess that Linux capabilities are an old joke!
21:14:05 <sorear> what sucks is that the interesting properties are all emergent. DAC_OVERRIDE hurts much more if you have or can mount a procfs; SYS_PTRACE is pretty harmless if everyone has their own pidns
21:14:48 <korvo> I was recently saying that Linux caps should be thought of as a *bitset* of flags; root has the full bitset, most users have the empty bitset, and there's ways to incrementally alter it. A Linux process may be *partially* root. https://lobste.rs/s/vp1zbg/tier_list_linux_security_mechanisms_2024#c_hbtrtq
21:16:02 <korvo> It does suck that Linux has almost no path towards deprecating some of the older caps. I think it's worth doing what Wayland did instead, with hosting Xorg servers as a Wayland client. I recently was looking at L4Linux to see if Linux-on-L4 is still an easy thing.
21:16:24 <zzo38> I think that isn't the best security mechanism, although having read the man page I would also have thought of working like bitsets (although these capabilities are too coarse for many uses).
21:19:25 -!- somefan has joined.
21:21:20 <esolangs> [[Talk:CLC-INTERCAL]] https://esolangs.org/w/index.php?diff=171581&oldid=122864 * Tpaefawzen * (+188) /* Author is gone again! (2025-12) */ new section
21:29:40 -!- ursa-major has quit (Ping timeout: 246 seconds).
21:31:35 -!- dcreager has quit (Ping timeout: 245 seconds).
21:32:00 -!- ManDeJan has quit (Ping timeout: 245 seconds).
21:34:27 -!- dcreager has joined.
21:34:28 -!- ManDeJan has joined.
21:34:54 -!- ursa-major has joined.
21:53:20 <ais523> zzo38: hmm, I guess you can imagine an object that can be viewed as a T in two different ways, but then you run into the question of what aspect of the programming language the type theory is trying to model
21:54:48 <ais523> Rust specifically solves this problem by treating a particular way in which an object can be viewed as having a type as being a type in its own right, e.g. u32 is an unsigned 32-bit integer type where >= is a greater-than-or-equals operation, and Reverse<u32> is an unsigned 32-bit integer type where >= is a less-than-or-equals operation
21:55:08 <ais523> u32 can be viewed as being an Ord in (at least) two different ways, but Rust gives the two views different names
21:57:52 <zzo38> OK, that makes sense. Rust is not a programming language that I am very familiar with, but I have some familiarity with Haskell and a similar thing can be done with implementing a class differently by making it a different type (because e.g. there are many monoids that can be made from a type, including reversing the existing one)
22:49:19 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
22:58:14 <esolangs> [[Language list]] M https://esolangs.org/w/index.php?diff=171582&oldid=171563 * Buckets * (+12) /* Q */
22:58:18 -!- Sgeo has joined.
22:58:52 <esolangs> [[User:Buckets]] M https://esolangs.org/w/index.php?diff=171583&oldid=171522 * Buckets * (+11)
22:59:10 <esolangs> [[Quate]] N https://esolangs.org/w/index.php?oldid=171584 * Buckets * (+1092) Created page with "Quate is an Esoteric Programming language created by [[User:Buckets]] In 2021. {| class="wikitable" |- ! Commands !! Instructions |- | * || Push third Top value * -2. |- | ! || Goto Coordinates 0, 0. |- | < || If the Second Top value has A negative Or Positive sign, Copy
23:02:18 <esolangs> [[EtomemoteetomemoteetomemoteetomemotE]] https://esolangs.org/w/index.php?diff=171585&oldid=171580 * A() * (+3020)
23:03:32 <esolangs> [[Hello world program in esoteric languages (D-G)]] https://esolangs.org/w/index.php?diff=171586&oldid=171567 * A() * (+1555) /* EtomemoteetomemoteetomemoteetomemotE */
23:05:27 -!- somefan has quit (Quit: Client closed).