00:03:52 -!- mtm has quit (Ping timeout: 252 seconds). 00:07:01 -!- mtm has joined. 00:29:02 hot take: a memory-safe compiler must maintain memory safety while applying optimizations. in fact, it must maintain memory safety up until writing the opcodes to disk. 00:29:15 no modern compiler does this, so no modern compiler can be said to be memory-safe 00:29:41 thus, there is no memory-safe way to use memory-safe programming languages 00:29:51 isn't that fun :D 00:34:06 Plenty of compilers are memory-safe, but I get the point. 00:34:21 Does Ada work? 00:54:22 [[List of ideas]] https://esolangs.org/w/index.php?diff=147332&oldid=146856 * Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff * (+81) /* Partially Silly Ideas */ 00:55:23 Soni: Another option is to look at this as an opportunity: what kinds of engineering difficulties arise when building a memory-safe compiler? 00:56:07 if the assembler isn't memory-safe, what's the point of claiming memory safety 00:57:13 or maybe we just have beef with the rust guys (yes, guys. it's always guys) and we want to make them look bad ^^ 00:58:36 (tbh we don't need to make up stuff about memory safety - we can just point out that they're, frankly, kinda violently against affirmative action - but we digress) 01:01:49 Who said Rust was the only memory-safe language? 01:35:20 [[User:Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff/Iota thing]] N https://esolangs.org/w/index.php?oldid=147333 * Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff * (+6698) Created page with "
 **i*i*ii***i*i*i*ii***i*i*i*ii***i*i*i*ii*i*i*ii*i*i*ii**i*i*ii***i*i* i*ii**i*i*ii****i*i*i*ii***i*i*i*ii*i*i*ii*i*i*ii***i*i*i
01:41:00 -!- amby has quit (Remote host closed the connection).
01:45:31 -!- Everything has quit (Quit: leaving).
02:18:54  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147334&oldid=147319 * MihaiEso * (+35) 
02:31:24  [[User talk:Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff]]  https://esolangs.org/w/index.php?diff=147335&oldid=147008 * Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff * (+90) /*  */ new section
02:31:39  [[User talk:Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff]]  https://esolangs.org/w/index.php?diff=147336&oldid=147335 * Fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff * (+2) /*  */
02:47:19 -!- molson_ has joined.
02:51:21 -!- molson has quit (Ping timeout: 252 seconds).
02:59:46 -!- molson_ has quit (Remote host closed the connection).
03:02:39 -!- molson has joined.
04:20:31 -!- ramiro__ has quit (Ping timeout: 264 seconds).
04:43:19  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147337&oldid=147334 * Ractangle * (-35) oh no you don't
05:12:48  cyskus.mol: points 3.07, score 23.52, rank 15/47
06:02:22 -!- Hooloovoo has quit (Quit: ZNC 1.8.2+deb2+deb11u1 - https://znc.in).
06:04:00 -!- Hooloovoo has joined.
06:04:35 -!- user3456 has quit (Quit: I use ZNC - https://znc.in).
06:23:03 -!- user3456 has joined.
06:30:37 -!- Sgeo has quit (Read error: Connection reset by peer).
06:52:13 -!- craigo has joined.
07:57:11 -!- tromp has joined.
08:51:56  [[Brainfuck for humans]]  https://esolangs.org/w/index.php?diff=147338&oldid=144430 * LillyHStClaire * (+676) Add a hello world example
09:20:12 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
09:42:19  [[User:H. H. P. M. P. Cole]] M https://esolangs.org/w/index.php?diff=147339&oldid=143020 * H. H. P. M. P. Cole * (+46) 
09:43:20  [[User talk:H. H. P. M. P. Cole]] M https://esolangs.org/w/index.php?diff=147340&oldid=145254 * H. H. P. M. P. Cole * (+263) 
09:46:09  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147341&oldid=143081 * H. H. P. M. P. Cole * (-1522) Bringing the alphabet down to 4 characters! Will work on syntax later.
09:48:12  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147342&oldid=147341 * H. H. P. M. P. Cole * (+242) 
09:48:30  [[User:H. H. P. M. P. Cole]] M https://esolangs.org/w/index.php?diff=147343&oldid=147339 * H. H. P. M. P. Cole * (-46) 
09:48:55  [[User:H. H. P. M. P. Cole]] M https://esolangs.org/w/index.php?diff=147344&oldid=147343 * H. H. P. M. P. Cole * (+74) 
09:52:44  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147345&oldid=147342 * H. H. P. M. P. Cole * (+35) 
09:52:56  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147346&oldid=147345 * H. H. P. M. P. Cole * (+12) 
09:53:27  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147347&oldid=147346 * H. H. P. M. P. Cole * (+27) 
09:57:33  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147348&oldid=147347 * H. H. P. M. P. Cole * (+63) 
09:58:41  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147349&oldid=147348 * H. H. P. M. P. Cole * (+80) /* Syntax */
10:10:31  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147350&oldid=147349 * H. H. P. M. P. Cole * (+4) /* Syntax */
10:20:01 -!- amby has joined.
10:31:40 -!- tromp has joined.
10:34:11 -!- craigo has quit (Remote host closed the connection).
10:34:53 -!- craigo has joined.
11:18:50  [[Esolang:Sandbox]]  https://esolangs.org/w/index.php?diff=147351&oldid=146796 * Artyxa * (+20) /* Tests */
11:19:33  [[Esolang:Sandbox]] M https://esolangs.org/w/index.php?diff=147352&oldid=147351 * Artyxa * (-8) /* Tests */
11:28:25 -!- wib_jonas has joined.
11:49:54  [[Fish]]  https://esolangs.org/w/index.php?diff=147353&oldid=147313 * Ractangle * (+73) /* Cat Program */
11:52:58  [[Esolang:Sandbox]]  https://esolangs.org/w/index.php?diff=147354&oldid=147352 * Ractangle * (-12) tify
11:54:21  [[Fish]]  https://esolangs.org/w/index.php?diff=147355&oldid=147353 * Ractangle * (-5) /* Hello, world! */
12:03:00 -!- mtm has quit (Ping timeout: 252 seconds).
12:05:30 -!- mtm has joined.
12:14:45  [[User:Iddi01]]  https://esolangs.org/w/index.php?diff=147356&oldid=145476 * Iddi01 * (+2257) [[brainfUck|Removed decoration since it has an impact on the function of this page]]
12:21:25 -!- __monty__ has joined.
12:24:26 -!- SGautam has joined.
12:41:19  [[Semi-serious language list]] M https://esolangs.org/w/index.php?diff=147357&oldid=144067 * Iddi01 * (+141) [[Redcode|This list is incomplete without t h e. u l t i m a t e. p r o g r a m m i n g. g a m e.]]
12:45:00  [[User:H. H. P. M. P. Cole/Modulo 2]] M https://esolangs.org/w/index.php?diff=147358&oldid=147350 * H. H. P. M. P. Cole * (-329) 
12:51:43  [[List of ideas]] M https://esolangs.org/w/index.php?diff=147359&oldid=147332 * Iddi01 * (+158) /* Joke/Silly Ideas */ Combining [[brainfUck]] (not [[bf]]!) with [[Redcode]], how crazy will that be, even though they are both [[:Category:Programming games|Programming games]]
13:26:34  [[User talk:Tommyaweosme]]  https://esolangs.org/w/index.php?diff=147360&oldid=147309 * PrySigneToFry * (+655) 
13:29:35  [[User talk:ZCX islptng]]  https://esolangs.org/w/index.php?diff=147361&oldid=147158 * PrySigneToFry * (+627) 
13:31:35  [[User talk:None1]]  https://esolangs.org/w/index.php?diff=147362&oldid=147231 * PrySigneToFry * (+688) /* Wasaya */ new section
13:36:27 -!- wib_jonas has quit (Ping timeout: 256 seconds).
13:39:57  [[Poetic (esolang)]]  https://esolangs.org/w/index.php?diff=147363&oldid=138087 * PrySigneToFry * (+356) 
13:55:01  [[Talk:Deadfish]]  https://esolangs.org/w/index.php?diff=147364&oldid=147326 * None1 * (+261) /* A quine */
14:07:50  [[Pete mort+]] N https://esolangs.org/w/index.php?oldid=147365 * None1 * (+1364) Created page with "'''Pete mort+''' (Romanian for Dead fish) is an esolang invented by [[User:None1]]. It is a [[deadfish]] derivative and an extension [[Pete mort]].  It can print ASCII characters. ==Commands== {| class="wikitable" |- ! Command !! Corresponding Romanian word !! Meaning 
14:07:56  [[Fish]]  https://esolangs.org/w/index.php?diff=147366&oldid=147355 * BrainFuckGirl * (-95) /* Hello, world! */ removed non-functional code
14:08:11  [[Pete mort+]] M https://esolangs.org/w/index.php?diff=147367&oldid=147365 * None1 * (+3) 
14:08:27  [[Pete mort+]] M https://esolangs.org/w/index.php?diff=147368&oldid=147367 * None1 * (+1) 
14:13:39  [[Pete mort+]] M https://esolangs.org/w/index.php?diff=147369&oldid=147368 * None1 * (+14) Fix hello world
14:17:36  [[Fish]]  https://esolangs.org/w/index.php?diff=147370&oldid=147366 * BrainFuckGirl * (-307) /* Cat Program */ reduced section because it became to large
14:19:15  [[Joke language list]]  https://esolangs.org/w/index.php?diff=147371&oldid=147098 * None1 * (+50) /* General languages */
14:20:00  [[User:None1]]  https://esolangs.org/w/index.php?diff=147372&oldid=146232 * None1 * (+50) /* My Esolangs */
14:21:06  [[Peste mort+]] N https://esolangs.org/w/index.php?oldid=147373 * None1 * (+26) Redirected page to [[Pete mort+]]
14:27:06  [[Wasaya]]  https://esolangs.org/w/index.php?diff=147374&oldid=147191 * None1 * (+45) /* Examples */
14:28:41  [[User talk:None1]]  https://esolangs.org/w/index.php?diff=147375&oldid=147362 * None1 * (+273) /* Wasaya */
14:31:25 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
14:31:32  [[User talk:Ractangle]]  https://esolangs.org/w/index.php?diff=147376&oldid=147118 * BrainFuckGirl * (+843) Talk about Fish
14:34:18  [[User:]]  https://esolangs.org/w/index.php?diff=147377&oldid=146146 *  * (+73) 
14:34:55 -!- tromp has joined.
14:48:23  [[User talk:BrainFuckGirl]] N https://esolangs.org/w/index.php?oldid=147378 * BrainFuckGirl * (+0) Created blank page
14:54:43  [[Propositio]] N https://esolangs.org/w/index.php?oldid=147379 *  * (+625) Started page
14:59:35  [[Propositio]]  https://esolangs.org/w/index.php?diff=147380&oldid=147379 *  * (+341) 
15:01:19  [[User talk:]] M https://esolangs.org/w/index.php?diff=147381&oldid=147262 *  * (+19) 
15:07:45  [[User talk:]]  https://esolangs.org/w/index.php?diff=147382&oldid=147381 *  * (+347) /* ULTRAESOLANG */ new section
15:18:09  [[WHAT]] N https://esolangs.org/w/index.php?oldid=147383 *  * (+633) Started page
15:47:24 -!- FreeFull has quit.
16:02:31 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
16:41:25  [[User talk:Tommyaweosme]]  https://esolangs.org/w/index.php?diff=147384&oldid=147360 * Ractangle * (+211) 
16:43:16  [[User talk:Ractangle]]  https://esolangs.org/w/index.php?diff=147385&oldid=147376 * Ractangle * (+177) /* Cat Programs in > */
16:44:46  [[Talk:Deadfish]]  https://esolangs.org/w/index.php?diff=147386&oldid=147364 * Ractangle * (+230) /* A quine */
16:45:31  [[Signs]] N https://esolangs.org/w/index.php?oldid=147387 * Ractangle * (+17) a very useful redirect
16:51:40  [[Special:Log/newusers]] create  * Zaikawo *  New user account
17:03:49 -!- FreeFull has joined.
17:22:39 -!- tromp has joined.
17:23:52 -!- SGautam has quit (Quit: Connection closed for inactivity).
17:28:28 -!- craigo has quit (Quit: Leaving).
17:41:21  [[User talk:Tommyaweosme]]  https://esolangs.org/w/index.php?diff=147388&oldid=147384 * Yayimhere * (+190) /* collab? */
18:03:42  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147389&oldid=147337 * Yayimhere * (+7) 
18:07:18 -!- Lord_of_Life_ has joined.
18:07:39 -!- Lord_of_Life has quit (Ping timeout: 252 seconds).
18:08:38 -!- Lord_of_Life_ has changed nick to Lord_of_Life.
18:15:49 -!- ais523 has joined.
18:27:26 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
18:29:00  Soni: so I think it's plausible to do memory safety verification on assembly language, by using, e.g., borrow-checking annotations and requiring a particular stack discipline
18:29:34  compilers don't actually do that in practice, but there's no reason why they couldn't other than historical reasons
18:30:48  Java does, for example. Most JREs have a bytecode-verification step which looks like abstract interpretation, and the bytecode won't be instantiated if it e.g. has a guaranteed stack underflow.
18:30:50  although, the easiest way to get an end-to-end memory-safe toolchain would be to use one of the old-fashioned programming languages in which all arrays are declared at compile time, it's then easy to statically check that all memory addresses are inbounds if you want to
18:31:29  korvo: well it's easier in Java because it's GCed, so the only place you can have memory-safety UB is on the stack
18:32:00  Whereas e.g. Python does not do this. I happen to have memorized the bytecode program "KABOOM"; convert this to a Python code object and the interpreter will crash -- portably!
18:32:32  that said, I've been meaning to write an article about how garbage collection doesn't prevent memory usage errors as well as borrow-checking does; it prevents memory-safety UB specifically, but it doesn't prevent memory safety bugs, just lessens their consequences
18:32:44  it's easy to write the equivalent of a use-after-free in Java, it isn't UB but may read stale data
18:32:51  ais523: Of course. If the question is about languages with explicit memory management, then I think that somebody is begging some part of the question: why would we expect memory-safety from such systems?
18:33:30  korvo: the word "expect" is ambiguous in English, both meanings fit your sentence and I agree with you in one case and disagree in the other
18:33:36  If Soni were talking only of Rust, for example, then I'd straight-up refute the premise: Rust is *not* memory-safe when we talk about the subset used in actual crates.
18:33:59  ais523: we'd just type-annotate the stack ngl
18:34:25  yes, type-annotating the stack and registers is a good example of the sort of thing you can do to make asm more type-safe
18:34:29  ais523: Like, in the Latin sense? I agree that we must somehow produce memory-safety by writing a small amount of hand-engineered hand-proven assembly. I usually disagree with the idea that it should be more than a page or two of code per low-level bootstrapping step.
18:34:49  ais523: we mean instead of "requiring a particular stack discipline"
18:35:04  e.g. WebAssembly uses typed stacks as part of its memory-safety strategy.
18:35:13  Soni: you have to give some semantics to the stack(s) in order to make function calls compose correctly
18:35:31  ais523: you just have to type the stack pointer
18:35:57  Or require every function to consume the entire stack and replace it with an entirely new stack. WebAssembly, but also type systems of Joy and descendants.
18:35:57  Soni: you are implicitly assuming a stack discipline there by assuming that the stack pointer points to the top of the stack
18:36:15  in generalised asm, this isn't a given, although people normally do write like that
18:36:26  ais523: Or forbid pointers~
18:36:28  or at least, have the top of the stack always at a known offset from the stack poitner
18:36:33  ais523: not at all, if anything, you're probably assuming something that we aren't
18:37:21  Soni: so the problem is, say we're writing a function that's meant to run in a type-safe way – some of the existing memory will be free for the function to use for its own purposes, some of it can only be changed in certain ways (or not at all) without violating memory safety
18:37:31  Like, *all* bytecodes I've mentioned so far are lacking in pointers. WebAssembly knows what arrays and function refs are, but not pointers in general. Java only has object refs on the stack. Python doesn't have pointers, period.
18:37:35  and some of it can't usefully be read because you can't make sufficient assumptions about what it holds
18:37:37  ais523: yes, that's all encoded in global typestate
18:37:57  which isn't even global at all, but it relates to global state
18:38:28  a stack discipline is a simple way to solve this problem, you say "on entry to the function, it can touch all memory below SP and above the stack guard page, but can't touch memory above SP unless given a pointer to it"
18:38:45  if you don't have a stack discpline you need some other solution
18:38:48  ais523: yes, you encode that in a type
18:38:58  you encode that whole phrase in a type
18:39:11  hmm, this might be a type but I am not convinced
18:39:15  this is called your function's "world"
18:39:34  A stack discipline is effectively a FORTH, via Greenspun's Tenth Law. It's going to generate a DSL which we might as well prefer instead of machine code.
18:39:57  Similarly, a global typestate which is isolated to a single struct is effectively a Self-style Smalltalk, again via Greenspun.
18:40:04  the world is also part of the function's type, so in theory the assembler would automatically fail stack overflows
18:40:12  korvo: so my thoughts on this is that memory-safe languages can't have raw pointers, but can have references which are, in effect, raw pointers together with rules for what you can do with them
18:40:39  I'd say "those who didn't read the VPRI or STEPS reports" paraphrasing Santayana, but STEPS didn't really produce many artifacts for us to study. They didn't have much to say about the boot process; instead, their languages do stuff like graphics.
18:40:42  or, well, you can have raw pointers as long as you never read or write through them, but that isn't very useful
18:41:35  ais523: we think having an escape hatch is necessary tho
18:41:49  for real-world use at least
18:41:55  I am not sure a "generalised" escape hatch is necessary
18:42:23  I think that you do often need a number of special cases that don't easily fit into the rest of the language, but am not sure why you would need more than a finite number of them
18:43:23  we just think not having to think about all possible abstractions and let someone else build them is fine
18:43:33  anyway, we're supposed to be streaming
18:43:39  ais523: Sure. There's a big general meta-statement that an actor/object/etc. is fundamentally a fat pointer of script/code/class and locals/vars/fields. Often, we want that first pointer to be an executable function pointer, and the second to point to a struct.
18:43:39  >.<
18:44:30  korvo: well, objects in the Java or Rust sense usually have multiple code-address-like entry points
18:44:32  Smalltalk had a bunch of functionality around this. It could let one object become another object, it could change the class of an object, etc. Some of this infected other languages, like C++'s reinterpret_cast<>.
18:45:28  ais523: Sure. Methods can be compiled down in a lot of ways, though. It turns out to be useful to let the script have the Strategy Pattern; deliver a message to the script, and let the script do its own dispatch. Anything fancier can be figured out in JIT.
18:45:40  Perl allows you to change the class of an object at runtime, but it works differently from C++
18:46:27  korvo: hmm, the systems programmer in me dislikes that approach, basically because it forces you to serialise the message
18:46:50  ais523: This might be the clearest indication that I grew up in the object-oriented world~
18:47:02  I guess I dislike having concrete representations of things unless there's a really good reason
18:47:29  one of the things I dislike most about Rust is that the language effectively forces &T to be represented as a pointer to some actual T in memory
18:47:56  whereas most uses of &T don't care about that and aren't conceptually thinking about the reference like that at all
18:48:23  We came up with a good reason in Monte: it lets us adopt the same extremely powerful named-args convention as Ruby and Python, while still guaranteeing E's fancy distributed semantics work for objects that generically forward messages.
18:48:33  I suspect that you could get fairly large savings by, say, optimising an &u32 into a u32 with the same value as the target
18:48:54  We also didn't care about the widths of ints, so it's fair to say that we didn't care about systems-programming goals.
18:49:30  right – I see named arguments as sugar, in that they can easily be compiled into positional arguments if you can see both the callsite and the definition
18:49:44  they are convenient for the programmer but don't need to exist in the compiled program
18:51:26  on the subject of int widths, I have been meaning to write a long rant about that
18:51:36  Makes sense. For distributed systems, we must assume that we get a uniform wrapper over an opaque blob of data. So we must transmit everything in the wrapper, and can't assume anything not in the wrapper.
18:51:47  in most languages (that have finite-width ints), it is unreasonably hard to write, say, a program that averages two integers
18:52:45  Rust is considering adding a builtin for that to its standard library, because it's hard to write correctly and almost impossible to write efficiently in a platform-independent way
18:53:16  E's wrapper is a tuple (verb :str, args :list[ref]). Monte's wrapper, we argue, is the much nicer tuple (verb :str, args :list[ref], kwargs :map[str, ref]). In both cases, that's *all* that the receiver knows, and anything else must be done very carefully.
18:53:59  so I had a job working on distributed systems, but we did it a bit differently – every system involved in the computation had the same compiled codebase available, and they would assume that the same code existed on every node
18:54:32  so messages didn't have to be generically understandable, you could just send blobs to objects on other systems in a way that they would understand
18:54:33  Ah, a common form of cope. Painful.
18:55:07  I remember watching as a child when a paperless office upgraded from one version of Microsoft Office to another, back when Office loaded documents via mmap.
18:55:19  the only generic component needed was a sort of dispatcher/multiplex because you don't want every object to open its own network port to listen to messages
18:55:55  Oof. And so you end up with an object server, even if you didn't want to write one.
18:56:12  well, you need one anyway
18:56:27  or, hmm, I should backtrack a bit
18:56:37  "Perl allows you to change the class of an object at runtime," => so does python, as long as their representation is compatible, which is the easiest to get if they are subclasses of a common class and neither adds more data over what that common class has. I think python inherited that from smalltalk, but I'm not entirely sure.
18:56:57  Right. Object servers, event loops, etc. are required, so they should be built-in. Erlang is a great demonstration of how this can turn into real high-reliability distributed-systems toolkits.
18:56:59  the entire purpose of the project was to split up existing programs across multiple nodes, but it was still intended to act as a single program with a single entry point
18:57:25  b_jonas: well Perl doesn't even care if the representation is compatible :-)
18:57:53  "you can have raw pointers as long as you never read or write through them, but that isn't very useful" => rust does exactly that, and it is helpful, but that's because it allows you to read/write them if you assume the responsibility for avoiding UB which includes keeping memory safety
18:57:56  it just trusts that the programmer knows what they are doing and/or will change the representation to match
18:58:04  b_jonas: Python 3's default class is the new-style object class with inferred slots, and there's no tools for making that work nicely. Python 2's default class did allow that, though; objects were a fat pointer to their class and their dict of locals. Ruby still does it that way IIUC.
18:58:26  I'd be astonished if Ruby didn't still do it that way, given the sort of language it is
18:59:16  Python changed because PyPy adopted Smalltalk's "maps" (awful name!) for computing optimized class layouts with inheritance. RPython implementations of SOM and Monte do it too.
18:59:52  So all of a sudden CPython used a lot more memory than PyPy, and that was politically unacceptable. Ergo, new class layouts that do about half of what PyPy does, get the memory usage down, and make Microsoft and Google happy.
19:00:21  the "office loading documents via mmap" is different because the .doc format is ostensibly intended for long-term storage, whereas most people don't even attempt to allow programs to continue running on a new codebase if the codebase has changed more than trivially
19:01:00  ais523: Any message put onto the network is in long-term storage.
19:01:12  Time is an illusion, wall-clock time doubly so.
19:01:37  not necessarily? if you are using rendevouz-style messaging then the time that the message spends in transit effectively doesn't exist from the program's point of view
19:01:51  "I suspect that you could get fairly large savings by, say, optimising an &u32 into a u32 with the same value as the target" => right, there was a proposal to add such a thing to C++, as in a new type that you use as a function parameter and it's either a const reference or a copy of the value and the compiler decides which one it is. rust doesn't have that, but its rules about references are strict 
19:01:57  enough that a compiler can reasonably do such an optimization when you pass a function argument by reference and the compiler knows that it's a specific small sized type.
19:02:24  it's OK to say "if this message is late arriving, then the 'thread' will just pause until it arrives" ('thread' in quotes because I'm referring to a chain of code-causing-each-other-to-run that might not correspond to an actual program or OS-level thread)
19:02:28  That's what I'm saying: the program's concept of time is constructed from what the OS and I/O tell it.
19:02:55  korvo: but what I am saying is that from the program's point of view, this is not long-term storage and is not in fact a form of storage at all
19:03:00  it's the equivalent of a pre-empted thread
19:04:03  b_jonas: so its rules about references are *almost* strict enough, but it doesn't prevent a function you call doing "immutable_ref as *const u32"
19:04:27  ais523: It's I/O. Programs don't know what I/O is hooked up to.
19:04:33  and the fact that functions can do that and compare the results means that it needs to track the identity of every u32 reference, even though programs basically never care
19:04:42  korvo: it isn't I/O from the point of view of the program! only from the point of view of the runtime
19:04:55  "Rust is considering adding a builtin for [averaging two integers] because it's hard to write correctly and almost impossible to write efficiently in a platform-independent way" => it's not *that* impossible to write efficiently in a platform-independent way, I think there are two portable magic formulas for it, but nevertheless it's easy to mess it up so it makes sense as a library function, and 
19:05:01  further there's an SSE instruction that averages two integers so the compiler can sometimes optimize to that and so a compiler builtin makes sense too. (of course this is mostly llvm's business, but llvm is developed partly to support rustc.)
19:05:02  the program need not know whether its messages are being handled locally or over the network
19:05:14  Oh. Oh noes.
19:05:36  Okay, so yes, but only because the program should be written so that its messages are *always* over a network.
19:05:55  my complaint isn't that attract is annoying to implement, but that other operations are annoying to implement based on just attract and repel (with no explicitly copy, you have to eg. loop attract for that)
19:05:58  well, it should be written so that it doesn't know or care whether the messages are over a network
19:07:06  ais523: In E, a program knows whether its refs are "near" or "far". Near refs can be deconstructed and treated as data. Far refs can only be targets of messages, returning promises or other far refs.
19:07:07  the whole purpose of what we were working on was to make the multiple networked nodes act as though they were a single computer with additonal cores
19:07:28  Sure. But that doesn't work.
19:07:48  korvo: right, that is a sensible optimisation – what we were doing treated everything as near refs, potentially requiring a network round trip to deconstruct
19:08:11  Like, Beowulf'ing it was a meme before I was born. The RPC debates were when I was a child. The question of NUMA has been answered: NUMA can't be substituted for SMP.
19:08:15  although if there was a small enough amount of data involved, we just sent a copy pre-emptively in case it needed deconstruction
19:08:40  you can only get away with this in a GC'ed language, otherwise you get memory lieaks
19:09:19  it is quite possible/probable that this would have hit either an insurmountable semantic barrier or an insurmountable performance barrier – I lost confidence in the project towards the end and left that job
19:09:20  Oh, in *any* language, there's the question of cyclic GC where the cycle extends across the network. This was one of E's big contributions, and most systems still don't implement it because it's such a PITA.
19:09:53  yes, I think our GC didn't implement that, we were probably planning to implement it at some point when we figured out how
19:10:27  The laws are strong when it comes to pulling apart a monolith. Amdahl's Law and Conway's Law suggest that the first step is to convert the monolith to a job server and farm out the most compute-intensive tasks to a fleet of identical workers.
19:11:08 -!- tromp has joined.
19:11:35  my guess is that the goal of the project wasn't to find something that worked "efficiently" – just faster than on a single computer, with no manual intervention
19:12:00  Conway's Law further suggests that a linguafranca is required in order to make this scale, like gRPC at Google, Thrift at Facebook, or the pile of crappy JSON-over-HTTP APIs that AWS and other cloud vendors offer.
19:12:47  Ah, yeah, management rarely knows the laws. Frustrating but common. I can't think of a job where I haven't had to explain the Fallacies of Distributed Computing to management.
19:13:39  I think you may be wrong about what Conway's Law suggests in general, though: if you are running a scheme where (semantically) anything can run on any node with a common code base, and the only difference between locations is efficiency / NUMA
19:14:12  then that doesn't necessarily imply that a lingua franca exists, just that there is some way to communicate messages between nodes that looks like it was running on a single node
19:14:42  if the structure is "anything can be anywhere, putting it in the right place is an optimisation decision" then there is no structure to mirror
19:15:06  In this case, Conway's Law is that if two nodes communicate with each other, then the designers of the software on those nodes communicated with each other. A linguafranca gives those designers a common language to facilitate their designs.
19:15:27  korvo: right but we had the same software on every node, because it was intended to act like a single computer running a single piece of software
19:16:02  Otherwise you end up with e.g. one designer trying their best to imagine what it must be like to be that other designer and guessing their intent. Incorrect API use, unstated invariants or requirements around usage, etc.
19:16:02  if you wanted to change it, you would exit the process and start a new one (copying its code everywhere in between), just like you would do ona single computer
19:16:34  ais523: "functions can [take the address of a reference] and compare the results" => I see! that makes sense and may be unfortunate. it means if your function reborrows its parameter (or a field in it) to an opaque function then it can't use a copied/moved version of the value, nor pass the value in a register, because the function might need to compare its address.
19:17:07  ais523: By an easy handwave, there must have been times when at least two nodes differed in the version of software that they ran. At scale, that turns into downtime.
19:17:29  So, at scale, distributed systems usually are designed to gracefully accept messages from different versions.
19:17:40   "Rust is considering adding a builtin for [averaging two integers] because it's hard to write correctly and almost impossible to write efficiently in a platform-independent way" => it's not *that* impossible to write efficiently in a platform-independent way, I think there are two portable magic formulas for it ← so (with unsigned ints) you can do (a >> 1) + (b >> 1) + (a & b & 1) but that doesn't go near to the optimal code on x86_64
19:18:23  "in *any* language, there's the question of cyclic GC where the cycle extends across the network." => how does Windows COM handle that incidentally? it has transparent remote objects (between processes) doesn't it?
19:18:31  korvo: yes, in this model the downtime becomes startup latency, because some time is needed to copy the codebase onto every node after restarting the program
19:18:34  maybe it only does reference counting?
19:19:01  ooh, actually I think our GC *did* handle cycles – if there was a potential cycle it tried to migrate all the objects onto the same node so that that node could detect the cycle and free them
19:19:15  err, a potential unreferenced cycle, that is
19:19:40  the way you do it is, if a node contains an object with no inbound local references, it moves the object to a node that does have a reference to it
19:19:53  ais523: Sure. A cool trick from the E world is to separate the object server from the user-level codebase, so that only a small slug of user code has to be copied. In Monte, we can do this incrementally on a per-module basis, although I never wrote a compiler that took serious advantage of it.
19:19:59  (or if it contains a cycle with no inbound references from otuside the cycle)
19:20:40  b_jonas: hmm, I wonder if COM is able to create a reference cycle
19:20:44  probably it is
19:20:59  but there are some languages where you can't modify things while they have inbound references, those languages are unable to create cycles
19:21:09  But e.g. I had a single object server doing lots of different raytracing jobs, with each job specified as a big generated Monte AST. When the object server received a request to draw a pixel, it also got a ref to that AST, and it could cache compilations for ASTs already seen before.
19:21:26  as a simple example, you can't create a reference cycle in Rust without using unsafe code or something that contains an UnsafeCell, so a hypothetical "cell-free Rust" couldn't have reference cycles
19:22:24  This is roughly how production RenderMan works, although the scene isn't executable in their case. But because a film contains so many different scenes, the scheduler has to have some awareness that a worker still "has the scene in memory" so to speak.
19:22:32  "tried to migrate all the objects onto the same node so that that node could detect the cycle and free them" => aren't there cases when that rule causes to migrate everything to the same computer, which causes it to run out of memory or at least catastrophically degrades performance?
19:24:24  b_jonas: yes, that case happens if the program is effectively single-threaded, you can work around the problem by creating extra "GC roots" that are pinned in place
19:24:35  "if COM is able to create a reference cycle" => it can at least represent two objects that reference each other, but that's with two objects within the same process and the server probably already knows how to clean them up, eg. either one of the references behaves as a weak reference, or one of the objects is guaranteed to have a longer lifetime than the COM client referencing them
19:24:51  Distributed GC can't progress that way. It looks like distributed reference counting; when an exported object isn't referred to locally, then its server can notify everybody else that the object wants to be GC'd.
19:25:36  Only at that point, if the object is safe and consenting to copy, can it possibly be transferred to other servers.
19:26:21  I think we were able to move the object elsewhere even if it did have local references, we would replace the local references with a shim object that would do the network accesses
19:26:29  Or quoting http://erights.org/elib/distrib/captp/dagc.html "Only the side that has the arrowtail can find out (by finalization from his local intra-vat garbage collector) that there is no longer any local interest in using the tail of that reference. This does not necessarily mean it's safe to drop the reference!"
19:26:42  otherwise that would violate the "anything can be anywhere" principle
19:27:01  obviously, doing that would probably be bad for performance unless the other node needed it much more
19:27:29  or the reference from the COM client to the object acts like a weak reference, so the object can be destroyed while the client has a reference to it and most ways to try to use that object fails afterwards though in a safe way
19:27:32  maybe that was only a planned feature, rather than implemented
19:28:08  Some things are closely held. An object with the capability for local I/O can always export methods that invoke that capability, but they can't allow it to be copied to another machine/process/etc. In Capn Proto, there's two kinds of opaque refs: pointers to blobs, and refs to capabilities.
19:28:20  b_jonas: so I have realised that weak references are useful even in non-GCed languages, and in general, many programs semantically want to be able to free an object while it still has inbound references
19:29:10  korvo: you can always copy something that's semantically identical to the object, though (and that does I/O on the original machine via forwarding the requests over the network)
19:29:20  yes. it's just complicated because there are multiple variants of weak reference.
19:29:37  obviously the implementation will be different, but the caller/message-sender doesn't need to know the details
19:30:06  NetHack is a good example, semantically you can destroy an object or kill a monster while parts of memory still refer to it
19:30:13  ais523: So, in cap theory, we say that that's *not* a copy. It's a "transparent forwarder", borrowing Smalltalk's phrasing. The weakness or ability to cut off forwarding makes it "revokable", in cap theory.
19:30:44  korvo: so you work around this by having the forwarders be the only thing that exist from the program's point of view
19:30:46  By saying this, we can start to imagine isolation as a provable property of objects: if an object holds something closely, then the only way to inspect that thing is via consent.
19:31:10  ais523: right, M:tG even more so
19:31:14  or, well, you say that there is no way from within the program to determine whether something is a forwarder or not
19:31:25  b_jonas: M:tG isn't a computer program, but yes
19:31:57  a program like Arena needs weak references to handle cases where an object refers to something that has changed zone and thus is considered a new object
19:32:06  ais523: Sure! The Joule language works like this. There's an obvious cost to not being able to treat objects as near refs; we need to indirect through the heap just to do local ALU ops. Haskell has the same problem for a different reason; lazy threading through the heap for strict ALU ops.
19:32:44  In both cases, it seems like it's a PITA to ask users to guess at whether a Sufficiently Smart Compiler will correctly guess that everything is strict/near/etc. So let's just give users the distinction and make them pick up the pieces.
19:33:08  korvo: the history of Java is informative here – even non-distributed Java treated everything other than primitives as objects until recently
19:33:43  but ended up adding what are in effect non-virtual objects (in C++ terminology) in order to avoid that performance pitfall
19:34:20  ais523: We could argue that, starting with Self, the forwarders were the only thing that an object could access. Those forwarders just happen to look like fat pointers from the implementation's POV. And that's kind of the history of the modern everything-is-an-object approach.
19:35:00  I suppose that Java made this choice for performance when compared to Self? That's normally the justification for this sort of difference.
19:35:14  right – I think everything-is-an-object is usually a good mental model for programmers to deal with, even if it is occasionally very difficult for implementations to implement efficiently
19:35:51  just look at Python's integers, for example – they can transparently convert to bignums to avoid arithmetic overflow, and as a result Python is one of the only widely used languages where programmers don't have to worry about overflow at all
19:36:11  Meta-tracing was the key insight, and even among JIT pros it's a controversial one. Without meta-tracing, JIT can only start and end on user-chosen boundaries like functions or methods.
19:36:49  But meta-tracing means that the JIT starts on compiler-engineer-chosen boundaries, like interpreter-level loops.
19:37:21  hmm, JIT works well in an everything-is-an-object world, where the exact type of the objects isn't known (only a superclass or set of interfaces), because the objects will in practice usually have the same type but that is hard to prove
19:37:55  and a JIT allows you to make optimisations that would be unsound in rare circumstances, by checking to see if the conditions for soundness hold, and reversing the optimisation when they dont'
19:37:59  yeah
19:38:52  AOT compilers can use similar optimisations sometimes
19:39:20  e.g. clang/LLVM will assume an object always has the same type if only one type exists in the compilation that fits the superclass/interfaces you specified
19:39:32  That's all pre-meta-tracing JIT. In particular, deoptimization should never happen; at worst, if an invariant fails, the JIT should just toss out all of the machine code tagged with that invariant.
19:39:46  korvo: that's a form of deoptimization, isn't it?
19:39:51  (also what I was referring to)
19:41:04  ais523: Usually folks are referring to the nasty process of generating a new interpreter state, copying the JIT's variables into that state, and restarting the interpreter in the middle of user-level code.
19:41:05  b_jonas: anyway, the best way to average two unsigned integers in x86_64 asm is to add them with the add instruction, then rcr the result
19:41:23  I haven't figured out how to get compilers to ever generate an rcr without using an intrinsic for the purpose
19:41:57  korvo: hmm, now I'm imagining AOT-compiled code with an injected fastpath
19:42:19  compile X into if (a holds) { X assuming a; } else { general implementation of X; }
19:42:26  But meta-tracing offers a different path. At compile time, generate multiple copies of the interpreter: one for normal interp, one for tracing, one for running JIT code, etc. Then, at each compiler-level "merge point", make a universal decision about which interp to use next.
19:42:36  I have noticed gcc doing this on occasion, but am not sure what heuristics it uses
19:43:05  Deoptimization is now merely when a guard in JIT code jumps to the normal interp.
19:43:50  I understand why JITs have interpreters, but in a way it feels conceptually wrong to me
19:44:14  ais523: you can also try to do such optimizations without JIT, in something like python, but it gets ugly. you hope that the object will be of the same concrete type every time, and so for method calls in the code you try to cache the specific method to call. this gets ugly because any code could change the class so that the method points to a different function, so you need some very ugly 
19:44:21  representation, but it can be done. and it's especially worth for those integers that you mentioned and floats, because there you don't just gain on faster method calls, but you can avoid allocating an actual object for a float or int temporary if you guess its type correctly and it doesn't overflow a fixed sized integer.
19:44:36  if part of program, under a set of assumptions, spends a long time running, then it is correct to compile it and run the compiled version; if it doesn't, performance isn't important so the time spent compiling it isn't a big cost
19:45:12  "add them with the add instruction, then rcr the result" => ah, so you want not only a portable method but one that's the most efficient. that makes sense.
19:45:15  b_jonas: well, there's the OCaml approach where everything is a disjoint union of integer and pointer
19:45:52  if it's of a type that can't be represented as an integer, it has to always be stored as a pointer, and the other disjoint union option isn't use
19:45:53  * used
19:46:00  (this is why OCaml has 31-bit integers)
19:46:07  ais523: It's for uniformity. In a meta-tracing JIT, the interps are running compiled versions of interpreters for user-level languages; the JIT isn't tracing Python ops, but RPython ops.
19:46:30  ais523: can you cast both to a larger size integer, add them, shift right, and then cast down to the original size? there's somethign similar for multiplications that compilers specifically look for and optimize
19:46:56  b_jonas: if there is a larger-sized integer, yes, but I think compilers will compile using larger-sized operations
19:47:07  let me load up godbolt and check for the 64→128 case
19:47:37  "everything is a disjoint union of integer and pointer" => right, ruby 1.8 does something similar to that (only there are a few more possibilities besides those two for reasons that I don't understand)
19:47:53  but that specifically doesn't work for python floats
19:48:22  I think scheme is designed to possibly work with those sorts of integers too
19:48:23  So the "part of program" that "spends a long time running" is something like a bytecode dispatch loop, and the "set of assumptions" is when the addresses for the bytecodes are repeated. This is why the JIT needs merge points: it needs hints that a user-level loop is happening.
19:48:37  b_jonas: https://godbolt.org/z/77vK8vv7r
19:49:24  that's a fun algorithm, but it isn't the RCR algorithm, and in fact doesn't use the carry bit at all
19:49:38  I think it is doing a 128-bit addition but has cancelled out a left-shift and a right-shift
19:50:04  korvo: oh, I see, you are thinking about languages like Python that are inherently interpreted
19:50:34  CHICKEN Scheme is another good example of this; https://www.more-magic.net/posts/internals-data-representation.html for more on that. Objective-C is another good example, particularly packing selectors.
19:50:48  or, well, AoT python exists but your JIT is trying to optimise an interpreter rather than trying to optimise the interpreted program
19:50:57  ais523: it's strange that you write it with i128 instead of u128, because then the division rounds towards zero and you have to notice that the dividend is nonnegative so that doesn't matter
19:51:18  b_jonas: it was a thinko but doesn't matter, LLVM is very good at noticing that sort of thing
19:51:27  ais523: Right. Most JITs do the first Futamura projection. Our JIT goes one higher.
19:51:41  let me look up what the blue book says
19:51:53  I tried with u128 and get the same result
19:52:06  yeah
19:52:34  I also tried with u<65> but apparently it hasn't been implemented yet, not even on nightly
19:52:56  and it probably wouldn't be special-case implemented as a register plus a flag, even if it conceptually would be
19:53:01  * conceptually should be
19:53:27  I think zig implements that, you could try with a zig compiler
19:53:45  out of interest, what does zig use for its code generation / backend?
19:54:36  I think it uses llvm too, but I'm not quite sure. it bundles a clang so there is at least an llvm somewhere in there.
19:55:26  I am worried about how LLVM-dependent the world is getting, LLVM seems inherently somewhat unsound to me
19:55:57  there was a miscompilation bug semi-recently that was caused by C++ autogenerating an == implementation for a type that didn't reflect actual equality for objects of that type, and nobody had noticed until the bug report
19:56:04  ok, so the blue book chapter 2-5 says you can use { (a & b) + ((a ^ b) >> 1) } for that, and then elaborates on what to do if you want to round up or your inputs are signed
19:56:26  right, that's the algorithm that LLVM picked
19:56:56  anyway, my more global point is – I think arithmetic operations in programming languages should round/truncate/wrap only where the programmer says they should, not at points determined by the language
19:57:15  I should be able to write, say, [ (a + b) / 2 ] and get a correct averaging routine even though the intermediate values can be outside the range of the data type
19:57:29  the square brackets show where rounding/truncation/wrapping is allowed
19:57:43  this would also be very useful with floats, e.g. [ a * b + c ] for a fused multiply-add
19:58:18  that would be rather hard to implement in general and efficiently
19:58:23  (at present, (a * b) + c means [ [ a * b ] + c ] in most programming languages – this can't be compiled into a fused multiply-add without fast-math because the result is different)
19:58:40  obviously we already have some special cases like (a*b+c) optimized to a fused multiply-add if you allow it
19:59:00  b_jonas: quite possibly, but I don't care – it beats programs producing incorrect results
19:59:15  you could perhaps generate a compile error if the compiler can't find an efficient implementation
19:59:25  and the (a+b)/2 *should* work if you upcast to a one larger integer type, even if you showed that llvm doesn't optimize it correctly, it could
19:59:26  asking the programmer to add additional rounding/wrapping points
19:59:40  hmm 
19:59:46  upcasting to a larger type should work for pretty much any integer example of this
20:00:02  except where exponentials/shifts are involved (OK, it technically works even then, but the type would be too large)
20:00:27  [ a << b ] is fun, it unambiguously returns 0 if b is larger than the width of a
20:00:55  (whereas a << b in C is UB in that case and often in practice returns a shifted a lesser distance)
20:03:11  oh, oh no, current Rust compiles a << b into a shl instruction in release mode
20:03:26  ais523: the problem is that there are some common cases where getting a guaranteed correctly rounded result is actually very hard and very often it's fine to get a result that might have a small error, this includes converting a machine float to decimal (for formatting it as a decimal string usually) or decimal to machine float (for scanning a decimal string usually) as well as floating-point exp, log, 
20:03:33  sin, cos, tan, atan, asin, acos
20:03:48  that has to be wrong, doesn't it? shl takes the bottom 5 significant bits of b, whereas it should be wrapping mod the width of a
20:03:56  according to the defined semantics of release-mode arithmetic
20:04:10  and so the programmer needs a way to specify whether he wants the definitely exact solution, or he wants a solution that may sometimes be off by a little bit, or even something worse
20:04:23  b_jonas: well, those are function calls, and those inherently round because they're returning a result of a concrete type
20:05:10  I think b_jonas is referring to the Table-maker's Dilemma. Rounding transcendental functions correctly is somewhere between exponential and undecidable IIRC.
20:06:06  "[ a << b ] is fun, it unambiguously returns 0 if b is larger than the width of a" => it's not that simple! the problem is that x86 has multiple shift instructions, and if you try to shift an u64 by 64 bits, some of them return zero and some treat it as a shift by 0, and because of this it does make sense for C to have a << operator that doesn't guarantee what result you get for ((uint64_t)1)<<64, even 
20:06:12  if as a programmer sometimes you would like a shift that always gives 0 for this
20:06:35 * korvo really should go run errands
20:07:53  korvo: I believe for decimal conversion, exp, log, sin, cos, tan it happens to be decidable, and even decidable in a time limit, but the time limit is something like a polynomial of the maximum exponent of the float, which can sometimes be too big in practice
20:08:37  b_jonas: so Rust currently seems to be compiling << with unspecified overflow behaviour, when in release mode (it does correctly panic in debug mode)
20:09:14  this seems like a bug in Rust? LLVM is assuming C-like overflow behaviour even though Rust doesn't use that
20:09:45  for sin, cos, atan this is because a nonzero machine float can't get closer to a multiple of pi than something on the order of magnitude of the smallest floating point number, and there's a similar reason for decimal conversion
20:10:31  oh, hmm, it seems intentional, the LLVM IR generated by Rust is masking off the bottom five bits of the shift and then doing the shift
20:11:19  right, println!("{}", 1u16 << black_box(17)); prints 2
20:12:09  ais523: it shouldn't matter, but out of curiosity, what type is the 17 there?
20:12:18  b_jonas: Oh no, now I'm remembering that one cringe idea I had a while ago for letting trigonometric functions be fuzzy to avoid precision issues.
20:12:29  b_jonas: u32 I think, although I keep getting confused about the type of the right hand side of shift operations
20:12:42  maybe i32
20:12:50  I do remember that it's something that's too large
20:13:08  https://langdev.stackexchange.com/q/3284 this one. Very funny, even if most folks didn't actually understand why I'd want this.
20:13:08  I'm guessing i32 but I'm not sure
20:13:17  I really need lunch now. Peace.
20:13:35 -!- zenmov has quit (Ping timeout: 260 seconds).
20:15:04  I have probably already linked from #esolangs to both of these about floating-point but just in case: https://www.exploringbinary.com/ a blog mostly about floating point to or from decimal conversions, I had known those were hard but reading the blog convinced me that they are *even harder* than I had thought; and http://sleef.org/ for transcendental functions on machine floats
20:16:42 -!- zenmov has joined.
20:20:46  b_jonas: I think the situation is more that a) they're hard to do efficiently and b) people keep forgetting about how weird floats are when implementing them
20:21:29  there should be a fairly simple correct implementation that entirely uses integer arithmetic and uses a big array to keep track of all the accumulated digits
20:21:35  but it'd be slow
20:22:29  [[Snakel/Errors]]  https://esolangs.org/w/index.php?diff=147390&oldid=145463 * Ractangle * (+63) /* SyntaxError */
20:24:54  [[Snakel/Errors]]  https://esolangs.org/w/index.php?diff=147391&oldid=147390 * Ractangle * (+93) /* Using anything BUT a tab or 4 spaces as your indentation */
20:25:34  [[Snakel/Errors]]  https://esolangs.org/w/index.php?diff=147392&oldid=147391 * Ractangle * (+5) /* Removing an entry that is not on the list */
20:26:06  [[Snakel/Errors]]  https://esolangs.org/w/index.php?diff=147393&oldid=147392 * Ractangle * (+0) /* Not specifying a type or specify a non existent type to a variable */
20:28:09  whoa! so the intel x86 arch manual says that SHLD with 16-bit operands gives an undefined result value and flags if the shift count unsigned modulo 32 is greater than 16, but a shift by exactly 16 is fine and will shift by 16 bits; but a SHLD with 32-bit operands is never undefined and a shift count of 32 shifts by 0 bits, so the two behave in an entirely different manner. I didn't know this
20:28:43  ais523: yes, that's a fine summary
20:32:22  it also says that for the ordinary SAL instructions with 8 or 16 or 32 bit sized arguments, the shift count is modulo 32, except that before 286 it was IIUC modulo 256 instead. that is funny because I think SHLD was added by 386, not 286 (since it has a prefix, and 286, so the reason for the change is not the new SHLD instruction but just different optimizations
20:36:44  [[User talk:5anz]]  https://esolangs.org/w/index.php?diff=147394&oldid=147318 * 5anz * (-1) /* esolang? */
20:42:15  [[Estrita]] M https://esolangs.org/w/index.php?diff=147395&oldid=146611 * Aadenboy * (+320) minor updagte
20:43:54 -!- olsner_ has joined.
20:45:40  ah, this is getting even more hilarious. for the SSE2 shift instructions PSLLDW/PSLLD/PSLLQ, which shift each 16-bit, 32-bit, or 64-bit part of an XMM/YMM/ZMM vector, the shift count is an unsigned 64-bit integer that comes from either an XMM register or memory, which means there's an instruction that rotates part of a 256-bit YMM register, reads a 128 bits shift count operand from memory, throws away 
20:45:46  the top 64 bits of that operand, then checks the middle 60/59/58 bits and if they aren't all zero it shifts zeros into every bit of the result. let me see what the later vector shift instruction does too.
20:46:13 -!- olsner has quit (Ping timeout: 248 seconds).
20:46:28  I hadn't known that AVX has an instruction with two differently sized vector operands
20:46:47  s/AVX/AVX2/
20:52:53  so in the AVX2 instruction VPSLLV[WDQ] the shift counts are the same size as the shifted pieces, 16-bit in VPSLLVW, 32-bit in VPSLLVD, VPSLLVQ, and in all cases the shift count is unsigned and if it's too big the result is zero; but for the AVX512 instructions VPSHLD[WDQ] and VPSHLDV[WDQ] the shift count is modulo 16, 32, 64 respectively when they operate on 16, 32, 64 bit chunks
20:53:43  wow
20:53:55  I didn't know x86 got this so complicated
20:54:22  shifts are inherently complicated because the two operands are basically in different units (the shift count is on a log scale compared to the value being shifted)
20:54:29  yeah
20:55:24  and I can understand that more than one of the wrapping behavior can be convenient (as a low-level programmer) in different circumstances
20:57:41  I think most of my programs that shift naturally never have an overflowing shift, and the few that do would want the result to be 0
20:57:58  and that wrapping the shift count is bascially only done because it is the easiest to implement in hardware (you just ignore some of the wires)
20:58:41  there's a reason that 32 bit x86 wraps the shift count mod 32 even if it's shifting something smaller than 32 bits
20:58:56  because changing the number of wires you ignored would be less efficient than ignoring a constant number
20:59:12  did you never try to use single shifts to implement a double shift? because that's the common case where you want, for 32-bit shifted numbers, that single shifting by 32 results in zero 
21:00:05  b_jonas: that's one of "the few that do"
21:00:26  but most commonly I want overflowing shifts to hit the adjacent elements of an array
21:00:39  (IIRC x86 has a bit selection routine that actually does that)
21:00:43  "there's a reason that 32 bit x86 wraps the shift count mod 32 even if it's shifting something smaller than 32 bits" => yes, but they introduced the modulo 32 rule in 286, which does not yet have 32-bit shifts nor double shifts. and I guess that makes sense because it means shifting by 16 results in 0 so you can implement a double shift easily.
21:05:55  yes, either you call the double 386 shift instruction SHLD with the two adjacent array elements as its input operands; or the 386 BT/BTR/BTS/BTS instructions which lets you affect one bit from a memory array and so use most of the shift count to determine how much to index your array
21:06:47  it wouldn't surprise me if BT were microcoded and thus really slow
21:06:52  although I don't remember for certain
21:07:36  microcoded on what cpu?
21:08:04  let me check Agner's docs
21:08:07  recent x86alikes
21:12:07 -!- Everything has joined.
21:17:08  it looks like on some cpus memory BT are slow (as in you'd usually better use other instructions) but not very slow, and on some cpus they're fast enough, so you are at least partly right. 
21:19:24  [[Special:Log/upload]] upload  * Tommyaweosme *  uploaded "[[File:Emojic wheel result.png]]"
21:23:30  [[File talk:Emojic wheel result.png]] N https://esolangs.org/w/index.php?oldid=147397 * Ractangle * (+46) Created page with "Yayimhere's suggestion is gonna be used then~~"
21:24:54  [[User:Ractangle/unnamed collab with yayimhere and ractangle]] N https://esolangs.org/w/index.php?oldid=147398 * Ractangle * (+75) Redirected page to [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]
21:25:25  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147399&oldid=147389 * Tommyaweosme * (+483) 
21:27:44  [[Talk:]] M https://esolangs.org/w/index.php?diff=147400&oldid=124497 * Brain Boy 53 * (+29) 
21:28:04  [[User:Tommyaweosme]] M https://esolangs.org/w/index.php?diff=147401&oldid=147311 * Tommyaweosme * (+6) 
21:28:51  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147402&oldid=147399 * Ractangle * (+62) /* commands */
21:42:59 -!- olsner_ has changed nick to olsner.
21:47:29 -!- zenmov has quit (Ping timeout: 260 seconds).
21:52:57  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147403&oldid=147402 * Tommyaweosme * (+548) 
21:55:19  [[User:Tommyaweosme/unnamed collab with yayimhere and ractangle]]  https://esolangs.org/w/index.php?diff=147404&oldid=147403 * Tommyaweosme * (+92) 
21:59:13 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
22:06:27  [[Bbtos]]  https://esolangs.org/w/index.php?diff=147405&oldid=142253 * Tommyaweosme * (+53) 
22:09:02 -!- tromp has joined.
22:09:39  [[Talk:Nine-hundred-eleven]]  https://esolangs.org/w/index.php?diff=147406&oldid=142473 * Tommyaweosme * (-7) 
22:24:27  [[Nile]] N https://esolangs.org/w/index.php?oldid=147407 * Corbin * (+697) Stub a page on one of the STEPS languages.
22:27:41 -!- Sgeo has joined.
22:34:53 -!- tromp has quit (Quit: My iMac has gone to sleep. ZZZzzz…).
23:37:15  cursed idea: what would a "resource fork"-native API look like, if we could pretend there's no filesystem altogether and just stack resource forks on resource forks? (and then use it for regular filesystems anyway because the rest of the world refuses to improve)
23:40:17  The API can look like whatever you want, really. Consider git, which I'm currently using instead of a filesystem; git's lowest-level API is a declarative content-addressed store, but folks usually use the "porcelain" API which provides a version-control system.
23:41:10  sure
23:41:28  what would a programming language's IO library look like if it were built with resource forks in mind, instead of files
23:41:40  (yes, *instead of*, not in addition to)
23:56:47  Soni: well a resource fork is part of a file – do you mean that executables would look at their own resource fork?
23:57:02 -!- ais523 has quit (Quit: sorry about my connection).
23:57:23 -!- ais523 has joined.
23:57:25  ... did you just quit after replying
23:57:37  I misclicked
23:57:41  oh
23:57:44  thus the fast rejoin
23:58:03  have you heard of "file-dir duality"?
23:58:11  accidentally opened my OS's equivalent of a start menu trying to tab away from the window, then accidentally clicked the close window button trying to close the menu
23:58:30  Soni: no – it's possible that I'll know the concept under another name
23:58:47  is it the way you can treat, e.g., a zip file as though it were a directory, and in theory vice versa although most filesystems don't do that?
23:59:11  do you know how http://foo.example/bar is not the same as http://foo.example/bar/ ?
23:59:31  indeed, although websites often choose to treat them the same way
23:59:49  yes, so file-dir duality is the same but for the filesystem