purr changed the topic of #elliottcable to: this is CLEARLY a cult.YEP
<
alexgordon>
there's a maximum of how much parallelism a system can take before you have "too much" and it gets slower because of all the overhead
<
glowcoil>
idk i guess this is not the lowest level language
<
glowcoil>
and also there'd probably be hooks to control that
<
whitequark>
it doesn't really make sense implicitly
<
alexgordon>
see, I think it's better to make it easy to pick off the low hanging fruit
<
whitequark>
you'd need a "sufficiently smart compiler"
<
alexgordon>
glowcoil: anyway we were talking about generators lol
<
alexgordon>
I forgot where we got to before we started talking about parallelism
<
glowcoil>
even without parallelism generators are great
<
alexgordon>
ok so if you take a function like map
<
glowcoil>
and the more flexible they are and thus the more places you can use them, the better
<
alexgordon>
you can have a parallel map
<
alexgordon>
and you can have a generator map
<
alexgordon>
parallel map is what it says: it splits the computation over multiple threads
<
whitequark>
or both at the same time
<
alexgordon>
whitequark: yes
<
whitequark>
let the language transform map with cps
<
whitequark>
if it's needed
<
whitequark>
scala can do that
<
alexgordon>
generator map is like in python: (f(x) for x in xs)
<
alexgordon>
this is making my head hurt already
<
alexgordon>
generators are mostly about memory rather than time
<
whitequark>
generators are about suspending control flow
<
alexgordon>
normal map requires O(n) extra space, whereas generator map does not
<
alexgordon>
whitequark: not to me
<
whitequark>
it's a special case of coroutines
<
glowcoil>
whitequark: or providing more neat places for it to flow to
<
glowcoil>
not really "suspending"
<
whitequark>
welp, then you have a different notion of generators than... everyone else? :]
<
alexgordon>
whitequark: I use generators to avoid allocating large chunks of space
<
glowcoil>
alexgordon: right, to interpolate two algorithms
<
alexgordon>
whitequark: e.g. you can have a generator that iterates recursively over a directory
<
glowcoil>
if one can start before the other is done
<
whitequark>
glowcoil: well, you suspend currently executing function and start executing something completely different
<
whitequark>
alexgordon: you can just make a language with external iterators
<
alexgordon>
whitequark: without requiring space for however many children and grandchildren that directory has
<
whitequark>
or, more like. what you describe is external iterators
<
whitequark>
generators can be used for conveniently implementing external iterators.
<
alexgordon>
whitequark: but when they're first class you can do cool shit like itertools
<
alexgordon>
e.g. chaining two generators together
<
alexgordon>
or filtering over a generator
<
whitequark>
can do that with just external iterators
<
alexgordon>
what's the difference then?
<
whitequark>
I mean, the external interface of a generator is that of an external iterator. what you describe all concerns external iterators only.
<
glowcoil>
i feel like this whole conversation has been unnecessarily hostile
<
whitequark>
the difference in the internals. external iterators maintain state explicitly
<
whitequark>
whereas generators maintain state explicitly by mimicking a closure
<
joelteon>
god, ruby fucking sucks
<
whitequark>
so external iterator is: class Foo; def init; @state = 1; end; def next; @state += 1; @state; end; end
<
alexgordon>
oh I see
<
whitequark>
and generator is: def generate; state = 1; loop { state += 1; yield state }; end
<
glowcoil>
i really like using scope for things
<
whitequark>
assuming yield doesn't work like it works in ruby but is a true generator keyword.
<
glowcoil>
ruby's yield is a little silly
<
alexgordon>
whitequark: "external iterators" is basically NSFastEnumeration in objc
<
whitequark>
I fully agree that external iterators is a wholly good pattern
<
whitequark>
glowcoil: I should have written that in python
<
whitequark>
to avoid confusion
<
alexgordon>
I mean they're pretty much equivalent in a sufficiently high level language
<
whitequark>
who are?
<
glowcoil>
whitequark: yeah was just making a semirelevant comment
<
alexgordon>
external iterators and generators
<
whitequark>
also "sufficiently high level" is a weasel phrase, don't use it
<
alexgordon>
"in the limit"
<
whitequark>
alexgordon: generators present an interface of an external iterator
<
whitequark>
they can't be equivalent
<
alexgordon>
so we can define the operations on a generator...
<
whitequark>
it's comparing apples and oranges
<
alexgordon>
1. yielding from a function
<
alexgordon>
2. yield froming from a function
<
alexgordon>
3. iterating over a generator
<
whitequark>
are you drunk?
<
alexgordon>
4. applying combinators to a generator
<
whitequark>
that doesn't make sense
<
alexgordon>
whitequark: -_-
<
alexgordon>
it makes sense in my head, which is a marvellous place
<
whitequark>
2. and 3. is "having a function next() which returns the values sequentially"
<
whitequark>
and 4. can be built around 2.
<
whitequark>
well, I'm assuming you're trying to make a minimal list of operations here
<
alexgordon>
I think the difference between us is that I always look at things from the perspective of a user...
<
glowcoil>
well if you want to define "the operations on a generator"
<
glowcoil>
that usually means like, inductively
<
whitequark>
alexgordon: same here
<
whitequark>
it's easier to grok a language concept if it's defined in minimal possible terms
<
glowcoil>
necessary & sufficient
<
whitequark>
easier to build abstractions based on it
<
alexgordon>
whitequark: but next() is an implementation detail
<
glowcoil>
ok fuckit i'm going to make hands
<
glowcoil>
and come back
<
alexgordon>
glowcoil: make hands?
<
whitequark>
alexgordon: only if you make it so
<
whitequark>
I mean, you can define generators like this:
<
whitequark>
1. has an interface of external iterator (next() function)
<
glowcoil>
alexgordon: my not-paws
<
whitequark>
2. maintains state implicitly via local variables and nonlocal control flow
<
alexgordon>
OH lol
<
alexgordon>
I get it glowcoil
<
whitequark>
you could of course tie these two orthogonal concepts together
<
alexgordon>
whitequark: your conception of a generator is so completely different to mine
<
whitequark>
i.e. 1. a thing which can be iterated, and maintains state implicitly via ...
<
glowcoil>
also it's going to be a lot easier to learn/write things in
<
glowcoil>
less of a turing tarpit
<
glowcoil>
just like hands are
<
glowcoil>
you
*can* pick things up and use them with paws...
<
whitequark>
alexgordon: as user, I'm interested in, say, writing map()
<
alexgordon>
whitequark: you use yield and for-in for that
<
alexgordon>
def map(f, gen):
<
alexgordon>
for x in gen:
<
alexgordon>
yield f(x)
<
whitequark>
okay, so it is exactly how I described: you've tied them together
<
whitequark>
I guess you can do so, it's wholly equivalent to my description
<
whitequark>
although
<
whitequark>
no, not really
<
whitequark>
alexgordon: how would you interleave values from gen1() and gen2() with your for..in ?
<
alexgordon>
you could do
<
whitequark>
loop { yield gen1.next() ; yield gen2.next() }
<
alexgordon>
well, it won't be nice :P
<
whitequark>
so I can write map()
<
whitequark>
but not zip()
<
alexgordon>
def next(gen)
<
alexgordon>
for x in gen:
<
alexgordon>
return None
<
alexgordon>
return x
<
alexgordon>
I see what you mean though, that requires gen to have state
<
whitequark>
as I've said: our descriptions are functionally equivalent :)
<
alexgordon>
which means it has to be a mutable reference
<
alexgordon>
whitequark: one way to do it (immutably) would be to return a new generator with the rest of it
<
whitequark>
alexgordon: so then you will have mutable local variables
<
whitequark>
except they're not mutable or local variables, but something completely different
<
alexgordon>
yeah but no references
<
whitequark>
no references ?
<
alexgordon>
ugh python is the wrong language for this example
<
alexgordon>
whitequark: awoidjaoiwdjoiawjd you know what I mean
<
alexgordon>
no mutable generators
<
alexgordon>
no references to mutable generators?
<
alexgordon>
something like that
<
whitequark>
it basically means that each time you enter a generator, you implicitly duplicate its state
<
whitequark>
and then you return it from next()
<
whitequark>
newgen, value = gen.next()
<
alexgordon>
heh yeah
<
whitequark>
well, this could work, except it completely breaks the way locals work in almost all existing languages
<
whitequark>
breaks the assumptions
<
whitequark>
also this would mean things like zip() perform deep copying of state
<
whitequark>
and this is horrible
<
whitequark>
each call to zip() would copy three states, which would copy more states maybe
<
whitequark>
screw that <>() shit
<
alexgordon>
it's C++
<
whitequark>
yes, screw that
<
alexgordon>
it's C++!
<
whitequark>
for explanation of functional concepts
<
whitequark>
screw C++.
<
whitequark>
absolutely.
<
alexgordon>
whitequark: anyway I kind lost the thread of what we were actually doing this for
<
alexgordon>
*kinda
<
alexgordon>
so you want to implement zip
<
alexgordon>
[A], [B] -> [(A, B)]
<
alexgordon>
so if we turn this into CPS
<
alexgordon>
hi vigs
<
vigs>
oh whoops wrong channel
<
vigs>
hi alexgordon :D
<
alexgordon>
vigs: I thought you just hated cps
<
vigs>
I'm not judging your cps, promise
<
alexgordon>
[A], [B], ([(A, B)] -> Void) -> Void
<
vigs>
okay THAT I'm judging
<
vigs>
(not really)
<
whitequark>
-> ⊥ :p
<
whitequark>
because they don't return
<
whitequark>
→ ⊥ actually
<
alexgordon>
erm [A], [B], ((A, B) -> Void) -> Void
<
whitequark>
alexgordon: no that's not cps
<
alexgordon>
no it isn't
<
alexgordon>
but it's what we want
<
whitequark>
that's a regular callback
<
alexgordon>
for a iterator generator thing
<
whitequark>
you have just described an internal iterator
<
alexgordon>
I KNOW
<
whitequark>
ok, you can't write zip() with internal iterators, kinda
<
whitequark>
show me next()
<
alexgordon>
for a list?
<
whitequark>
oh, wait, the input is not an iterator, it's just a list
<
whitequark>
so it doesn't compose. boring.
<
alexgordon>
whitequark: it could be an iterator
<
whitequark>
not an internal one
<
alexgordon>
why not
<
whitequark>
show me the implementation
* alexgordon
gets out the C++ again
<
whitequark>
in C++? now that's interesting
<
alexgordon>
(ps, I'm glad that you can read furrow!)
<
whitequark>
eh I'm not a good benchmark. I read all kinds of stuf
<
whitequark>
*stuff
<
whitequark>
brb writing postscript by hand
<
whitequark>
I actually need this for a good practical reason
<
alexgordon>
man C++ is ugly
<
whitequark>
omg if this file is being printed on paper less than size it wants, it'll print an angry message instead
<
whitequark>
whoever came up with US page sizes, fuck you and your shit
<
alexgordon>
whitequark: ah I get you
<
alexgordon>
need to make it proper cps
<
whitequark>
yes, I think that would be sufficient
<
alexgordon>
can't see how though
<
alexgordon>
something is VERY wrong LOL
<
whitequark>
alexgordon: the loop
<
whitequark>
you can't have loops with cps
<
whitequark>
make it a tail-recursive inner function
Sgeo has joined #elliottcable
yorick has quit [Remote host closed the connection]
alexgordon has quit [Ping timeout: 250 seconds]
Willox has quit [Read error: Connection reset by peer]
eligrey has quit [Quit: Leaving]
eligrey has joined #elliottcable
alexgordon has joined #elliottcable
alexgordon has quit [Quit: My iMac has gone to sleep. ZZZzzz…]
eligrey has quit [Quit: Leaving]
sharkbot has quit [Remote host closed the connection]
sharkbot has joined #elliottcable
gq has joined #elliottcable
yorick has joined #elliottcable
prophile has joined #elliottcable
Sgeo has quit [Read error: Connection reset by peer]
alexgordon has joined #elliottcable
prophile has quit [Quit: The Game]
<
whitequark>
hey ec
<
whitequark>
CVE-2014-0044 CVE-2014-0045
prophile has joined #elliottcable
prophile has quit [Quit: The Game]
<
alexgordon>
fuck yeah furrow
prophile has joined #elliottcable
<
alexgordon>
it's amazing, only TWO ERRORS
<
alexgordon>
hear that prophile ?
<
alexgordon>
JUST TWO ERRORS
<
prophile>
that's incredible
<
prophile>
just two errors?
<
alexgordon>
...I should really not check in generated code
<
alexgordon>
haha so many linking errors
prophile has quit [Quit: The Game]
<
glowcoil>
made it over the past two days
prophile has joined #elliottcable
<
alexgordon>
glowcoil: I can't log into my laptop :|
<
alexgordon>
literally I can't click the text field LOL
* alexgordon
tries logging in as a guest
<
joelteon>
do underscore and jquery play nice together
<
alexgordon>
joelteon: yes
<
alexgordon>
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
<
alexgordon>
"vtable for std::__1::__shared_weak_count", referenced from:
<
alexgordon>
std::__1::shared_ptr<Literal>::shared_ptr<Literal, void>(Literal*) in parser_generated-MShdYt.o
<
alexgordon>
std::__1::shared_ptr<LValue>::shared_ptr<LValue, void>(LValue*) in parser_generated-MShdYt.o
<
alexgordon>
iawjodijawdoijawd
<
alexgordon>
DIE C++
<
joelteon>
yay, cool
<
joelteon>
man it's amazing how many people have worked together to make javascript a little less awtful
<
whitequark>
not that much, about two hundred
<
whitequark>
brendan eich once described the cost of implementing all the modern js engines, it's surprisingly low
<
joelteon>
what is it?
<
prophile>
in australian dollars
<
joelteon>
so like $44.75
<
prophile>
something like that
<
aki_>
omg do I love jenn schieffer
prophile has quit [Quit: The Game]
<
alexgordon>
IAJWDOJAWD
<
joelteon>
ok, I don't get it
<
joelteon>
is that a jab at jquery, at web developers, or at the NSA
<
alexgordon>
it compiles
<
glowcoil>
joelteon: read the rest of jenn schiffer's articles on medium
<
alexgordon>
mmmm string literals
<
alexgordon>
the thing that no programming language ever gets right
<
whitequark>
oh fuck you
<
whitequark>
like, really
<
alexgordon>
lol whitequark
<
alexgordon>
I miss ELLIOTTCABLE
<
ELLIOTTCABLE>
I miss alexgordon
<
alexgordon>
thanks for reminding me
<
glowcoil>
ELLIOTTCABLE: <3
<
glowcoil>
ELLIOTTCABLE: did you hear my beat did you hear my beat
<
alexgordon>
glowcoil: while we're at it, wtf are \a and \b for?
<
alexgordon>
bell and backspace
<
glowcoil>
hahaha bell is sweet
<
alexgordon>
s/sweet/fucking annoying
<
glowcoil>
well ascii was originally to transfer like,
<
glowcoil>
every keyboard input over a network
<
glowcoil>
like, a series of keypress/status things
<
glowcoil>
like, beps are good for teletypes
<
glowcoil>
and \b is good for teletypes
<
glowcoil>
and \v too
<
glowcoil>
woefully useless now
<
alexgordon>
easy to add back escape sequences if people actually want them
<
alexgordon>
harder to take them away
<
joelteon>
\a is excellent
<
alexgordon>
think we can get rid of octal representations too
<
whitequark>
it's nice to imagine a line printer and vi when thinking about ascii
<
whitequark>
because that's exactly what it was developed for
<
whitequark>
anyway, it could be worse. we could still use ebcdic
<
alexgordon>
glowcoil: how about \^H
<
glowcoil>
alexgordon: haha what's that
<
alexgordon>
control code escape
<
alexgordon>
\^ then a letter
<
alexgordon>
\^H would be delete
* alexgordon
waits for whitequark to find a problem with it
<
whitequark>
alexgordon: ruby has \cH
<
whitequark>
or \C-H
<
whitequark>
or \C-\M-H for example
<
whitequark>
it's kinda obscure and rarely used gimmick which has strange implications for e.g. pretty printing and parsing
<
whitequark>
I personally would prefer to have two sequences: \xHH for hex anx \uNNNNNN for hex unicode codepoint
<
whitequark>
simple and efficient
<
alexgordon>
there's either too many or too few N's there
<
whitequark>
no, last codepoint ix 0x10ffff
<
whitequark>
hand in your unicode cred
<
whitequark>
to get it back, explain the difference between code unit, code point, character and grapheme
<
alexgordon>
I dunno I was just reading the python docs
<
alexgordon>
\uxxxxCharacter with 16-bit hex value xxxx (Unicode only)
<
alexgordon>
\UxxxxxxxxCharacter with 32-bit hex value xxxxxxxx (Unicode only)
<
whitequark>
>>> "\U10000000"
<
whitequark>
'\\U10000000'
<
purr>
whitequark: (string) 'U10000000'
<
whitequark>
wait, what
<
whitequark>
purr: why did you just reply
<
alexgordon>
purr does python?
<
alexgordon>
>>> print "hello world"
<
purr>
alexgordon: SyntaxError: Unexpected string
<
alexgordon>
>>> print("hello world")
<
purr>
alexgordon: undefined; Console: 'hello world'
<
alexgordon>
well that could mean anyting
<
whitequark>
>>> PYTHON_VERSION
<
purr>
whitequark: ReferenceError: PYTHON_VERSION is not defined
<
whitequark>
>>> VERSION
<
purr>
whitequark: ReferenceError: VERSION is not defined
<
whitequark>
*shrug*
<
alexgordon>
>> undefined
<
purr>
alexgordon: undefined
<
whitequark>
>>> shrug()
<
purr>
whitequark: ReferenceError: shrug is not defined
<
alexgordon>
>>> undefined
<
purr>
alexgordon: undefined
<
whitequark>
>>> undefined()
<
purr>
whitequark: TypeError: Property 'undefined' of object #<Object> is not a function
<
alexgordon>
I think it's javascript :P
<
joelteon>
>>> typeof typeof
<
purr>
joelteon: SyntaxError: Unexpected end of input
<
joelteon>
>>> typeof typeof undefined
<
purr>
joelteon: (string) 'string'
<
alexgordon>
whitequark: the real python says '\\U10000000'
<
whitequark>
yes, see above
<
whitequark>
oh, I was using 2.x
<
whitequark>
>>> u"\U10000000" File "<stdin>", line 1
<
whitequark>
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 0-9: illegal Unicode character
<
purr>
whitequark: SyntaxError: Unexpected string
<
whitequark>
purr: fuck off
<
whitequark>
anyway. there are only so many codepoints
<
whitequark>
I wonder why they even did UTF-32, UTF-24 is much more storage efficient
<
whitequark>
alignment likely
<
joelteon>
should've done UTF-18
<
whitequark>
they did
<
joelteon>
did they?
<
whitequark>
rfc4042
<
joelteon>
is that in python
<
alexgordon>
whitequark: so apparently in python you HAVE to have all 8 digits
<
alexgordon>
for \U
<
alexgordon>
but \u is more lax
<
whitequark>
alexgordon: yeah, usual python silliness
<
alexgordon>
oh wait, no \u has the same thing but with 4
<
alexgordon>
whitequark: I guess it would be strange if you typed in \U00000001
<
alexgordon>
and you got \001
<
whitequark>
they really should have dropped the first two zeroes
<
whitequark>
because they're
*always* 00
<
alexgordon>
whitequark: anyway, just type the code symbol into the file :D
<
alexgordon>
gostyle
<
whitequark>
that doesn't fly
<
alexgordon>
tell that to rob pike
<
whitequark>
editors may well want to transform the text. turn it from NFKC to NFD for example
<
whitequark>
I think apple text widgets do so
<
whitequark>
rob pike made a ton of silly decisions in go, and I'm saying this being fully aware who he is
<
whitequark>
I guess he just doesn't really care about unicode support that much
<
joelteon>
well go is for embedded systems isn't it
<
joelteon>
or is that another language I'm forgetting
<
alexgordon>
whitequark: LOL
<
whitequark>
go is a dsl for io-bound servers. not even a general-purpose language
<
whitequark>
alexgordon: at what?
<
joelteon>
must be another language then
<
alexgordon>
whitequark: rob pike not caring about unicode :P
<
whitequark>
yes, that is funny
<
whitequark>
I don't know how else to explain the fact you can't distinguish – and — in go source by looking at them
<
alexgordon>
erm anyway
<
alexgordon>
so what does ruby do for 32-bit unicode?
<
whitequark>
exception
<
alexgordon>
it breaks?
<
whitequark>
um? define "32-bit unicode"
<
alexgordon>
code points beyond ffff
<
whitequark>
no, it supports the entire range till 10ffff
<
whitequark>
it's only javascript that breaks
<
alexgordon>
but does it have \u and \U like python?
<
whitequark>
ruby's \u accepts any number of digits
<
alexgordon>
ah I see
<
alexgordon>
maybe the best way to do it would be to have \u take exactly 4, and \U take any number
<
alexgordon>
otherwise how do you type a unicode character followed by a literal digit?
<
whitequark>
"\u1234" + "123"
* alexgordon
chuckles
<
whitequark>
actually
<
whitequark>
in ruby
<
whitequark>
"\u{1234}"
<
whitequark>
I'd say just go with ruby's \u{} notation and make it the only one
<
alexgordon>
or have that and \u1234
<
alexgordon>
people kind of expect \u1234 to work
<
whitequark>
that'll do
<
whitequark>
stop obsessing over irrelevant minutae ;)
<
whitequark>
also who is glowcoil, I forgot it again
<
whitequark>
oh right, micah
<
alexgordon>
whitequark: lol I'm not obsessing, I was writing the lexer
<
whitequark>
I was kinda joking
<
joelteon>
ok guys, how does "a" "æ" "ag" sort
<
whitequark>
a æ ag
<
whitequark>
if you do the proper normalization dance of course
<
joelteon>
that's what I'm trying to do
<
whitequark>
here you'd need... NFD
<
joelteon>
NFC or NFD?
<
whitequark>
NFD, you need to decompose them
<
joelteon>
postgres doesn't support that
<
joelteon>
of course
<
whitequark>
actually, æ won't split to a and e
<
whitequark>
but Å would, for example
<
joelteon>
yeah, that's what I want
<
joelteon>
ugh, calling out to perl
<
joelteon>
that's gross
<
alexgordon>
woot it parsed
<
alexgordon>
I got hello world to parse in furrow
<
alexgordon>
this is a glorious day
<
whitequark>
"we took about 90 meters... and then blew all them up"