<alexgordon>
seems like you'd need two different syntaxes
<cuttle>
and make a typeclass so that you can reimplement for different datatypes
<cuttle>
for effiency and control
<alexgordon>
one for "fast" indexing, and one for "slow" indexing
<cuttle>
typeclass for sliceable or whatnot
<whitequark>
alexgordon: ah, you mean the overhead spent for checking whether the index is lower than zero?
<alexgordon>
whitequark: yeah
<whitequark>
negligible
<whitequark>
with branch prediction
<whitequark>
you're overthinking it.
<alexgordon>
eh but people practically expect list subscripting to be *(ptr + idx)
<whitequark>
no ?
<cuttle>
alexgordon: so I've decided on the producer name "glowcoil"
<whitequark>
if your language is memory-safe, then it at least check bounds
<whitequark>
*checks
<cuttle>
alternative choice was coilnoise
<cuttle>
what do you think?
<alexgordon>
whitequark: ew
<whitequark>
and memory-unsafe by default is... well, let's just not do this.
<alexgordon>
C++ has operator[] for unsafe indexing, and .at() for safe indexing
<alexgordon>
which sucks
<whitequark>
I mean honestly, for that case where you really-need-uber-fast-indexing you can have unsafe { array.unsafe_get(shit) }
<alexgordon>
maybe I AM overthinking this
<whitequark>
now forget about that, it's not even relatively common
<whitequark>
you are.
<alexgordon>
maybe the answer is a rich library of functions and combinators
<alexgordon>
map replaces 90% of the things that C++ programmers use [] for
<whitequark>
yep
<whitequark>
that's how you solve the constant bound checking.
<alexgordon>
most of the time when I use [] in python it's to get the last element
<alexgordon>
or to copy a list
<whitequark>
an array*
<alexgordon>
shuddup
<whitequark>
regardless of how guido wants to call it, it's an array.
<whitequark>
that man needs to check his NIH syndrome
<alexgordon>
list is shorter
<alexgordon>
list() vs array()
<whitequark>
int is even shorter
<alexgordon>
it's like one extra character
<whitequark>
let's call them ints
<alexgordon>
python logic: "string()" is too long, let's use "str()". THEN: "str()" is too xenophobic, let's use "unicode()". THEN "unicode()" is too long, let's use "str()"
<alexgordon>
whitequark: it's kind of hard to balance safety with practicality
<whitequark>
guido: "you don't need map, therefore let's make it awkward"
<alexgordon>
heh
<whitequark>
alexgordon: it's not. everything is safe by default. at this time, it's not a question.
<alexgordon>
what about integer overflow!
<alexgordon>
division by zero!
<whitequark>
imo both should be checked
<alexgordon>
it depends really
<alexgordon>
in a game? no way
<alexgordon>
in a CRUD server? sure
<whitequark>
disagree
<whitequark>
what's a game? say an RPG? of course you want to check for overflows and div/0
<alexgordon>
I dunno, anything that does drawing can't use checked integers
<whitequark>
and if you mean something that heavily uses 3D... that will use floating point won't it?
<alexgordon>
not for loops and stuff
<whitequark>
not even 3D, powerful 2D libraries like cairo use floats too.
<whitequark>
loops. which loops?
<whitequark>
iterating over a collection? doesn't apply here
<whitequark>
when you have higher-order functions, you don't use bare loops all that much
<alexgordon>
lots of drawing code does stuff like "while (x is onscreen) { draw something }"
<whitequark>
still floats
<alexgordon>
there might be a counter
<alexgordon>
but anyway, it's just not really *necessary* in a game
<whitequark>
perhaps, but it doesn't hurt.
<alexgordon>
in a perfect world, any network code would be in a separate process, so it doesn't matter if the game process crashes
<alexgordon>
haven't quite got to that reality yet though
<whitequark>
are you interested in designing languages for perfect world? I sure not
eligrey has joined #elliottcable
<alexgordon>
yeah I always design for a perfect world, usually when you're done the world has caught up ;)
<alexgordon>
but anyway, you want to be able to turn checked integers off
<alexgordon>
but that kind of precludes linked libraries
<whitequark>
I don't think so
<whitequark>
well, there's two ways. first, you can record the flags in the compiled object. you should do that anyway.
<whitequark>
second, you probably shouldn't make that a global flag. enable that locally. no problem then.
<whitequark>
don't forget there might be code relying on checked integers for correctness and/or security
<alexgordon>
yeah but if your game can't use checked integers, you don't want your libraries to use them anyway
<eligrey>
are there any pnp (for windows) usb 3 802.11ac adapters?
<alexgordon>
eligrey: ur mom
<eligrey>
what do you guys use for 802.11ac on desktops?
<whitequark>
alexgordon: wat?
<eligrey>
(and no my primary link for my desktop isnt wireless im not that crazy)
<whitequark>
alexgordon: you don't make sense.
<whitequark>
there's no reason the fact your codebase is a "game" should prevent it from using checked integers in its entirety.
<whitequark>
I can see why you would want to avoid that on hot paths. most paths aren't hot.
<whitequark>
that is, I agree with the general sentiment that you should be *able* to turn that off for hot paths, but I don't see why you must be able to turn that off globally.
<alexgordon>
it's all fun and games until you have to drop down to C though
<alexgordon>
this is why people use C++!
<whitequark>
or perhaps because there's all sorts of libraries and C++ in general allows you to have realtime guarantees
<whitequark>
whereas most managed runtimes prevent that outright.
<alexgordon>
yeah well fuck managed runtimes :P
<alexgordon>
managed runtimes are the reason why I have to write games in C++!
<whitequark>
I wish I could burn things on people's foreheads. realtime isn't about "fast", it's about having a higher bound on the execution time.
<whitequark>
granted you usually want it to be fast too, but that becomes less and less of an issue with years passing.
<alexgordon>
well it's the object references that are the problem
<whitequark>
the boundedness however only becomes worse. it's one thing to GC 128K of memory, and it's another one to GC 16GB of it!
<alexgordon>
arbitrary mutable references, means a GC, means unpredictibility
<whitequark>
there are realtime GC's around
<alexgordon>
seems a bit like clean coal
<whitequark>
the problem with them is that they're generally much slower :3
<whitequark>
and often impose constraints of varying strictness
<whitequark>
e.g. Lisp got off incredibly easy in that area because it only has cells, therefore there's no fragmentation
<whitequark>
realistically you do have to worry about fragmentation and everything. I don't think you can truly write a modern game fully supporting hard realtime requirements, there's just too much to think about
<whitequark>
you just make sure the most problematic places are taken care of, and build the rest so it won't break catastrophically
<alexgordon>
games run the full gamut
<whitequark>
hm?
<alexgordon>
is that a mixed metaphor?
<whitequark>
what do you mean?
<alexgordon>
whitequark: angry birds vs call of duty
<alexgordon>
angry birds has no problem using a GC
<whitequark>
is that so?
<alexgordon>
it's kind of not optional on android
<whitequark>
I don't think they wrote their game in Java
<alexgordon>
even minecraft uses a GC, I wouldn't say it works well however
<whitequark>
pretty sure they did not, in fact
<alexgordon>
does it not run on android?
<whitequark>
you do realize android specifically supports native binaries for writing games?
<alexgordon>
nope
<whitequark>
well, it does
<whitequark>
it gives you a GL context and an input context and nothing more really
<alexgordon>
when I looked into that, I was told it's impossible -_-
<whitequark>
so the only thing you can write with that is a game
<whitequark>
note how most games don't include native UI. now you know why: you can't interact with Javaland from native very well
<whitequark>
and the UI is all written in Java
<whitequark>
find whomever told you that, and tell them they're a moron.
<alexgordon>
LOL
<purr>
LOL
<alexgordon>
well anyway, minecraft uses a GC
<alexgordon>
I forgot what we were arguing about
<whitequark>
managed runtimes
<alexgordon>
ah yes, nuke them
<whitequark>
minecraft experiences some hefty GC pauses
<alexgordon>
minecraft turns my PC into a heater
<alexgordon>
like no other game
<whitequark>
but JRE was never really written for games, keep that in mind
<whitequark>
it's written for noninteractive, high-throughput servers
<alexgordon>
I guess I just don't get the attraction of "managed runtimes"
<whitequark>
not goddamn physics engines
<alexgordon>
interpreted scripting languages like Python have charm
<whitequark>
well, closures don't work well with manual memory management
<alexgordon>
as long as you're not using say... numpy... they very useful for casual scripting
<alexgordon>
whitequark: that's possibly true, but most uses of closures are contrived
<whitequark>
lolwhat?
<purr>
lolwhat
<whitequark>
we were just discussing map like five minutes before
<alexgordon>
nah I mean REAL closures
<whitequark>
usefulness of higher-order functions without closures is... rather limited
<alexgordon>
not simply lambdas
<whitequark>
same thing
<alexgordon>
not really, lambdas don't need fancy memory management
<alexgordon>
it's just a function pointer
<whitequark>
it's a procedure then
<alexgordon>
it's when you start closing variables in the enclosing scope that things get complicated
<alexgordon>
*over
<whitequark>
as I've said, passing procedures to higher-order functions is rather useless
<alexgordon>
depends on the language
<whitequark>
not at all
<whitequark>
why would it?
<alexgordon>
in haskell most "function values" are partial application
<whitequark>
so, currying. that still requires closures
<alexgordon>
in objc you have stuff like GCD where a closure gets copied and stored in a queue
<alexgordon>
yes but the memory management ramifications are different
<whitequark>
how?
<alexgordon>
like I said, if a closure has no state attached, then it's just a function pointer
<alexgordon>
an int
<alexgordon>
there's no memory to manage
<alexgordon>
you don't need a GC for passing ints around!
<whitequark>
(+) 10 creates an object
<whitequark>
allocates memory for it somewhere. gotta free that.
<alexgordon>
it does because haskell is designed that way, but there's no reason why it should
<whitequark>
curried functions are completely equivalent to closures
<alexgordon>
(+) 10 is just int __plus10(int x) { return x + 10; }
<whitequark>
yes
<whitequark>
(+) n is what ?
<alexgordon>
more difficult
<alexgordon>
:P
<whitequark>
*facedesk*
<alexgordon>
although if n is an int, then it's just struct { int n; int(*__func)(int); }
<whitequark>
it's a closure, yay.
<alexgordon>
yes but the easy sort
<alexgordon>
__block int x = 1; dispatch_sync(^{ x = 2; });
<alexgordon>
in objc
<whitequark>
if you want, you can represent all mutability via cells
<alexgordon>
I'm not exactly sure what that code gives in fact o_o
<whitequark>
this way, even if the captured environment is a copy, you preserve the behavior
<alexgordon>
is it 1 or 2! it's like schrodinger's cat
<whitequark>
I believe it's 1
<whitequark>
but not sure
<alexgordon>
it's definitely 1 if you do dispatch_async
<alexgordon>
depends on whether the block is copied
<alexgordon>
by dispatch_sync
<whitequark>
ah, no, __block makes it visible outside
<whitequark>
encouraging people to use memory-unsafe languages is like encouraging people to write their own crypto
<whitequark>
with similarly disastrous results
* alexgordon
needs sleep
<alexgordon>
lifetime annotations is such an obvious solution, from a proglang designer point of view
<alexgordon>
it's a shame it just *sucks*
<whitequark>
it's still not memory-safe though
<whitequark>
if you can verify it, you can infer it
<alexgordon>
another problem is that it becomes part of the API
<alexgordon>
if you have different types of references
<whitequark>
that's a problem with anything that doesn't use a GC globally
<alexgordon>
I love that in C++ there's this concept of "const references" which *are* memory safe (as long as you don't do stupid shit) and ridiculously easy to use
<alexgordon>
but I do agree that that kind of thing can and should be inferred
<whitequark>
you should stop talking about memory safety when there isn't
<whitequark>
const_cast etc
<alexgordon>
that counts as stupid shit ;)
<alexgordon>
for the most part, if you use a const reference, it acts like the thing it represents, except that it's a pointer! the compiler copies if it needs to. everything is good
<whitequark>
yay, C++ discovers immutability
<alexgordon>
*exactly*
<alexgordon>
and without runtime cost
<alexgordon>
COUGH HASKELL COUGH
<alexgordon>
const references remind me of generators in python, how slick they are
<alexgordon>
I want more of that sort of thing in programming languages. less runtime heroics
* alexgordon
has lost the ability to talk about technical subjects