ELLIOTTCABLE changed the topic of #elliottcable to: #ELLIOTTCABLE — do something cool, shove it into throats, everyone thinks it's crap, then it's all amazing.
Sgeo has joined #elliottcable
PragCypher has quit [Quit: Leaving]
<cuttle> hi
<purr> cuttle: hi!
<ELLIOTTCABLE> cuttle: hi!
<ELLIOTTCABLE> alexgordon: here?
<alexgordon> ELLIOTTCABLE: yep
<ELLIOTTCABLE> whitequark: how's it one big security hole?
<ELLIOTTCABLE> whitequark: (mind you, I think it's *obvious* that it's not a real, or robust, security measure.)
<ELLIOTTCABLE> whitequark: I'm just curious about the specifics that you're aware of, since you're buried deep in Ruby implementation specifics.
<ELLIOTTCABLE> alexgordon: hi! (=
<alexgordon> what's one big security hole?
<ELLIOTTCABLE> alexgordon: Ruby's $SAFE
<alexgordon> don't know what that is
<alexgordon> oh wow that's horrible
<ELLIOTTCABLE> yep
<alexgordon> never run untrusted code unless: 1. you don't have a choice, 2. it's in a VM, 3. it's so simple that it's conceivable to interpret it safely, 3. it's in Chrome
<alexgordon> *4
<ELLIOTTCABLE> Chrome :D
<ELLIOTTCABLE> rather, V8.
<alexgordon> ELLIOTTCABLE: nah not V8 on its own
<alexgordon> e.g. chrome has sandboxed subprocesses
<ELLIOTTCABLE> idk, v8's got some sickeningly awesome sandboxing / security features, as well.
<ELLIOTTCABLE> dived into them *wayyyy* back when, when I was trying to get ryan dahl to include *actual* sandboxing in Node.
<ELLIOTTCABLE> it was totally possible. easy, even. Didn't require much in the way of changes to Node's core, at the time.
<ELLIOTTCABLE> but oh noooooes we had to have fucking revolting CommonJS compatibility bullshit.
<ELLIOTTCABLE> god forbid we sandbox evaluation of modules. god forbid that an_object !instanceof Object.
<ELLIOTTCABLE> alexgordon: hi!
<alexgordon> hi
<purr> alexgordon: hi!
<alexgordon> -spec @ alexgordon
<purr> alexgordon: Paws' half-arsed Version 10 specification <http://ell.io/ihQzs>
<ELLIOTTCABLE> m'kay
<ELLIOTTCABLE> alexgordon: what do you remember?
<ELLIOTTCABLE> (cuttle: might wanna wake up, if you're around)
* ELLIOTTCABLE breathes
<ELLIOTTCABLE> been a while since I looked at this doc. lol.
<purr> lol
<alexgordon> ELLIOTTCABLE: what was really helping me was that I was implementing it in C++ as I went along
<ELLIOTTCABLE> lost your imll?
<ELLIOTTCABLE> impl*?
<alexgordon> hold on lemme spotlight it
<ELLIOTTCABLE> okay. the types are easy. let's see if you remember the *framework* we'd built up, to discuss executions.
<ELLIOTTCABLE> you remember our graph masks?
<ELLIOTTCABLE> in Paws, all manipulable information in the program (data, as opposed to code) is stored in one big graph. Nodes are objects, and edges are relationships between objects. It's all homogenous.
<ELLIOTTCABLE> you remember that much, yes?
<alexgordon> yeah
<ELLIOTTCABLE> m'kay
<ELLIOTTCABLE> masks are exactly what (I hope) they sound like: a mask against that entire graph.
<ELLIOTTCABLE> i.e., they are a way of describing a *particular* sub-graph thereof.
<alexgordon> ah found it
<ELLIOTTCABLE> given foo: {bar: {a: 123, b: 456}} for instance, a mask might be able to describe foo: {bar: {a: 123 …}} (with the 456 node not being included in the masked-out sub-graph.)
<ELLIOTTCABLE> with me?
<ELLIOTTCABLE> cuttle: just discovered Gold Panda. Fan?
cloudhead has quit [Ping timeout: 264 seconds]
<alexgordon> ELLIOTTCABLE: that's not what I have in my implementation
<alexgordon> I just have struct Mask { Expr* expr; }
<alexgordon> ;
<alexgordon> but alright
<ELLIOTTCABLE> wat
<ELLIOTTCABLE> no, masks have nothing to do with expressions
<alexgordon> ELLIOTTCABLE: FTFA
<ELLIOTTCABLE> wasn't done, sorry, was waiting for you to read your old impl, and got distracted
<alexgordon> interface Mask
<alexgordon> readonly attribute Expression root
<alexgordon> your own words!
<ELLIOTTCABLE> hm, root should be an *object*, a piece of data
<ELLIOTTCABLE> ahhhhhh that's because I copy-pasted and fucked it up
<ELLIOTTCABLE> thanks D:
<alexgordon> haha
<ELLIOTTCABLE> yeah.
<ELLIOTTCABLE> okay.
<ELLIOTTCABLE> so.
<alexgordon> ok but that still doesn't explain how it can represent set operations
<ELLIOTTCABLE> instead of, for instance, storing every object that is within the Mask,
<alexgordon> since it's just one node instead of like... a mask
<ELLIOTTCABLE> (getting there)
<ELLIOTTCABLE> or, even storing the *boundaries* of a sub-graph, with anything within that graph being known-good,
<ELLIOTTCABLE> our masks are actually sort of ‘light’ masks.
<ELLIOTTCABLE> specifically, we leave describing the boundaries up to *the object graph itself*.
<alexgordon> how
<alexgordon> ?
<ELLIOTTCABLE> a given mask has a particular root-location in the graph, a node it “starts at”;
<ELLIOTTCABLE> and since the object graph is directed, it then implicitly flows outward to encompass all nodes it touches …
<ELLIOTTCABLE> … until it reaches the boundaries explicitly defined *in the data*.
<ELLIOTTCABLE> these boundaries are stored as “ownership.”
<ELLIOTTCABLE> clickyclicky. the Ownership heading.
<ELLIOTTCABLE> ick. hold n.
<ELLIOTTCABLE> was in the middle of re-naming EVERYTHING IN PAWS last time we stopped working.
<alexgordon> lol
<purr> lol
<ELLIOTTCABLE> was giving things clearer names.
<alexgordon> uh oh
<alexgordon> as clear as stratum?
<ELLIOTTCABLE> so, I'd like to replace the messy ownership/responsibility names with more alexgordon-familiar terms.
<ELLIOTTCABLE> remember Thing instead of Object, and whatnot?
<ELLIOTTCABLE> anyway.
<ELLIOTTCABLE> for now, ownership.
<alexgordon> I liked object though
<ELLIOTTCABLE> no, it *used* to be Thing.
<ELLIOTTCABLE> we changed it to Object, 'cause alexgordon.
<ELLIOTTCABLE> there's a bunch of stuff like that.
<alexgordon> ELLIOTTCABLE: depends on what the replacement is. sometimes a completely unrelated name can be good if it's a new concept
<ELLIOTTCABLE> ownership just hasn't been changed yet.
<alexgordon> less baggage
<ELLIOTTCABLE> yes!
<ELLIOTTCABLE> like execution.
<ELLIOTTCABLE> micah saved me from switching to “Continuation.”
<ELLIOTTCABLE> anyway.
<ELLIOTTCABLE> anyway. GOING ON.
<alexgordon> right
<alexgordon> I'm happy now that I have my C++ file
<ELLIOTTCABLE> so, these masks *start* somewhere, cascade through the directed edges of the graph.
<alexgordon> it has spinlock!
<ELLIOTTCABLE> and the other boundaries are described by not-responsible edges.
<alexgordon> (oh did I mention, I'm also trying to make it efficient and thread safe)
<ELLIOTTCABLE> (wait on that.)
<ELLIOTTCABLE> so. all edges in this graph are *annotated* with this concept of ownership.
<ELLIOTTCABLE> if <foo> has a directed link to <bar> in the graph,
<ELLIOTTCABLE> then <foo> knows *whether it owns* <bar>.
<ELLIOTTCABLE> in the spec text right now, that's called `isResponsible: true`
<alexgordon> man you know what this feels like?
<alexgordon> it feels like I've trained to be a lawyer
<alexgordon> passed my exams
<ELLIOTTCABLE> these masks of ours, describe a sub-graph by crawling the data-graph, and stopping at places where the edge is isResponsible: False
<alexgordon> then gone off for a year
<alexgordon> now I'm trying to read this alien script, that I used to *understand*
<ELLIOTTCABLE> stupid legalese. ;)
<alexgordon> cablelang
<alexgordon> esoliott
<alexgordon> ESOLIOTT!
<alexgordon> that's it
<alexgordon> ELLIOTTCABLE: I'm really itching to get to the bit where I GCD all the things
<ELLIOTTCABLE> GCD ALLLLL OF THE THINGS
<ELLIOTTCABLE> okay.
<ELLIOTTCABLE> moving forward, then!
<ELLIOTTCABLE> so.
<ELLIOTTCABLE> now that you understand the how, let's talk about the what.
<ELLIOTTCABLE> Basically, a mask is A Data Structure™.
<ELLIOTTCABLE> think `struct` in C.
<ELLIOTTCABLE> a mask might describe a whole Person.
<ELLIOTTCABLE> or, if Person has a Dog, then if we wanted, we could mask *down* to just the Dog.
<ELLIOTTCABLE> all depends on the root.
<ELLIOTTCABLE> but whether we're masking out the whole Person, or the person's Dog, or the dog's Name,
<ELLIOTTCABLE> our mask will *never* include the Person's Dog's Name's first-name-String,
<ELLIOTTCABLE> because the String *object* is not a part of that data-structure.
<ELLIOTTCABLE> understand?
<alexgordon> right ok
<ELLIOTTCABLE> so Masks, and the “ownership” of these graph-edges that define their boundaries, are a sort of dynamic “map” of the data-graph, showing the mutable boundaries between countries.
<ELLIOTTCABLE> between spheres of influence and interest.
<alexgordon> as long as a mask can be entirely described by its root object...
<alexgordon> as in it doesn't need additional information in the mask itself
<ELLIOTTCABLE> thus far, we've avoided having to do that.
<ELLIOTTCABLE> but that's why there's a Mask type. might need to make them a little more information-heavy later. *shrug*
<purr> ¯\(º_o)/¯
<alexgordon> k
<ELLIOTTCABLE> the original implementation allows multiple root-objects per Mask
<ELLIOTTCABLE> but there was never a situation where that was actually *usable*, so I've removed it from the spec.
<ELLIOTTCABLE> anyway.
<ELLIOTTCABLE> now. that's the how, and then the what.
<ELLIOTTCABLE> let's do the ‘why.’
<ELLIOTTCABLE> which is where we start to get into Paws' execution mode;.
<alexgordon> so this reactor stuff at the bottom, don't think I've implemented that yet
<ELLIOTTCABLE> (we're coming up on the beginning of new stuff, now; I'd only *partially* covered this last time we talked, from my skimming of what the spec has)
<ELLIOTTCABLE> yeah.
<ELLIOTTCABLE> that's what we were actively discussing.
<ELLIOTTCABLE> so, the ‘why’ of masks.
<ELLIOTTCABLE> Masks are our data-locking system for parallelism.
<ELLIOTTCABLE> when a given procedure (avoiding the term `execution` until we can talk about what that IS),
<ELLIOTTCABLE> when a given procedure is going to work with some data, it locks up that data so other parallelly-running procedures can't muck about with its series of operations.
<ELLIOTTCABLE> more specifically, we allow either: A) “multiple-sequential-read” (or MSR) reservations (NEW WORD NEW WORD IT'S PERFECT WHEEEE), or B) write reservations.
<ELLIOTTCABLE> (all pretty mundane stuff, I know.)
<ELLIOTTCABLE> when a procedure says it needs a write-reservation for a particular Mask, it's saying “I need to modify <this area-of-interest> in the data-graph.”
<alexgordon> k
<ELLIOTTCABLE> and then we can see which *other* procedures may have multiple-sequential-read reservations (i.e., are in the middle of preforming some sort of manipulation of *multiple, interdependent parts* of that data-structure), and we can avoid executing the procedure that needs to write, until that data-structure, that mask, is freed up again.
<ELLIOTTCABLE> pretty clear stuff, I hope?
<ELLIOTTCABLE> there's a really, really important note, hovering implicitly behind all of this:
<ELLIOTTCABLE> NONE of this has to do with concurrency. ALL of this is important in a fully single-threaded implementation of Paws.
<ELLIOTTCABLE> 'cause coroutines.
<ELLIOTTCABLE> (really, executions, but I'm gonna lie for a moment to explain it.)
eligrey has quit [Quit: Leaving]
<ELLIOTTCABLE> is my terminology okay? anything particularly confusing? please let me know, if so. trying to work on that. okay? okay.
<alexgordon> nope I think I get it
<ELLIOTTCABLE> once a procedure takes out a multiple-sequential-read reservation on a particular sub-graph, *because* we're an asynchronous language … or, to put it another way, because they're inherently coroutine-ish …,
<ELLIOTTCABLE> then they might get paused. I think it's called yielding with traditional coroutines.
<alexgordon> still trying to load all of this stuff back into my brain
<alexgordon> why oh why can't brains be like computers
<alexgordon> fopen for your noggin'
<ELLIOTTCABLE> if they *yield* in the middle of their manipulation of the data-structure, and thus get paused,
<ELLIOTTCABLE> then they might continue to hold that MSR reservation for an indeterminate period of time.
<ELLIOTTCABLE> that means that *no writes may happen*, even if that means hours of real-time.
<ELLIOTTCABLE> Paws' locks, then, are not ephemeral millisecond things, like concurrency locks are.
<ELLIOTTCABLE> instead of being concurrency constructs, they're *order of operations* constructs, for us.
<ELLIOTTCABLE> 'k.
<ELLIOTTCABLE> hold that in your head, if you can.
<alexgordon> yeah
<ELLIOTTCABLE> procedures that last over long periods of real-life time, having reservations on sub-graphs of the big 'ol all-pervasive DATAGRAPH™.
<ELLIOTTCABLE> that's a great picture of Paws. A little bit wrong, but we're getting very close.
eligrey has joined #elliottcable
<ELLIOTTCABLE> sorry, skimming the spec
<ELLIOTTCABLE> seeing what's there, what's missing.
<alexgordon> looks like I'll need to do some renaming up in this bitch
<ELLIOTTCABLE> okay, reservations, aaaaand …
<ELLIOTTCABLE> might just call that ownership.
<ELLIOTTCABLE> confusing if you know old-world paws, but clear if you don't, I think.
<ELLIOTTCABLE> need to get this in git, soon
<ELLIOTTCABLE> lazy, though. docs is working for the moment, and don't want to yak-shave until this is more complete.
<alexgordon> ELLIOTTCABLE: so Execution has changed a lot
<ELLIOTTCABLE> your implementation-type, you mean?
<ELLIOTTCABLE> don't worry. it'll change more, we haven't really discussed what it *is* yet.
<ELLIOTTCABLE> sorry, spec-work, keep talking, but I'm taking a break to multitask here before we talk more.
<ELLIOTTCABLE> (I like this pattern. Talk about things so you understand then, then take what I *learn* from teaching it, and use that to improve the spec. Rinse, wash, repeat.)
<alexgordon> it's gained a lot of new ivars
<alexgordon> root and stack, and now programCounter is a Node
<ELLIOTTCABLE> hm, it might be useful to Floobits this while you work, so I can see visually if you're coding up something that demonstrates a lack of understanding of some sort
<alexgordon> LOL
<purr> LOL
<ELLIOTTCABLE> keep trying to use vim controls.
<ELLIOTTCABLE> hi.
<alexgordon> er so
<alexgordon> I need to implement advance()
<ELLIOTTCABLE> questions arising that the spec doesn't answer?
<ELLIOTTCABLE> probably lots. lol.
<purr> lol
<ELLIOTTCABLE> -stop
<alexgordon> ELLIOTTCABLE: I think I asked this before but when it says
<alexgordon> "then we may presume that the Execution has been completed, and sort-circuit this algorithm with no result."
<alexgordon> what does no result mean
<alexgordon> returning NULL I presume
<ELLIOTTCABLE> link?
<alexgordon> ELLIOTTCABLE: not sure how to
<alexgordon> it's in advance()
<alexgordon> If the pc and the stack are both non-existant, then we may presume that the Execution has been completed, and sort-circuit this algorithm with no result.
<ELLIOTTCABLE> reading
<ELLIOTTCABLE> it's *meaningless* to advance a completed execution.
<ELLIOTTCABLE> so the return value can be whatever you want it to be in your implementation, as long as the only consumer of advance() can ascertain that that value *means* no-result.
<ELLIOTTCABLE> so yes, in a C++ impl, NULL is appropriate, I believe.
<alexgordon> ok but is it meaningless in that I should assert() it?
<ELLIOTTCABLE> no, it's not an error.
<ELLIOTTCABLE> advance() is not a public API.
<alexgordon> k
<ELLIOTTCABLE> it's a *part* of the reactor, but it's specified *outside of* the reactor.
<ELLIOTTCABLE> actually,
<ELLIOTTCABLE> yes.
<ELLIOTTCABLE> assert it.
<ELLIOTTCABLE> because the reactor should be checking if an execution is completed *prior* to advancing() it, and should never get around to doing so.
<ELLIOTTCABLE> that sounds reasonable to me.
<alexgordon> ELLIOTTCABLE: and another question: what happens if there's a stack but no pc?
<alexgordon> or can that never happen
<ELLIOTTCABLE> assert that as well, because that *definitely* shouldn't happen.
<ELLIOTTCABLE> here's why:
<ELLIOTTCABLE> that algo basically says, “move the PC forward until it's exhausted the procedure's code-block,”
<ELLIOTTCABLE> and *as the code-block deepens* (that is, within layers of parenthesis, I guess you can say), the stack gains unfinished work
<ELLIOTTCABLE> but as it exits the layers of parenthesis, it should *use up* items from that stack again.
<ELLIOTTCABLE> if the Script is remotely sane (i.e. it has the encoded-equivalent of balanced parenthesis … I guess, it has balanced depth,) then you'll never complete the Script (and thus have an empty pc) without having already previously emptied the stack.
<alexgordon> so in other words I can assert that there's a PC
<ELLIOTTCABLE> yep
<ELLIOTTCABLE> wat
<ELLIOTTCABLE> hm.
<alexgordon> and all that matters is whether there's a stack
<ELLIOTTCABLE> hm. you're right, implementation-wise. spec-wise, though, gotta handle that situation.
Sgeo has quit [Read error: Connection reset by peer]
<ELLIOTTCABLE> basically, it *makes sense* for an Execution to have an empty pc.
<ELLIOTTCABLE> but advance(), specifically, doesn't need to handle that situation, because nothing should ever be trying to advance() an empty Execution.
<ELLIOTTCABLE> anyway.
<ELLIOTTCABLE> not linguistic stuff, so moving on.
<alexgordon> okaaay next line
<alexgordon> "We'll define next as the Node after the pc within its immediately-superior Expression"
<alexgordon> so expressions need to keep track of parents too?
<alexgordon> I presume that's what you mean by "immediately superior"
<ELLIOTTCABLE> yes, but you don't need to keep track of the expression *in other expressions*
<ELLIOTTCABLE> unless you're doing so for performance reasons
<ELLIOTTCABLE> the simplest way is to crawl the Script again, because you implicitly have a reference to that
<alexgordon> ah k
<ELLIOTTCABLE> okay.
<ELLIOTTCABLE> Relations now have isChild,
<ELLIOTTCABLE> and the only term every used to refer to that, is “ownership.”
<ELLIOTTCABLE> a lot simpler nomenclature.
<ELLIOTTCABLE> structure A ‘owns’ structure B, if structure A has a `Relation` member that points to `B`, that is moreover annotated with `isChild: true`.
<ELLIOTTCABLE> cool. simple, I hope.
<alexgordon> I think it's getting late
<ELLIOTTCABLE> )'=
<ELLIOTTCABLE> aww
<alexgordon> can't decode 3c at all
<alexgordon> c. Now if, and as long as, the next refers to an Expression expr, we repeat the following until it no longer does:
<alexgordon> i. increase the length of the stack (leaving the new slot at the top of the stack ‘empty.’)
<alexgordon> ii. ‘increment’ next, such that it now pointing at the first word of expr
<ELLIOTTCABLE> reading it
<ELLIOTTCABLE> don't need to copy-paste, I have it open too ;)
<ELLIOTTCABLE> hm. well, ignoring i and ii, can you understand the loop being described
<ELLIOTTCABLE> we're repeating this until `next` is no longer nested, basically.
<ELLIOTTCABLE> i.e. diving as deeply “down” as we can, in one step.
<ELLIOTTCABLE> or, to re-phrase: the overall algorithm of (3) can only operate on *actual values*. If it reaches a sub-expression, it needs to dive into that sub-expression and operate on the first *value* in it, instead.
<ELLIOTTCABLE> (3.c) is a *loop*, because sub-expressions can be nested … that first-value inside the subexpression, may still be another expression.
<ELLIOTTCABLE> so we keep looking until we come to something that *isn't*.
<alexgordon> nah I still don't understand
<ELLIOTTCABLE> okay. code-time.
<ELLIOTTCABLE> `foo bar baz`
<alexgordon> what does increment mean?
<ELLIOTTCABLE> representing pc with a period
<ELLIOTTCABLE> adding an element to the stack.
<ELLIOTTCABLE> i.e., I guess, in C++, copying the stack to a new, one-element-longer, array.
<ELLIOTTCABLE> the last element, the new one, will be null-ish, still. ‘empty’ as the spec puts it.
<ELLIOTTCABLE> so. example code.
<ELLIOTTCABLE> `foo bar baz`, is our Script at first.
<ELLIOTTCABLE> pc is a period, so,
<ELLIOTTCABLE> `foo .bar baz`
<ELLIOTTCABLE> actually, will use v-bars
<ELLIOTTCABLE> `foo |bar| baz`
<ELLIOTTCABLE> advance():
<ELLIOTTCABLE> decide that `next` is |baz|,
<ELLIOTTCABLE> |baz| is neither an empty Expr, nor any Expr, so we use (3.d).
<ELLIOTTCABLE> okay. simple. now, let's wrap that up in an expression.
<ELLIOTTCABLE> `foo (bar baz)`.
<ELLIOTTCABLE> errr
<ELLIOTTCABLE> `foo bar (baz)`.
<ELLIOTTCABLE> we're at:
<ELLIOTTCABLE> `foo |bar| (baz)`
<ELLIOTTCABLE> let's evaluate advance()
<ELLIOTTCABLE> (3.a), `next` is |(baz)|
<ELLIOTTCABLE> (3.b) `next` is an expression, but it is not empty
<ELLIOTTCABLE> (3.c) `next` is an expression. so we need to *de-expression-ify* it.
<ELLIOTTCABLE> (3.c.i), our (currently empty) `stack` becomes an empty one-element array
<ELLIOTTCABLE> (that indicates that we're one sub-expression deep right now)
<ELLIOTTCABLE> (3.c.ii), `next` becomes |baz| instead of |(baz)| (we've “dived into” the expression).
<ELLIOTTCABLE> now, it's no longer an expression, so we don't need to loop. now it's an Object-type node, an actual value.
<ELLIOTTCABLE> so we break out of the loop and continue on to (3.d), with |baz| as our `next`.
<ELLIOTTCABLE> with me?
<alexgordon> yeah I think I get it
<alexgordon> but I need sleep
<alexgordon> o7 ELLIOTTCABLE
<ELLIOTTCABLE> kk
<ELLIOTTCABLE> sleep well
<alexgordon> unlikely!
alexgordon has quit [Quit: ["Textual IRC Client: www.textualapp.com"]]
Sgeo has joined #elliottcable
<prophile> NIXON'S BACK
mcc has joined #elliottcable
<ELLIOTTCABLE> prophile: wat
<ELLIOTTCABLE> cuttle: you around and awake?
<ELLIOTTCABLE> oh! hey! mcc! :D
<cuttle> ELLIOTTCABLE: yyyyyup
<ELLIOTTCABLE> -spec @ cuttle
<purr> cuttle: Paws' half-arsed Version 10 specification <http://ell.io/ihQzs>
<ELLIOTTCABLE> help me review this and clean up the mess that it is. It's a little out of sync, especially because I dumped a lot of paws-y-horrible terminology in the middle of writing it, and tried to re-write the entire thing in new terminology.
<ELLIOTTCABLE> so it's got a lot of bugs where the text is suuuuuper unclear, because it uses two sets of words to refer to the same concept. :x
<silentbicycle> b
<ELLIOTTCABLE> silentbicycle: hi.
<silentbicycle> so, as you were saying...
* ELLIOTTCABLE grins
<ELLIOTTCABLE> Paws. It's been my primary project (on and off, due to traveling a lot, but still) for the last three years or so.
<ELLIOTTCABLE> basically, I wanted to take pervasive continuations (almost, I'll explain in a second) and use them to design a programming language that was asynchronous, as Node was for networking stuff, but *inherently*.
<ELLIOTTCABLE> i.e. instead of callbacks, I wanted *every* procedure-call to be ‘asynchronous.’ Which, I know, doesn't make a lot of sense.
<silentbicycle> *listening*
<ELLIOTTCABLE> so. in the same way that undelimited continuations, when masquerading as functions (in R5RS Scheme, for instance), don't return, *all* ‘functions’ in Paws never return.
<ELLIOTTCABLE> which is such an ass-backwards solution by any standard in the plt community right now, I know. but I wanted to see where I could take it.
<prophile> actually having everything in CPS isn't that uncommon
<silentbicycle> ELLIOTTCABLE (not to interrupt, but I don't entirely understand delimited continuations. I have an inkling about what they're good for, enough to convince me that I should learn more, but haven't gotten to it yet.)
<prophile> chicken scheme's implementation works like that
<silentbicycle> right
<ELLIOTTCABLE> silentbicycle: I just finally grokked 'em the other night. It's not important here, because our continuations are explicitly *undelimited*.
<silentbicycle> I think what chicken does is a really cute trick, taking two tricky scheme implementation problems and using them to cancel each other out
<silentbicycle> okay
<ELLIOTTCABLE> but I'd be happy to chat about 'em with you, if you like. It's helpful to ignore the stupid-ass syntax that everybody, everywhere uses. It's also helpful to ignore the precise Computer Science™-y wording that everybody tends to use. They're really quite a easy concept.
<ELLIOTTCABLE> In fact, I'd say that I'd have an easier time teaching *delimited* continuations to a newbie, and showing them how to use them, than I would have teaching them traditional continuations.
<silentbicycle> I have a decent idea what delimited continuations are *used for* / why they're significant, but as it stands I couldn't implement them in C or something
<ELLIOTTCABLE> silentbicycle: oh? how so?
<ELLIOTTCABLE> I have a tab open about that, actually.
<silentbicycle> the Cheney on the MTA thing?
<ELLIOTTCABLE> ltu/4313
<ELLIOTTCABLE> which has two nice results:
<ELLIOTTCABLE> (Monadic Framework for DelConts)
<ELLIOTTCABLE> (famous)
<silentbicycle> scheme is supposed to have tail call optimization, and it's supposed to have garbage collection, and if you compile to C and make it so that every function is CPS-transformed
<ELLIOTTCABLE> and a talk from ICFO '09
<ELLIOTTCABLE> anyway. paws.
<silentbicycle> C, not having TCO, will eventually overrun the call stack. you intercept that, copy the values that are still live to the heap, and longjmp, and hey presto, you have TCO and you're using the C call stack as the first generation of a generational GC.
<silentbicycle> essentially.
<ELLIOTTCABLE> wat. that works?
<prophile> that's the chicken approach
<prophile> it's quite clever
<ELLIOTTCABLE> that's a hack of pretty *awesome* proportions.
<silentbicycle> there are a few bits that need to be adapted (it's not 100% portable) but it's quite clever, indeed
<silentbicycle> yeah!
<ELLIOTTCABLE> okay. I'm really, really bad at multi-tasking.
<silentbicycle> psh, nobody is good at it
<ELLIOTTCABLE> so delconts, and then you teaching me about CHICKEN, because I know nothing and wish to, are now on our stack.
<mcc> beware i live
<ELLIOTTCABLE> back to Paws.
<silentbicycle> yes.
<silentbicycle> (and there are a few other implementation details w/ chicken, but that's the gist)
<ELLIOTTCABLE> so.
<ELLIOTTCABLE> I've got a thing I call an “execution.”
<ELLIOTTCABLE> continuations are, at the highest level, best construed as “first-class representations of the call-stack at a particular point in the program,” I suppose.
<ELLIOTTCABLE> at least, that's close 'buff.
<silentbicycle> right
<silentbicycle> if it helps skip ahead, I feel like I've got a pretty good understanding of continuations, in the call/cc sense
<ELLIOTTCABLE> Executions, conversely, are “first-class representations of *a particular realization* of a procedure.”
<ELLIOTTCABLE> there's two important distinctions from normal conts:
<ELLIOTTCABLE> A), there's no concept of the call stack, or any *environment* at all, for that matter (which doesn't matter for us, because we never ‘return’ anyway.)
<ELLIOTTCABLE> and B), they *aren't immutable*.
<ELLIOTTCABLE> when you run some code via an execution, *since* that execution represents that code being run-through (what we call ‘realization’, being realized), that execution moves forward *with* the code.
<ELLIOTTCABLE> if the code completes without somehow being paused again, then the execution is no longer valid. the execution (of the code) is *over*.
<ELLIOTTCABLE> easy enough to grok, so far?
<ELLIOTTCABLE> laptop dying in a sec. gonna head up to my hotel room and plug it in.
<ELLIOTTCABLE> … yeah, that happened way sooner than I expected. Phone-IRCing while I finish my Bell's Best Brown.
<silentbicycle> I think so
<silentbicycle> yay Bell's
<ELLIOTTCABLE> So. Every running block of code in Paws, has a reference to itself.
<ELLIOTTCABLE> Not to the block, but to the *current execution of that block*.
<ELLIOTTCABLE> It can pass itself when calling other code; thus allowing that other code to resume it when it becomes paused.
<silentbicycle> okay...
<ELLIOTTCABLE> This is the only mechanism in Paws for "returning" results: CPS-y “resume this block with this result.”
<ELLIOTTCABLE> this has a bunch of interesting side-effects
<silentbicycle> but so, you have one primary thread of control, everything is just able to suspend and resume asynchronously on demand?
<ELLIOTTCABLE> actually, not necessarily. In a (rare) single-threaded implementation of Paws, pretty much; but Paws is designed to be massively-concurrent, as well.
<ELLIOTTCABLE> In general, most (or all) executions that *can* be realized, *will* be being realized simultaneously.
<ELLIOTTCABLE> More on that in a moment.
<ELLIOTTCABLE> There's some other aspects of the language that come into play here (our concurrency model and data-locking, and the tightly-integrated data-model that all this operates on)
<ELLIOTTCABLE> But: executions can be resumed multiple times, meaning that a procedure can have multiple "results"
<ELLIOTTCABLE> A common example of this would look something like;
<ELLIOTTCABLE> print(a_list.each)
<ELLIOTTCABLE> (To be compared with the more common explicit-CPS style of a_list.for_each {|item| print(item) } )
<silentbicycle> backtracking? is there a defined order?
<ELLIOTTCABLE> How d'y'mean?
<silentbicycle> multiple results
<silentbicycle> is there a defined order, like in Prolog (if only because of the implementation), or is it inherently nondeterministic?
<cuttle> ELLIOTTCABLE: u r makin it 2 complicat
<ELLIOTTCABLE> sorry, back
<ELLIOTTCABLE> cuttle: how so?
<ELLIOTTCABLE> cuttle: well, lemme finish. multiple cooks spoil the student, to mix some metaphors.
<silentbicycle> okay yeah sorry, don't let me sidetrack you, you were getting to the advantages of this approach
<ELLIOTTCABLE> not sure how you mean a defined order, beyond “the order that the copies of the execution are resumed”
<ELLIOTTCABLE> if A calls B, and B generates results, it can co-produce those results back to A, one at a time.
<silentbicycle> and I'm derailing you with "wait a minute, does this land near my mental map of how the Warren Abstract Machine works" which is not important
<ELLIOTTCABLE> or, to look at it another way, B can provide results as they come in, asynchronously, so to speak.
<silentbicycle> right
<silentbicycle> generator/iterator stuff
<ELLIOTTCABLE> re-ask later when I've explained more? yeah. that.
<ELLIOTTCABLE> mmhmm.
<ELLIOTTCABLE> everything is inherently a generator.
<silentbicycle> okay
<ELLIOTTCABLE> anyway.
<silentbicycle> much briefer derail: how familiar are you with 1) erlang 2) logic programming
<ELLIOTTCABLE> 1) none, and 2) very little.
<ELLIOTTCABLE> prolog is in my Next Three.
<cuttle> ELLIOTTCABLE: prolog is like
<cuttle> ELLIOTTCABLE: really really fucking simple, learn it in 20 minutes
<mcc> i'm curious about whether you could get erlangy concurrency/ message passing in a non-erlang language.
<ELLIOTTCABLE> Erlang, too, but not because of interesting-ness (as you put it yesterday, “This will be useful. Or, at the very least, interesting, and that's Good Enough for me.”)
<mcc> i was lucky enough to hear the erlang inventor guy give a talk a few months back
<ELLIOTTCABLE> cuttle: that's really good to know. Maybe I'll promote it to “Next after learning Haskell.”
<ELLIOTTCABLE> except, I want to learn APL/K.
<ELLIOTTCABLE> anyway.
<cuttle> learning erlang is very much not about erlang itself, but about the techniques and conventions and stuff that it encourages
<mcc> and the ideas in it sounded really cool
<cuttle> so you have to immerse yourself in erlang to benefit from learning it
<ELLIOTTCABLE> so, some of the common patterns for executions, you can guess.
<mcc> the thing he said that was mostly interesting to me was kind of
<cuttle> whereas prolog, you nod at it for an afternoon
<ELLIOTTCABLE> obviously, you can implement coroutines laughably easily.
<mcc> talking about the idea of the model of message-passing concurrency vs memory sharing concurrency
<ELLIOTTCABLE> then there's aping “returning,” which is also easy. although it's silently asynchronous to the caller; there's no way to force a synchronous form of calling
<mcc> and i was just like geez, it never occurred to me to think of memory sharing concurrency as a "model" and not just The Natural Way Of Things
<silentbicycle> mcc hah, yes
<cuttle> mcc: haha yeah
<ELLIOTTCABLE> there's returning-multiple, which is a really common alternative to the way you would iterate things in a more Rutty language.
<ELLIOTTCABLE> then, and this one is fairly important, there's “falseness.”
<silentbicycle> mcc except I think the whole "message passing / lots of little state machines" feels like The Natural Way of Things to me
<ELLIOTTCABLE> this language is still under design, and a lot of people are telling me not to do this, sooooo, consider it a big “maybe/probably” at the moment,
<cuttle> mcc: it's *ridiculous* how much people say concurrency is fundamentally a difficult thing, when they're assuming that the only way to do it is pthreads
<ELLIOTTCABLE> but in paws, falsehood is conveyed by non-execution.
<mcc> well i'm mostly thinking about
<mcc> ok so i'm trying to do EVERYTHING in lua these days
<mcc> lua has a problem
<mcc> it's like, generally incompatible iwth threading
<silentbicycle> mcc it has more than one problem, certainly
<mcc> but what if i could have a world like lua, where i have tons of little lua microprograms and pass tables between them…
<ELLIOTTCABLE> lua <3
<ELLIOTTCABLE> lua's so inspiring.
<ELLIOTTCABLE> so small, but such an excellent D/X.
<silentbicycle> mcc I think, in most cases, its design is very upfront about what it does poorly
<ELLIOTTCABLE> luau's what lisp never was or will be.
<cuttle> ELLIOTTCABLE: NO WE NEED TO HAVE A MORE VERSATILE WAY
<cuttle> ELLIOTTCABLE: BECAUSE BEING-DONE-AND-FALSE IS DIFFERENT FROM BEING-HALFWAY-DONE
<cuttle> ELLIOTTCABLE: AND BUBBLING IS FUNDAMENTAL IN PAWS SO WE CAN SOLVE IT LIKE THAT
<cuttle> i don't like lua because since it doesn't privilege one way of doing OO, etc., literally every library has a different class system
<silentbicycle> mcc look at lua lanes and a couple other extensions that do message-passing between different lua_States
<ELLIOTTCABLE> cuttle: bubbling? I'm still unclear with your definition of that.
<silentbicycle> mcc I'd rather use Erlang or something else in that situation, but I've got different trade-offs than you seem to
<cuttle> ELLIOTTCABLE: learn prolog *right now*, it will take you 10 minutes
<ELLIOTTCABLE> let's multi-thread these conversations.
<ELLIOTTCABLE> cuttle -> #Paws.Nucleus,
<ELLIOTTCABLE> silentbicycle: here.
<silentbicycle> ELLIOTTCABLE: I second learning Prolog, when you have the time and mind for it. it's really, really good at a few things, and really interesting
* ELLIOTTCABLE nods
<ELLIOTTCABLE> unfortunately, I've got about a thousand things to learn that are really, really interesting.
<ELLIOTTCABLE> but. I'll get there.
<ELLIOTTCABLE> very tippy-top of my list is finally fucking grokking Haskell.
<silentbicycle> ELLIOTTCABLE: I suspect it's most practical as a subset, either constraint/logic programming, or a database query language like datalog, or as something like Erlang, but mashing those all together leads to problems. but other people disagree with me there, and have reasons.
<cuttle> ELLIOTTCABLE: no, just ##paws
<ELLIOTTCABLE> Unfortunately, *learning* it, or a significant portion of the basics, did fuckall for me, there. I never understand any conversation that dives into Haskell, and that's half of the conversations I find myself involved in.
<ELLIOTTCABLE> so, time to waste a couple weeks of my life *making* things in it. ಠ_ಠ
<silentbicycle> cuttle and I like lua *because* it isn't opinionated about stuff
<ELLIOTTCABLE> cuttle: ##paws doesn't exist anymore, it redirects here
<cuttle> silentbicycle: well it doesn't make for a very fun experience
<cuttle> silentbicycle: obj:method is kind of ugly
<silentbicycle> cuttle I would rather have a language hand me the plumbing to make object systems and stuff, "see? there was never any magic to it"
<ELLIOTTCABLE> cuttle: that's one of the problems I'm trying to solve with Paws, rather obviously. We should talk more in-depth about that, some day
<cuttle> prolog is less of a programming language and more of just like a utility
<silentbicycle> cuttle: I'm kind of indifferent to that. I like the prototype / __index style of OO, or multimethods as in CLOS
<cuttle> silentbicycle: i like multimethods too
<ELLIOTTCABLE> multimethods <'3
<silentbicycle> for better and worse, prolog seems to treat EVERYTHING from the perspective of a search query
<cuttle> i think __index is a brittle hacky way of doing single dispatch
<cuttle> like, the way js and python and stuff do it, dispatch-as-lookups
<silentbicycle> which is really, really useful for certain things, and gets really, really freaking weird when things like IO come into the pictuer
<cuttle> on the object properties
<silentbicycle> picture
<ELLIOTTCABLE> a hybrid of prototypes and multimethods is my favourite flavour of OO
<cuttle> silentbicycle: yeah, IO is very ugly in prolog
<cuttle> basically because the only IO that was meant to be is questions and answers
<cuttle> ELLIOTTCABLE: look at atomo and slate
<silentbicycle> cuttle one thing I think lua does well is having all the semantic hooks in a "metatable" rather than __get__ / method_missing / yada yada on the objects themselves
<cuttle> silentbicycle: yeah that is cleaner
<ELLIOTTCABLE> atomo was alex's language, right?
<cuttle> no nono
<ELLIOTTCABLE> not alexgordon. suraci. yeah. just checked.
<silentbicycle> (uh, anyway, not trying to dominate the conversation here)
<ELLIOTTCABLE> I think I recall talking to him about this before he started on it … hem …
<ELLIOTTCABLE> maybe I'm mixing that up with somebody else's prag-lang
<cuttle> silentbicycle: nah don't worry :p
<silentbicycle> but I think one thing particularly interesting with Erlang's concurrency model is how the mailbox / receive / actors thing allows scheduling around dataflow
<ELLIOTTCABLE> we tend to be all over the map.
<silentbicycle> and there are some smart hacks there, like, the cost to send a message to a process is proportional to how big its message backlog is, so there's automatic counterpressure
<silentbicycle> flow control like that is crucial, but usually such an afterthought. and their whole design assumes that message sends can fail. the whole design is about explicitly acknowledging the possibility of failure in the platform design, not just bolting on exceptions or something
<ELLIOTTCABLE> okay. back to Paws, 'cause girlfriend wants my attention in a bit.
<silentbicycle> (there are also a lot of Prolog-isms in Erlang; I learned Prolog first, and that helped me get familiar with the syntax that seems to really irritate some people. though in all fairness, ruby's syntax really bugs me.)
<ELLIOTTCABLE> so, that's our ‘code’ type. basically, first-class program counters.
<ELLIOTTCABLE> data-types are pretty boring.
<ELLIOTTCABLE> we don't really provide much structure here: a bit like lua's tables, but with ordered-lists instead of object-maps being the inspiration for the core datatype.
<cuttle> silentbicycle: yeah paws is all about that too
<ELLIOTTCABLE> we've Objects, which are ordered-lists (à la JavaScript arrays, but without the fake-key-ness of indices) of references
<cuttle> silentbicycle: the failure system is gonna be deeply integrated and beautiful
<ELLIOTTCABLE> fuck exceptions ಠ_ಠ
<silentbicycle> a good knuckle tattooo
<mcc> silentbicycle: whatever "lua lanes" is sounds promising…
<mcc> silentbicycle: i really just … god damn it i want thread pools or some shit
<ELLIOTTCABLE> actually, our Objects might be best described as inside-out-JavaScript-Objects.
<mcc> i wanna be able to just start a long-running process
<ELLIOTTCABLE> instead of implementing arrays as faux-dictionaries,
<ELLIOTTCABLE> we implement dictionaries in arrays.
<silentbicycle> mcc also luaproc, I think there's a paper by Ierusalimschy on making multi-thread/process parallelism work with lua, they just don't want it in the core language. I can dig up the paper if you want
<cuttle> ELLIOTTCABLE: i feel like we should make that abstracted
<ELLIOTTCABLE> keys and values are simply another ordered-list; but the tooling to *treat* lists-of-key-value-pairs as dictionaries is built-in.
<mcc> and the reason i'm not interested in using erlang is i'm already writing software! concurrrency is one of several problems i need solved, i'm unlikely to switch languages to solve this one problem
<cuttle> ELLIOTTCABLE: if we *require* exposure of the ordered-list-ness to paws itself, that limits implementation opportunities for no reason
<mcc> thanks
<ELLIOTTCABLE> you want to make them unordered?
<ELLIOTTCABLE> the problem is I'm pretty dead-set on ordered-versioned-data being A Thing™.
<silentbicycle> mcc either this is it, or it's in the bibliography certainly: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.139.1000
<ELLIOTTCABLE> Like, it's not something I've talked about in here *at all*, because I'm also dead-set on not implementing any part of it in the Nucleus,
<ELLIOTTCABLE> but it's definitely going to be in the very first layers of Core.
<silentbicycle> mcc yeah, that's it. I couldn't get the luaproc lib to build, but I use weird platforms like OpenBSD and that's my problem :)
<ELLIOTTCABLE> i.e. `previous foo blahblahblah` instead of `foo blahblahblah` to work on the current-minus-1 value of `foo`.
<cuttle> ELLIOTTCABLE: well i mean that should be integrated with time travel and insanities
<ELLIOTTCABLE> hm
<ELLIOTTCABLE> we can talk about it, for sure.
<ELLIOTTCABLE> but. more importantly, none of this is stuff to discuss here. make an issue for it.
<silentbicycle> mcc erlang makes a lot more sense if you're primarily writing *servers*. for locally installed games or something it's an awkward fit
<ELLIOTTCABLE> when I'm talking about Paws to somebody who's new to it, I want a *consistent* feature-set to explain, even if it has bugs or considerations we haven't come to a consensus on, yet.
<ELLIOTTCABLE> so, I'm teaching silent bicycle Design-10. If you're right, and I kinda see your point re: insanities, that's something for a later iteration.
<silentbicycle> mcc Erlang feels like an embedded / telecom platform to me. which means it's a great fit for me personally, but I get why people don't like it.
<ELLIOTTCABLE> god, I hate having systematic autocomplete in my IRC. Worst part of switching to IRCcloud is having my IRC client try to “spelling-fix” somebody's goddamn nickname.
<ELLIOTTCABLE> 'k.
<ELLIOTTCABLE> so, Object == ordered-list of Relation.
<ELLIOTTCABLE> Relation references another Object.
<ELLIOTTCABLE> usually, you get ordered-lists that look like [ , [key, value], [key, value], [key, value] ]
<silentbicycle> ELLIOTTCABLE assuming ordered lists seems like a very useful property, but are sub O(n) collections fine? like, red-black trees / AVL trees / B+ trees / skiplists / etc? or are linked lists/arrays inherent?
<ELLIOTTCABLE> those are *treated* as dictionaries. (That is, you can look-up keys against them.)
<ELLIOTTCABLE> I don't discuss performance. It's a personal rule.
<ELLIOTTCABLE> There's plenty of *other* languages out there trying to iterate on our ability to have *fast* systems, as a whole.
<ELLIOTTCABLE> Nobody, anywhere, is putting enough effort into making languages that allow us to *develop* faster, though.
<silentbicycle> ELLIOTTCABLE okay, "treated as dictionaries" is the answer I was looking for. less about performance than general collection semantics.
<ELLIOTTCABLE> Big philosophy point of me. Drives plenty of people off.
<ELLIOTTCABLE> heh!
<ELLIOTTCABLE> basically:
<ELLIOTTCABLE> we're *designing a language* right now.
<silentbicycle> ELLIOTTCABLE I think pinning THAT down in important, and generally you can swap out a couple implementations unless you've painted yourself into a corner
<ELLIOTTCABLE> I won't remove any feature that adds *even the slightest bit* of ease-of-use due to vague performance concerns related to me,
<silentbicycle> ELLIOTTCABLE besides, focusing on performance first seems to get one stuck in local maxima designwise
<ELLIOTTCABLE> unless there are provable, *serious* (i.e. language-usefulness-impacting) effects to my desired design decision.
<ELLIOTTCABLE> I'd rather get a pretty specific design down,
<ELLIOTTCABLE> where all the design aspects are well-integrated for ease-of-use, something *coherent*,
<silentbicycle> ELLIOTTCABLE there's a really good quote I wish I'd saved verbatim w/ citation by Joe Armstrong (of Erlang), essentially saying, "I must program less efficiently, I must program less efficiently, that way I find real solutions" or somesuch
<ELLIOTTCABLE> and *then* we can begin trashing up the ease-of-use in carefully restrained ways, for performance concerns.
<silentbicycle> right
<ELLIOTTCABLE> sorry. I'm pretty dogmatic about a couple things. It's something people slowly learn to live with, I guess. )'=
<ELLIOTTCABLE> so. dictionary-ish ordered-lists.
<silentbicycle> I mean, there's certainly a case where if you include dynamism willy-nilly you can get stuck supporting the wackiness in Javascript or Ruby that makes efficiency hard, but you're still feeling out the design and I don't anticipate Browser Wars™ freezing your prototype
<ELLIOTTCABLE> *every* piece of data that you can deal with in-language, is that.
<silentbicycle> okay, cool
<ELLIOTTCABLE> if you get, say, a string-ish thing, it's still, from your point of view, an empty dictionary.
<silentbicycle> with a content attribute? or what?
<ELLIOTTCABLE> basically, yes.
<ELLIOTTCABLE> if you pass it to a native procedure that you've somehow acquired a handle on that *cares* whether things are strings, then *it* can know whether or not that's a string,
<ELLIOTTCABLE> but *you* can't, except by whether or not that fails.
<ELLIOTTCABLE> another controversial thing, so consider it a maybe for the moment.
<ELLIOTTCABLE> (basically, it comes down to “I don't want JavaScript typeofs, but I will put it in if I absolutely have to.”)
<ELLIOTTCABLE> so.
<ELLIOTTCABLE> really, really, really, core-to-Paws-philosophy/design observation here,
<ELLIOTTCABLE> is that the entire space of data/information/code relevant to a given program is one big graph, about which we are all-knowing.
<ELLIOTTCABLE> it's all homogenous, kinda lisp-y.
<ELLIOTTCABLE> and that brings us to the parallelism mechanisms (in fact, they're parallelism, concurrency, and control-flow, all in one mechanism.)
<silentbicycle> ELLIOTTCABLE (do you have much familiarity with escape analysis and other static analysis stuff, btw?)
<ELLIOTTCABLE> nope!
<ELLIOTTCABLE> I'm pretty easy to understand: I know nothing, and depend heavily upon a bunch of people smarter than me that I've pulled into my personal gravity-well to tell me when I'm wrong.
<prophile> smells a bit like perl's typing
<silentbicycle> (I mean, I don't want to shut you down with death-by-bibliography, but you'll probably find a lot of useful techniques there)
<ELLIOTTCABLE> cf. cuttle, alexgordon, prophile, cloudhead, inimino, whitequark …
<mcc> silentbicycle: well so first off i'm actually kinda interested in eventually writing my servers and clients in the same language… i a couple times very briefly got to do this with python and it's lovely
<mcc> silentbicycle: and yeah erlang was very much designed for a single purpose
<mcc> as i understand
<silentbicycle> mcc erlang is designed for systems that need to outlive the physical hardware they're running on, and need to be upgraded without interruptions to service. everything else is just details.
<prophile> erlang's single purpose is fault-tolerant computing
<silentbicycle> exactly
<prophile> everything else is just a side effect
<silentbicycle> a means to an end, yeah
ELLIOTTCABLE changed the topic of #elliottcable to: #ELLIOTTCABLE — “do something cool, shove it into throats, everyone thinks it's crap, then it's all amazing.” “everything else is just details.”
<silentbicycle> and it's this weird prolog-flavored distributed platform
<prophile> just it turns out fault tolerant systems are by necessessity scalable
<prophile> as what'shisface would argue
<prophile> the erlang guy
<silentbicycle> that I happen to find tremendously appealing
<prophile> armstrong, that's the guy
<prophile> joe armstrong
<ELLIOTTCABLE> Erlang'd make a great Paws server, actually.
<silentbicycle> erlang and lua both make very sharp trade-offs that fit the kind of problem domains I care about
<silentbicycle> ELLIOTTCABLE well, and there's Elixir and such that run on the BEAM VM
<ELLIOTTCABLE> Elixir certainly looks nice. Syntax-wise alone, I could lick it.
<prophile> CloudHaskell apparently exists
<prophile> no idea how well it actually works
<ELLIOTTCABLE> cuttle: just discovered EPROM
<silentbicycle> prophile the thing with Haskell is that it's based around the whole concept of there being a single "static" time,
<ELLIOTTCABLE> ick. Just got a 20-minute warning.
<silentbicycle> prophile like, "the typechecking runs with complete information, the program is accepted or rejected with (hopefully very meaningful!) errors"
<prophile> yeah
<ELLIOTTCABLE> silentbicycle: lemme cover this real quick, then I'll be gone for half an hour or so's
<silentbicycle> prophile which works brilliantly in many cases, but in a program that's distributed and being upgraded incrementally, it's inherently dealing with multiple "static" times
<silentbicycle> ELLIOTTCABLE okay sorry
<ELLIOTTCABLE> basically, Paws' entire trick is encoding concurrency information into the data, instead of into the code
<prophile> silentbicycle: oh I see
<ELLIOTTCABLE> it makes some trade-offs there, but it turns out to be fairly elegant
<prophile> I wasn't including the incremental code loading with CloudHaskell
<prophile> but there are papers on doing that sort of thing
<silentbicycle> prophile I wouldn't put it past them to have smart solution for this, they're certainly a clever group, but it's a hard problem
<prophile> I could listen to SPJ talks all day
<ELLIOTTCABLE> in that graph of data, we encode ‘ownership’ information into the edges between objects;
<ELLIOTTCABLE> basically, saying whether “this object we're relating ourself to, is a part of the same overall data-structure as us.”
<ELLIOTTCABLE> really generic example being { {'Elliott', 'Cable'}, 24, {'Chicago', {'Illinois'}} }
<ELLIOTTCABLE> the ‘name’ object is, generally speaking, a “part” of the overall data structure, so we annotate the edge between that top-level object and the name-object to say “this owns that.”
<silentbicycle> and it's unidirectional?
<ELLIOTTCABLE> then executions can preform basic locking tasks on sub-graphs of the overall program's data-graph, and gain *ordered* access to that data
<ELLIOTTCABLE> yep
<ELLIOTTCABLE> that's the only ordering system in place, at all. If you don't tell the language the relationships between your data, it'll assume there's no sharing of concerns amongst the sub-objects, and it won't meaningfully order operations happening to that data.
<ELLIOTTCABLE> (think that's something you brought up earlier; sorry, a little scattered)
<ELLIOTTCABLE> the locking I mentioned is really, really basic.
<prophile> if you pour acid on it
<prophile> it becomes salty
* ELLIOTTCABLE past prophile
<ELLIOTTCABLE> … pats. pats.
<ELLIOTTCABLE> we call it reservations: you can either ‘sequential-read’ reserve, or ‘write’ reserve.
<ELLIOTTCABLE> as long as you've got a write reservation on a sub-graph, nothing else can sequentially-read from that sub-graph.
<silentbicycle> would making it copy-on-write be advantageous?
<ELLIOTTCABLE> an important note is since this is our *ordering* system, and most tasks in Paws are very asynchronous by nature, these aren't ‘locks’ that last for milliseconds: they can easily last for hours.
<silentbicycle> I'm not sure I'm tracking you
<ELLIOTTCABLE> (i.e. in a server, if something is modifying a data-structure and is depending on a network-request's result to finish that modification, then nothing else can sequentially-read from that structure until the request completes.)
<ELLIOTTCABLE> mmmmm. what sounds confusing?
<ELLIOTTCABLE> cuttle: I need to ark D:
<ELLIOTTCABLE> afk*
<ELLIOTTCABLE> chellio demanding me.
<ELLIOTTCABLE> cuttle: can you repair all the damage this cook has done? ;)
<ELLIOTTCABLE> mmm. be back soon, ish. if cuttle's around, he can often explain my own design work better than I can.
<ELLIOTTCABLE> long story short, procedures operating on unrelated parts of the data-graph are automatically parallelized (‘automatically’ not even really being the right word, because that implies there's some sort of hard computation going on to determine how to do so. it's trivially parallelized.)
<silentbicycle> ELLIOTTCABLE I wonder if using persistent data structures and COW would mitigate some of the long locks. it sounds like you're setting yourself up for loooong, uncontrollable delays while things settle out.
<ELLIOTTCABLE> well, I like dynamism. a lot.
<ELLIOTTCABLE> dynamism of structure and interaction is a higher goal to me, than speeding up operations in the edge-cases where they *might* be able to operate safely on parts of a data-structure, while it's elsewhere reserved.
<ELLIOTTCABLE> cuttle: opinion on that? you've the knowledge-base here. I feel like making Paws' data-structures copy-on-write would trash up a lot of the dynamic interactions.
<silentbicycle> it is ... a point to carefully design around
<silentbicycle> I guess I'm morbidly fascinated by how systems break down, rather than how they operate under normal circumstances
<silentbicycle> look at me ending up working in embedded. somehow.
<silentbicycle> and liking erlang. surprise surprise.
<ELLIOTTCABLE> hah
<ELLIOTTCABLE> that's an excellent viewpoint to work from, though.
<ELLIOTTCABLE> I'm similar, but with the design and developer-experience of systems.
<silentbicycle> ...which is also to say, I hope I'm not coming across as overly critical, I'm just trying to feel out the edge cases
<ELLIOTTCABLE> nope. it's entirely appreciated.
<ELLIOTTCABLE> “Criticism, pull-req's, and issues, joyously appreciated.”
<ELLIOTTCABLE> 'k. brb.
<silentbicycle> do you have an implementation anywhere public? or is it still in the "you have to be familiar with the internals to use it" phase?
eligrey has quit [Quit: Leaving]
<ELLIOTTCABLE> silentbicycle: that's an interesting question, because it brings us to an important point about the project.
<ELLIOTTCABLE> silentbicycle: to illustrate, here's some “paws code.”
<ELLIOTTCABLE> *all of that code*, barely even ‘defines a procedure’ and ‘saves it to a variable’
<ELLIOTTCABLE> Paws, or at least what we've been talking about as “Paws,” isn't actually much of a user-facing programming language. it's more like a VM.
<ELLIOTTCABLE> but, unusually, it's a VM you target by *abstraction*, not compilation.
<ELLIOTTCABLE> this has nothing to do with the interesting-asynch stuff, though.
<ELLIOTTCABLE> Paws as a project is a combination of a couple philosophies.
<prophile> chiefly among which is zionism
<ELLIOTTCABLE> - minimalism. The core *language* has gone through a ton of “remove a feature we want, and re-implement it *in* the other features already provided” cycles.
<prophile> the core language contains absolutely no gentiles
wudofyr has quit [Remote host closed the connection]
<ELLIOTTCABLE> - dynamism / flexibility. Anywhere I can let you do things your own way, instead of the way *I* intend for you to, and that doesn't detract from the language's ability to cleanly/happily do it the way I intend for you to, then I'd rather leave you to do it that way.
<ELLIOTTCABLE> - zionism. There is one true god, and that god is ELLIOTTCABLE.
<ELLIOTTCABLE> /ht prophile
<ELLIOTTCABLE> so, what we've been talking about, the ‘Nucleus,’ is a high-level VM targeted by “languages,” or rather, groups of iterative abstractions.
<ELLIOTTCABLE> (of note, there's no syntax; that, too, is dynamic.)
<ELLIOTTCABLE> so. There's a working, but ugly, implementation of much of the stable parts of the Nucleus design.
<ELLIOTTCABLE> there's a couple other implementations underway.
<ELLIOTTCABLE> I believe cuttle has two, a partial one in haskell, and a partial one in Rust
<ELLIOTTCABLE> alexgordon is working in C++ as a learning exercise, as he's always had a bit of trouble wrapping his head around working in Paws' concepts
<ELLIOTTCABLE> and I'm working on one in (forgive me,) CoffeeScript.
<prophile> I like toast
<prophile> CoffeeScript isn't too bad
<prophile> I much prefer working in it to JS
<ELLIOTTCABLE> I'm also pretty dead-set on providing a Very Small, Very Portable implementation in ISO C. Have a lot of work on one, as a matter of fact, but it got put on hold a couple of years ago, and no longer cleanly conforms to the consensus of Paws' design.
<ELLIOTTCABLE> https://github.com/ELLIOTTCABLE/Paws.js is my new implementation, as of the last few months (not that I've had a lot of time for it, unfortunately.)
<silentbicycle> *catches up*
<ELLIOTTCABLE> silentbicycle: (in here, we call that -clouds)
<ELLIOTTCABLE> ;)
<silentbicycle> ah, okay
<ELLIOTTCABLE> -clouds, when you're reading scrollback, and -ground when you're caught up.
<ELLIOTTCABLE> relevant, because we have a mildly sentient bot.
<purr> that's me!
<ELLIOTTCABLE> prophile: I don't “much” prefer it, but I do use it at the moment by choice
<ELLIOTTCABLE> prophile: if nothing else, it prevents me from making my code too Elliott™
<ELLIOTTCABLE> lolwat, floating-point error in the Testling conformance graphic
<ELLIOTTCABLE> it seems to think Paws.js fails on Opera version 11.6000000001
<prophile> ELLIOTTCABLE: what, no right-aligned code and eldritch unknowable rules on newlines?
<ELLIOTTCABLE> prophile: Eldritch Newlines.
<ELLIOTTCABLE> prophile: only *ocassionally*. damn you, CoffeeScript. ;)
<ELLIOTTCABLE> this is pretty knowable code, yes?
<ELLIOTTCABLE> see, only *one* eldritch newline!
<prophile> surprisingly nice
<prophile> have you tried literate coffeescript at all?
<ELLIOTTCABLE> yep
<ELLIOTTCABLE> love the idea
<ELLIOTTCABLE> I want to do something very, very neat
<ELLIOTTCABLE> at the conjunction of docco-style documentation, litcoffee-style Literate Programming, and Paws' dynamic syntax.
<ELLIOTTCABLE> someday soon. (=
<silentbicycle> I'm still mostly tracking, though I'm not very familiar with node as a platform
<silentbicycle> for better and worse, I usually prototype this sort of thing in either lua, scheme (chicken or scheme48), or c
<ELLIOTTCABLE> silentbicycle: got distracted. what were we talking about?
<ELLIOTTCABLE> didn't even realize anyone was still talking in here (=
<silentbicycle> nobody even knows
<silentbicycle> I asked about implementation(s), there were pauses
mcc has quit [Quit: This computer has gone to sleep]
niggler has joined #elliottcable
<ELLIOTTCABLE> silentbicycle: re: where we were,
<ELLIOTTCABLE> no, there's no useful implementations. Only ones that exist to help further the design, basically.
<ELLIOTTCABLE> the only *fully operable* implementation is A) unreadable/uniterable, due to having evilly terrible code, and B) has no IPP, making it untenable for Real World Usage™
<silentbicycle> "IPP"?
<ELLIOTTCABLE> silentbicycle: interpretive preprocessor
<yorickpeterse> whitequark: re Reddit link, that's pretty accurate
fwg has joined #elliottcable
wudofyr has joined #elliottcable
fwg has quit [Ping timeout: 264 seconds]
<cuttle> sorry was marathoning dark knight trilogy
fwg has joined #elliottcable
<cuttle> -unclouds
<purr> cuttle: is no longer stuck up in the clouds.
<cuttle> ELLIOTTCABLE: i feel very strongly that we could make some huge leaps in usability in paws by:
<cuttle> simplifying the core data model to just sets of key-value pairs + hidden data
<cuttle> among other things, but that's the one on my mind
<ELLIOTTCABLE> On phone
<ELLIOTTCABLE> “Hm.”
<cuttle> irccloud needs regular refreshes so it doesn't get so laggy :p
<ELLIOTTCABLE> Hidden data?
<cuttle> ELLIOTTCABLE: as in ints and executions
<ELLIOTTCABLE> It's terrible in safari. Try chrome.
<cuttle> egh dark knight rises is starting
<cuttle> be back in 2 hours haha
<ELLIOTTCABLE> Oh )'=
<ELLIOTTCABLE> I'll be asleep
<cuttle> aw
<cuttle> :(
<cuttle> ok say things and i'll intermittently reply
<ELLIOTTCABLE> No
<ELLIOTTCABLE> Phone
<ELLIOTTCABLE> YOU say,
<ELLIOTTCABLE> I red and think
<ELLIOTTCABLE> ;)
<ELLIOTTCABLE> cuttle: I have an idea.
<ELLIOTTCABLE> cuttle: an idea you'll really, *really* like.
<ELLIOTTCABLE> Not really Paws. But, neat. Maybe a new tiny esolang based on this?
<ELLIOTTCABLE> idk.
<ELLIOTTCABLE> cuttle: hit me when you're here.
<cuttle> ELLIOTTCABLE: tell me idea :)
<cuttle> ELLIOTTCABLE: (also fact: lua tables use numerical indices to make arrays, and they are super optimized at it too)
<ELLIOTTCABLE> I care nothing for optimization, and everything for clarity.
<ELLIOTTCABLE> Anyway:
<ELLIOTTCABLE> We've been discussing adding information to the *code path*, for insanities obviously, and possibly for other purposes.
<ELLIOTTCABLE> Well, one of the original innovations of Paws, was making an execution of some code, first-class. deferrable.
<ELLIOTTCABLE> referrable*
<ELLIOTTCABLE> what if we did it again?
<ELLIOTTCABLE> make code-paths first-class.
<ELLIOTTCABLE> Have a duality of reference, two ways to refer to Where I Am:
<ELLIOTTCABLE> A) by the series of choices taken to get this code, into this state. ("Vertical" history, what are currently Executions.)
<ELLIOTTCABLE> B) by the series of code-paths that led to the current *set* of choices (“Horizontal” history.)
<ELLIOTTCABLE> If it becomes first-class, then it becomes exposed, and it obviously becomes *trivial* to an is-insane member to that structure, or an is-tainted
<ELLIOTTCABLE> Not to mention
<ELLIOTTCABLE> passing it around, and this abstracting on that
Sgeo has quit [Read error: Connection reset by peer]
<cuttle> ELLIOTTCABLE: not quite sure i understand
<cuttle> then again i really need to sleep :p
<cuttle> talk to you after sleep? :p
<cuttle> sounds like an interesting idea
yorick has joined #elliottcable
yorick has quit [Read error: Connection reset by peer]
yorick has joined #elliottcable
fwg has quit [Ping timeout: 264 seconds]
fwg has joined #elliottcable
PragCypher has joined #elliottcable
fwg has quit [Ping timeout: 264 seconds]
cloudhead has joined #elliottcable
fwg has joined #elliottcable
fwg has quit [Ping timeout: 240 seconds]
fwg has joined #elliottcable
fwg has quit [Ping timeout: 241 seconds]
PragCypher has quit [Quit: Leaving]
alexgordon has joined #elliottcable
vil has quit [Ping timeout: 260 seconds]
vil has joined #elliottcable
vil has quit [Ping timeout: 240 seconds]
vil has joined #elliottcable
vil has quit [Ping timeout: 260 seconds]
cloudhead has quit [Ping timeout: 260 seconds]
vil has joined #elliottcable
<joelteon> there was a really good youtube app for mac around somewhere
<joelteon> i feel like it had a french name
<joelteon> anybody know what i'm talking about
fwg has joined #elliottcable
<ELLIOTTCABLE> Nope.
<ELLIOTTCABLE> Hi, all.
fwg has quit [Quit: gone]
cloudhead has joined #elliottcable
niggler has quit [Quit: Computer has gone to sleep.]
sharkbot has quit [Remote host closed the connection]
sharkbot has joined #elliottcable
cloudhead has quit [Quit: Lost terminal]
cloudhead has joined #elliottcable
eligrey has joined #elliottcable
alexgordon has quit [Quit: Computer has gone to sleep.]
<cuttle> hi ELLIOTTCABLE
<cuttle> ELLIOTTCABLE: the optimization thing about lua numerical indices was neither here nor there; i just remember that they had really fast only-numbers-for-keys tables
<cuttle> ELLIOTTCABLE: but yeah the point is they do the whole numbers as keys thing
<cuttle> and it's great
<cuttle> ELLIOTTCABLE: so regarding your idea of first-class code-paths/call-stacks: I know smalltalk has a first-class call-stack that lets you do some cool stuff from within the language
<cuttle> ELLIOTTCABLE: but I think that the whole contagion system would be more elegant if we simply describe the way particular things bubble
<cuttle> and then let it happen
<cuttle> so we need to like, really concretely enumerate every way things can spread
<cuttle> this is another reason I want to have a way to specify dependencies without values, or maybe with void-values like empty lists of return values
<cuttle> for like
<cuttle> something happens when an operation is finished but has no return value
<cuttle> we also need to track that contagion
<cuttle> idek actually though
<cuttle> but yeah let's have void-values that represent doneness, and then they can bubble contagion just like anything else
alexgordon has joined #elliottcable
<joelteon> are you guys talking about paws again
niggler has joined #elliottcable
<devyn> yes they are
<ELLIOTTCABLE> hi
<ELLIOTTCABLE> cuttle: stilllllll not understanding what the fuck you mean when you use the word ‘bubble’
<ELLIOTTCABLE> joelteon: always.
<ELLIOTTCABLE> devyn: hi!
<cuttle> ELLIOTTCABLE: bubble up
<cuttle> ELLIOTTCABLE: contage
<cuttle> ELLIOTTCABLE: spread
<cuttle> hi devyn
<ELLIOTTCABLE> that seems backwards.
<cuttle> ._.
<ELLIOTTCABLE> to me, ‘bubbling up’ means something like the Node.js term, wherein it goes to *earlier* code
<ELLIOTTCABLE> i.e. bubbling an error ‘back up’ through callers' call-backs/catches
<yorickpeterse> VIM!: coffeeRegex is linked to rubySymbol
<ELLIOTTCABLE> whereas infection spreads to *later* code
<yorickpeterse> MAKES TOTAL SENSE
<ELLIOTTCABLE> yorickpeterse: oh hi.
<yorickpeterse> hai
<yorick> hi
<cuttle> ELLIOTTCABLE: ok well then don't call it bubbling
<yorickpeterse> yorick: hai
<yorick> joelteon: does your thingy have graphite for me yet
<joelteon> no
<joelteon> i wasn't supposed to tell you there's a free graphite server
<yorick> because there isn't.
<joelteon> well it's not released yet
<yorick> and it won't be free?
<joelteon> not sure if it will or not
<joelteon> but it's not "done"
<joelteon> i'm not a dev, idk
<yorick> I pressed the cancel my account button but it also didn't work.
<joelteon> huh
<ELLIOTTCABLE> graphite? what?
<ELLIOTTCABLE> cuttle: re-reading up above
<ELLIOTTCABLE> An-ten-nae.
<ELLIOTTCABLE> music :D
nicoou has joined #elliottcable
<nicoou> hihihi
<ELLIOTTCABLE> hihihi
jdhartley has joined #elliottcable
<nicoou> hihihihihihihiihihi
<ELLIOTTCABLE> mmm
<ELLIOTTCABLE> so what do you know of JS already?
<jdhartley> i figured you guys moved in here after people stopped asking me to make more jokes
<ELLIOTTCABLE> better yet, what *else* do you know already?
<nicoou> honestly
<nicoou> barely anything
<ELLIOTTCABLE> we never asked you to make jokes, jdhartley
<nicoou> html css
<ELLIOTTCABLE> you just made them anyway.
<nicoou> LOL
<ELLIOTTCABLE> need to cut my toenails, and go get my haircut. meh.
<jdhartley> purr do you love me
<ELLIOTTCABLE> and do laundry. so much shit.
<nicoou> okay like today my teacher gave me an assignment to style a WP blog
<nicoou> and use sass
<nicoou> but she didnt actually teach us how to use sass
<alexgordon> what is a nicoou
<jdhartley> SASS (if you're doing the SCSS syntax) is exactly like vanilla CSS but with extra cool stuff
<nicoou> yeah that's what i figured
<nicoou> i kinda tried to teach myself some stuff while we were supposed to be working
<ELLIOTTCABLE> fuck sass
<ELLIOTTCABLE> LESS <'3
<ELLIOTTCABLE> but: a teacher that makes you uses SASS? What world is this!?
<nicoou> ahahaha
<ELLIOTTCABLE> like, that's suuuuuuper forward-looking and edgy for a university
<jdhartley> LESS < SCSS to be honest
<alexgordon> jdhartley: cloudhead now hates you
<nicoou> she's good for being up to date with trends
<ELLIOTTCABLE> alexgordon: LOL
<nicoou> she just doesn't properly teach them and i end up googling and trying to learn them myself
<nicoou> but there's the other teacher who is trying to teach us yahoo pipes
<ELLIOTTCABLE> lol
<ELLIOTTCABLE> jesus, really?
<jdhartley> hey they had revenue this quarter
<ELLIOTTCABLE> I thought that died.
<jdhartley> lol
<nicoou> well he's trying to bring it back
<ELLIOTTCABLE> so.
<ELLIOTTCABLE> what *did* you learn about JS, then.
<ELLIOTTCABLE> tell me things that you learned, and remember, and think you understood.
<ELLIOTTCABLE> you don't have to sound smart, or remember perfectly. just give me your impressions from the class.
<nicoou> literally nothing that i can remember
<nicoou> there's some things that when i see, i kinda recognize but i have basically no real knowledge of it
<ELLIOTTCABLE> k. gimmie a min.
<jdhartley> I'm guessing almost everything you did was DOM stuff, or maybe even jQuery
<nicoou> some jquery
<nicoou> im finding my old notes or whatever just to see what he did "teach"
<jdhartley> thats all you need to know about JavaScript
<nicoou> LOL
<nicoou> oh yes these notes are golden http://d.pr/n/AvtW
<ELLIOTTCABLE> haven't the slightest idea, jdhartley, why any of those are weird to you.
<ELLIOTTCABLE> JS's got an object linked to the global context that you can index as any other object. And?
<jdhartley> it is recursive and fun
<ELLIOTTCABLE> as for the first, lol well? what's so strange about that? when a method returns identity, you can call the method on it again.
<ELLIOTTCABLE> lol nicoou
<ELLIOTTCABLE> oh gods. (=
<ELLIOTTCABLE> nicoou: well, luckily, we have a nice bot in here to help!
<ELLIOTTCABLE> purr: hi
<nicoou> oh god what
<ELLIOTTCABLE> >> console.log('hi')
<ELLIOTTCABLE> well, correction, then, we *sometimes* have a *sometimes*-nice bot in here, to *sometimes* help. ಠ_ಠ
<ELLIOTTCABLE> -start
<ELLIOTTCABLE> hi
<purr> ELLIOTTCABLE: hi!
<ELLIOTTCABLE> >> console.log('hi')
<ELLIOTTCABLE> who broke purr, damnit
<nicoou> ahaha
<jdhartley> purr hi
<purr> jdhartley: hi!
<ELLIOTTCABLE> purr: i love you
<purr> ELLIOTTCABLE: thank you! ^_^
<jdhartley> >> console.log('purr can you log this for me')
<purr> jdhartley: undefined; Console: 'purr can you log this for me'
<ELLIOTTCABLE> wow. wat.
<jdhartley> >> window
<purr> jdhartley: ReferenceError: window is not defined
<ELLIOTTCABLE> >> console.log('fuck')
<ELLIOTTCABLE> so, purr won't listen to me, but he'll listen to jdhartley
<ELLIOTTCABLE> can't say I saw that one coming.
<jdhartley> >> var x = 0; x++; console.log(x)
<purr> jdhartley: undefined; Console: 1
<jdhartley> >> alert('JD IS GOD')
<purr> jdhartley: undefined; Console: 'JD IS GOD'
<nicoou> oh my
<ELLIOTTCABLE> okay, stop confusing nicoou.
<jdhartley> sorry
<jdhartley> ill let you handle this. im going to get eat tacos with ellie
<ELLIOTTCABLE> nicoou: type some javascript code after ">> " to execute it. (=
<nicoou> im just sitting here giggling its ok
<ELLIOTTCABLE> jdhartley: o7
<ELLIOTTCABLE> so.
<jdhartley> l8r guys miss you already <3
<nicoou> bye jd
<ELLIOTTCABLE> first off, is there any other programming language you've learned anything about?
<nicoou> does html and css count
<ELLIOTTCABLE> and no, html isn't a programming language. it's what we call markup.
<nicoou> LOL
<purr> LOL
<nicoou> ok
<nicoou> i didnt think so
<nicoou> then nope
<ELLIOTTCABLE> well, how well do you remember variables from algebra class?
<ELLIOTTCABLE> solve for x, and all that.
<nicoou> somewhat well
<ELLIOTTCABLE> okay. Well, in math, variables don't have *time*, so it's not a perfect analogy (everything is presumably instantaneous in math … X just *is* 123, forever, it doesn't *become* 123 at some point.) … but we can start with that.
<nicoou> okay
<yorick> nicoou: so \ doesn't literally do that, it's an 'escape code'
<ELLIOTTCABLE> a *variable*, in a programming language like JavaScript or Ruby is basically a box.
<ELLIOTTCABLE> yorick: oh shush, don't spoil my nicole-soup
<yorick> the char after it determines the meaning
<nicoou> okay
<ELLIOTTCABLE> at any given point, a program has a big garage-wall with racks upon racks of boxes, and each box has a name that you've given it.
<yorick> ELLIOTTCABLE: it was wrong!
<ELLIOTTCABLE> in javascript, you create a new box, and give it a name, with what we call a “keyword.” (Keywords are special words that you type into the code, and have to type *exactly* right. Don't worry too much about that, right now, just copy what I show you verbatim.)
<ELLIOTTCABLE> the keyword to create a variable-box, is `var`
<ELLIOTTCABLE> for instance, `var name` or `var number_of_feet`
<ELLIOTTCABLE> that won't do anything for our nice little bot here, because it doesn't actually have any direct result. You're telling the program you'll need another box, but there's really no pretty way for you and I to look at that wall of boxes, and see that there's a new one.
<ELLIOTTCABLE> nonetheless, you can try it: `>> var name`
<nicoou> >> var name
<purr> nicoou: undefined
<ELLIOTTCABLE> there ya go
<nicoou> :D
<ELLIOTTCABLE> for our purposes, right now, undefined means “That's cool. I did that, and it was okay.”
<ELLIOTTCABLE> it also means “whatever you asked me to do, although it happened okay, it didn't cause any *results*.”
<nicoou> okay
<ELLIOTTCABLE> a bit like telling a friend it's your birthday. That's different from asking him for a gift; all he can say is “That's nice. Now I know!”
<ELLIOTTCABLE> so.
<nicoou> haha ok
<ELLIOTTCABLE> a box is rather useless without something in it. Just like in math, we're going to put numbers in boxes. You can do that with another ‘keyword,’ the equals-mark. `=`
<ELLIOTTCABLE> you put that *between* the name of the box, and what you're putting into the box.
<ELLIOTTCABLE> now, remember: programs have *time*, unlike math. In the code that runs *before* that line, where we fill the box, the box will still be empty. But in the code *after* that line, the box will be full, and we can look at the value in it.
<ELLIOTTCABLE> so, as an example, `number_of_feet = 2`
<ELLIOTTCABLE> (remember, you've gotta create the box, first.)
<ELLIOTTCABLE> can you combine those two, for me?
<yorick> ELLIOTTCABLE: it doesn't mean that :(
<ELLIOTTCABLE> yorick: shush, I'm teaching.
<nicoou> soo
<nicoou> do i need the var?
<ELLIOTTCABLE> (yorick: better to be well-understood and wrong, then right and *mis*understood.)
<nicoou> or just the ' = '
<ELLIOTTCABLE> just the latter, for now.
<ELLIOTTCABLE> but you need both lines of code.
<yorick> ELLIOTTCABLE: better be well-understood and right
<ELLIOTTCABLE> one tells the computer to create a box, and the next tells it to put a value in it.
<nicoou> oh ok
<nicoou> duh that makes sense
<ELLIOTTCABLE> (yorick: well-understood and right comes with time.)
<nicoou> >> number_of_feet = 2
<purr> nicoou: (number) 2
<ELLIOTTCABLE> you forgot the line where we tell the computer to make a box!
<nicoou> oops :x
<alexgordon> >> print "which language is this?"
<purr> alexgordon: SyntaxError: Unexpected string
<alexgordon> >> puts "which language is this?"
<purr> alexgordon: SyntaxError: Unexpected string
<alexgordon> >> console.log("which language is this?")
<purr> alexgordon: undefined; Console: 'which language is this?'
<ELLIOTTCABLE> unfortunately, in JavaScript, your code still worked. that's bad, though, because it did secret sneaky things that you don't understand, and that have *bad* consequences.
<nicoou> oh no
<yorick> ELLIOTTCABLE: put it in strict mode
<nicoou> >>
<nicoou> oops
<ELLIOTTCABLE> or, to put it another way: remember how I told you that “undefined” was the computer saying ‘Okay, I got it. <3’
<nicoou> yeah
<ELLIOTTCABLE> well, you're now learning the hard way, that sometimes the computer lies about that.
<nicoou> lovely
<ELLIOTTCABLE> if the computer was smarter, it would say ERROR ERROR, THERE'S NO BOX FOR NUMBER_OF_SHOES
<ELLIOTTCABLE> but the computer isn't smarter. it's dumb, and it's going to work very, very hard to confuse you.
<ELLIOTTCABLE> so it's up to *you* to remember to make that box, first, every single time.
<ELLIOTTCABLE> (I'll get to an explanation of what actually happened there, and why it's bad, later on =)
<nicoou> okay
<ELLIOTTCABLE> so. here's the ‘correct’ answer, that won't confuse the computer:
<ELLIOTTCABLE> || var number_of_feet
<ELLIOTTCABLE> >> number_of_feet = 2
<purr> ELLIOTTCABLE: 2
<ELLIOTTCABLE> (you can put multiple lines in here, if you put two v-bars before them: || like, || this, || whee)
<ELLIOTTCABLE> (you can also use the >> on the last line, if you want. you don't have to.)
<nicoou> oh okay i wasnt sure how to do that!
<ELLIOTTCABLE> it's okay. you didn't need to be. (=
<ELLIOTTCABLE> so. we talked a little about the left-hand side of that equals-mark, the boxes we put things into.
<ELLIOTTCABLE> it's a really good time to talk about the *right* hand side of that line, the stuff we *put* in boxes.
<nicoou> yes yes
<ELLIOTTCABLE> some of these are obvious: numbers, for instance.
<ELLIOTTCABLE> (I'm going to teach you *about programming*, as much as I can … but remember that *some* of this stuff is JavaScript-specific. For instance, the specific rules of what you type [we call that ‘syntax’] and some of the arcane, specific rules about how certain things work … that might all be slightly different in another language.)
<nicoou> okay
<ELLIOTTCABLE> in JavaScript, we really only have one kind of number. This isn't very compatible with the real world, where there's actually several *different* types of numbers that we deal with on a regular basis, not to mention many more flavours of numbers in more advanced mathematics.
<ELLIOTTCABLE> the type we have available to us is what programmers call a floating-point, or float. Mathematics calls similar stuff ‘the reals.’ I'll just call it a decimal.
<ELLIOTTCABLE> it can look like this: 1234
<ELLIOTTCABLE> or it can look like this: 42.8888
<nicoou> okay
<ELLIOTTCABLE> it can even look like several other things, such as -1.1e-10
<ELLIOTTCABLE> but that's besides our point, right now.
<ELLIOTTCABLE> those numbers are a thing that we can put in boxes.
<ELLIOTTCABLE> we call those things, “values.”
<ELLIOTTCABLE> so, we have, in our programs, as we've described them right now:
<alexgordon> omg ELLIOTTCABLE is going all teacher
<nicoou> this is fantastic, shhhhhh
<ELLIOTTCABLE> ‘variables,’ that we can create more of, and give names to; and then ‘values,’ that we can, at a particular point in time, store *into* a variable
<ELLIOTTCABLE> now, for a little side-track (we're still talking about values! I like values! there's lots more fun, useful types of values! so, we'll come back. believe me.),
<ELLIOTTCABLE> I want to tell you that I lied to you earlier.
<ELLIOTTCABLE> the answer when you asked if you needed the `var` keyword *and* the ` = ` keyword, both,
<ELLIOTTCABLE> is actually: “Both yes and no.” (whee! confusing!)
<nicoou> oh great
<ELLIOTTCABLE> as it turns out, you can *combine* the box-creation, and box-filling, stages. into a single line of code.
<ELLIOTTCABLE> so `var number_of_feet = 2`, all put together like that, is a perfectly sane way to both *create* a box, and put a variable in it, all at once.
<ELLIOTTCABLE> but it's very, very important to remember that you're doing two things, there.
<ELLIOTTCABLE> and only to do both at once, when you *need* both.
<ELLIOTTCABLE> there's plenty of situations where you'll want to create a box, but not put anything in it yet …
<ELLIOTTCABLE> … or, put a new value into a box you created earlier.
<ELLIOTTCABLE> so don't go all woozy on me, become lazy, and start typing out the whole thing every single time you put a value into a variable. You'll *always* want to remember, to keep those two steps separate in your head.
<ELLIOTTCABLE> (That's possibly the single most common, and single most confusing when it trips you up, mistake amongst JavaScript newcomers.)
<nicoou> okay
<ELLIOTTCABLE> so. try that, a couple times. define two different variables, and put useful decimal values in them.
<nicoou> separately?
<ELLIOTTCABLE> do whatever you think. I'll tell you if there's another way. (=
<nicoou> >> var box = 4
<purr> nicoou: undefined
<nicoou> || var pen || pen = 4.5
<nicoou> oops
<nicoou> >> || var pen || pen = 4.5
<purr> nicoou: SyntaxError: Unexpected token ||
<nicoou> :(
<ELLIOTTCABLE> hahaha
<ELLIOTTCABLE> don't worry, I didn't actually sit down and explain the bot to you. It's largely irrelevant, because it's not real JavaScript.
<nicoou> lol okay
<purr> lol
<nicoou> the way i got taught this kind of stuff was with alerts
<ELLIOTTCABLE> but, unfortunately, because I am a lazy-ass programmer and didn't take time to make it very accommodating, you *have* to put the || at the start of the message, and put each line in a new message
* ELLIOTTCABLE nods
<ELLIOTTCABLE> so, here's how you could make the bot understand what you just typed:
<ELLIOTTCABLE> || var box = 4
<ELLIOTTCABLE> || var pen = 4.5
<nicoou> ohhhhh okay
<ELLIOTTCABLE> (the bot waits a while before executing code, if it doesn't see the >>; so you can use that if you want to speed it up, like this:)
<ELLIOTTCABLE> >>
<ELLIOTTCABLE> >>
<ELLIOTTCABLE> bah
<ELLIOTTCABLE> >> ;
<ELLIOTTCABLE> oh, I forgot, the bot doesn't like me today
<ELLIOTTCABLE> well, it'll work for you. (=
<nicoou> hahaha
<ELLIOTTCABLE> anyway! you're on the right track.
<ELLIOTTCABLE> what you did, will work.
<ELLIOTTCABLE> but, again, there's a slightly easier way, for convenience.
<ELLIOTTCABLE> if you want to create a bunch of new boxes, all at once, you can put them on one line, separated by commas:
<ELLIOTTCABLE> var name, age, city, dogs_name
<nicoou> okay i think i knew that haha
* ELLIOTTCABLE nods
<ELLIOTTCABLE> I'm covering things you hopefully already know, even if you ‘learned them with alerts’ ;)
<ELLIOTTCABLE> but I'd like to cover it all in detail.
<ELLIOTTCABLE> make sure you know what's going on.
<nicoou> i appreciate it
<ELLIOTTCABLE> so, you can add alllll that up together, to make and fill a bunch of boxes very quickly, fairly easily:
<ELLIOTTCABLE> var height = 4, width = 3, depth = 0.25
<ELLIOTTCABLE> finally, I'll iterate one more time (and then leave it alone and assume you're a smart girl, and can remember it. lol.), that that's *two steps*: it's both creating new variables *and* then filling them, for each of those names.
<purr> lol
<nicoou> yes
<ELLIOTTCABLE> if you forget the `var` keyword, then you're only filling *existing* boxes … and as I mentioned before (but didn't remotely explain and thus probably confused you a lot), that's very very very bad.
<ELLIOTTCABLE> so remember that the first time you put stuff in a box, you need to make sure you're creating it … and then later, when you put *new* stuff in the box, you can reference it without creating a new one.
<ELLIOTTCABLE> so,
<ELLIOTTCABLE> || height = 4, width = 3, depth = 0.25
<ELLIOTTCABLE> is bad,
<ELLIOTTCABLE> but
<ELLIOTTCABLE> || var height = 4, width = 3, depth = 0.25
<ELLIOTTCABLE> || depth = 0.5
<ELLIOTTCABLE> is okay.
<nicoou> okay
<ELLIOTTCABLE> by the way yorick, this room is reduced-moderation, so *I* and the *bot* can see you in-channel.
<ELLIOTTCABLE> it only prevents other members from seeing unvoiced members; or, to put it another way, normal members only see voices and ops
<ELLIOTTCABLE> yep! (=
<ELLIOTTCABLE> SO.
<ELLIOTTCABLE> we're done with that side-track. back to values!
<ELLIOTTCABLE> numbers are easy. let's talk about something more fun, because we don't like math.
<cuttle> -unununclouds
<ELLIOTTCABLE> words. english.
<nicoou> haha okay
<ELLIOTTCABLE> you can put words into a program, as long as you put them between quotes:
<ELLIOTTCABLE> "like this"
<ELLIOTTCABLE> it's very important that you never forget the quotes, because computers are terrible at everything ever, and might not notice or might do really terrible things, if they think your words are actually code.
cloudhead has quit [Read error: Operation timed out]
<ELLIOTTCABLE> you might be noticing a pattern here: there's a couple things about *how you write down* code, that are very important. We call these things syntax, and they're so very stupid and horrible, but so very important, that you have to learn them PERFECTLY and EXACTLY, very early on. Which kind of sucks.
<nicoou> yeah i noticed that
<ELLIOTTCABLE> But, that being said, it's a good habit to get into: typing exactly the number of spaces that I type in something; not adding even a single extra character or letter even if it seems obvious … but more importantly, just paying *attention* to that stuff is a very important skill to have.
<ELLIOTTCABLE> stuff like not forgetting the word `var` before some boxes you're defining,
<ELLIOTTCABLE> or not forgetting to put the *second* quote-mark *after* your words.
<ELLIOTTCABLE> so. words.
<ELLIOTTCABLE> programmers call a series of words like that, inside quote-marks, a ‘string.’
<nicoou> i knew that!
<ELLIOTTCABLE> in a computer, that's just like a number.
<ELLIOTTCABLE> in fact, if you'd like, I can tell you *how* it's stored, in the real world, as a bunch of numbers.
<ELLIOTTCABLE> but the important point, is that it's a value that we're putting into a box.
<ELLIOTTCABLE> `name = "Elliott"`
<ELLIOTTCABLE> (you have probably figured this out by now, but I use `backticks` like `this`, to show you when I'm writing syntax … that is, when I'm writing exact characters that you have to pay special attention to, and type *exactly* how I typed them.)
<nicoou> yes
<ELLIOTTCABLE> just like numbers, there's really only one type of string in JavaScript, despite there being lots of types of words in real-life. Again, this is a huge failure of the language, and one that will eventually bite you. It's unfortunate.
<ELLIOTTCABLE> what you need to know right now, is that JavaScript's words are what we call “Unicode.”
<nicoou> okay
<ELLIOTTCABLE> that means there's a particular selection of possible words that you can write into them, a little bit like how you can store 3.3333 and 1597274 in a box, as a number, but you cannot store the square root of two, or pi. (those are irrational, and transcendent, numbers respectively, incase you're curious.)
<nicoou> okay
<ELLIOTTCABLE> for instance, I can store the letters A and E, and the digits 2 and 9, and even the kanji radical for dog, ⽝
<ELLIOTTCABLE> just like writing 3.3333, I can put all of those things between quotes, and they become a value:
<ELLIOTTCABLE> "A and E, 2 and 9, and my dog, ⽝"
<nicoou> okay
<ELLIOTTCABLE> there's one, important, and rather obvious, rule:
<ELLIOTTCABLE> I *can't* put the punctuation-mark for double-quote, itself, in there.
<ELLIOTTCABLE> because what's "Hi, I'm "Elliott Cable"!" mean to the computer?
<ELLIOTTCABLE> it doesn't know if the string is "Hi, I'm "
<ELLIOTTCABLE> or "Hi, I'm "Elliott Cable"
<ELLIOTTCABLE> or the whole thing, even with the exclamation point.
<ELLIOTTCABLE> this is where those escape-marks you wrote in your notes come in.
<ELLIOTTCABLE> but, fortunately for you, I'm not going to talk about them, because they're *really* unimportant.
<ELLIOTTCABLE> just write your strings without quotes inside of them, for now. (=
<ELLIOTTCABLE> moving on.
<ELLIOTTCABLE> quick pause before we get into more important stuff: anything remotely confusing, thus far? I hope not, but …
<nicoou> okay haha
<nicoou> nooo
<ELLIOTTCABLE> good, all easy.
<nicoou> yes
<ELLIOTTCABLE> I want to revisit something very, very important that I snuck in there.
<nicoou> okay..
<ELLIOTTCABLE> I said this, earlier.
<ELLIOTTCABLE> “just like writing 3.3333, I can put all of those things between quotes, and they become a value …”
<ELLIOTTCABLE> at the moment, the first half of the sentence was more important. But now, I want to talk about the second half.
<ELLIOTTCABLE> “… and they become a value …”
<ELLIOTTCABLE> this is another important thing to understand:
<ELLIOTTCABLE> just as the *variables* have time to them (that is, they don't exist <before>, and they do exist <after>), the same is true of the values themselves.
<nicoou> okay
<nicoou> kinda seems like common sense
<ELLIOTTCABLE> before the program runs the line of code that says “Put 1895 in box X,” the number 1895 doesn't exist.
<ELLIOTTCABLE> during that line, it's created.
<ELLIOTTCABLE> that creation, arising from a line of code like that, is called “a literal”
<ELLIOTTCABLE> (coming from the fact that you literally typed the digits of the number, into the code; and when it ran that line, the digits became a number, so that it could be stored.)
<nicoou> ok
<ELLIOTTCABLE> so now, we've gotten to the point where you can understand that there's *three, separate actions* happening in this line of code:
<ELLIOTTCABLE> >> var name = "Elliott Cable"
<ELLIOTTCABLE> First, a new variable is created, and labeled ‘name’
<ELLIOTTCABLE> Second, a new string is created, to hold the words “Elliott Cable”
<ELLIOTTCABLE> Thirdly, *that string*, that value, is stored in that new variable, that box.
<ELLIOTTCABLE> it helps, at these early stages, to think of this in non-code. Let's talk about shoes. Programs can't have shoes, so it's easy to lie about them.
<nicoou> haha okay
<ELLIOTTCABLE> We've got our garage-wall, covered in boxes. I want to make my own shoes, as a shoe-making hobbyist.
cloudhead has joined #elliottcable
<ELLIOTTCABLE> The very first step, is adding a new box, and labeling it 'my new shoes'
<ELLIOTTCABLE> the next step, is gluing together a piece of cardboard and some cloth, to make the most basic possible pair of shoes,
<ELLIOTTCABLE> and the final step, is putting those brand new barely-shoes-yet, into that box.
<nicoou> okay
<ELLIOTTCABLE> keep that analogy in your mind, we'll revisit it later.
<ELLIOTTCABLE> now, we're about to take a huge leap, and get exponentially more intellectually difficult.
<nicoou> uh oh
<ELLIOTTCABLE> it's still, hopefully, child's-play, for someone smart like you,
<nicoou> i guess we'll see haha
<ELLIOTTCABLE> but if you were lulled into a sense of security by the simplicity above, now's a good time to wake up ;)
<nicoou> no no that seemed to easy :p
<nicoou> too *
<ELLIOTTCABLE> let's ignore the boxes on the garage-wall, with their nice organized arrangement and their easily-identified labels, for a moment … and talk about a Thing™, with a capital T, some unidentified blob of stuffness, hovering in the middle of the garage. Just one Thing. The only Thing we care about in the world, right now.
<ELLIOTTCABLE> we're going to call a Thing like that, “an Object.”
<nicoou> okay
<ELLIOTTCABLE> the most useful property of an Object, is that it's very sticky. We can stick stuff to it, like glue. In fact, we stick stuff to it, and we give *that* a label, too, just like we were labeling boxes. (we programmers like naming things.)
<ELLIOTTCABLE> for instance, I can take this amorphous mass of Objectness, and stick a number to it.
<ELLIOTTCABLE> the same kind of numbers we were discussing earlier, these number-values that the computer has made out of our text.
<nicoou> okaay
<ELLIOTTCABLE> we can say that “On this blob, there's a slot named 'age', with 42 in it.”
<ELLIOTTCABLE> (a little bit like variables, right? don't be too sure, just yet.)
<ELLIOTTCABLE> but, those sticky blobs, with the named-slots you can stick things into, these Objects of ours, are *also* values.
<ELLIOTTCABLE> just like a number, (at least, like a number once it's actually been *created* by the computer), we can put that blob, in a box. ^)^
<ELLIOTTCABLE> ^_^*
<nicoou> okay..
<ELLIOTTCABLE> so, here's some more syntax for you, so, stuff you have to type exactly right:
<ELLIOTTCABLE> you list all of the things stuck to an Object, with the label you're giving them, inside two curly-brackets: `{ }`
<ELLIOTTCABLE> the label goes *before* a colon, and the value stuck to it goes *after* it:
<ELLIOTTCABLE> `{ age: 42 }`
<nicoou> okay
<ELLIOTTCABLE> that's called an “Object literal.”
<ELLIOTTCABLE> just like the string literals we were discussing above, the sticky blob gets *created*, only when that line of code is run. it doesn't exist until then.
<ELLIOTTCABLE> so, type me up a line of code that creates an Object, just like that.
<ELLIOTTCABLE> curly brackets, colons, a label, and a value of some sort.
<nicoou> >> { name: nicole }
<purr> nicoou: ReferenceError: nicole is not defined
<ELLIOTTCABLE> ohhoh
<ELLIOTTCABLE> you forgot your double-quotes :D
<nicoou> :x
<nicoou> oops
<ELLIOTTCABLE> tol' you that'd confuse the computer! ;)
<nicoou> i shouldve known that!
<yorick> also that would interpret as a statement
<yorick> wouldn't work
<yorick> >> { javascript: 'is evil' }
<purr> yorick: (string) 'is evil'
<nicoou> >> { name: "nicole" }
<purr> nicoou: (string) 'nicole'
<nicoou> yay
<yorick> explain that and good luck.
<ELLIOTTCABLE> hm. bot's got a hack to special-case object-literals, for teaching purposes, but it seems to be deactivated
<ELLIOTTCABLE> we were wrapping any code that didn't have a semicolon in it into an arbitrary expression.
<ELLIOTTCABLE> (can't be arsed to re-activate it, because doesn't matter right now)
<ELLIOTTCABLE> okay. back to nicoou.
<ELLIOTTCABLE> so, since these blobs are data, values, like numeric data or string data, we can store them in variables.
<ELLIOTTCABLE> can you figure that out?
<nicoou> i think so
<nicoou> the fact you're making them into literal *physical* objects is kinda helping
* ELLIOTTCABLE nods
<ELLIOTTCABLE> remember, you're *making these things*.
<nicoou> yes yes
<ELLIOTTCABLE> it's harder to explain with numbers, but it works really well with Objects, 'cause sticky blobs.
<nicoou> haha yes!
<ELLIOTTCABLE> you turn around, use your hands, put together a blob, and stick labeled-slots onto it one at a time, and *then* you turn around and put that whole lot into a box.
<ELLIOTTCABLE> and maybe wash your hands.
<ELLIOTTCABLE> 'cause nobody specified *what* made the blob sticky. >,>
<nicoou> LOL
<purr> LOL
<ELLIOTTCABLE> m'kay
<ELLIOTTCABLE> two quick iterations on what we've discussed, little new things:
<ELLIOTTCABLE> first off, you can stick more than one slot onto an object-literal at once
<ELLIOTTCABLE> again, commas … but this time *inside* the brackets.
<ELLIOTTCABLE> { name: "Elliott", age: 24 }
<ELLIOTTCABLE> so it goes { label: <value>, label: <value>, label: <value> }
<yorick> that will syntax error the bot
<nicoou> okay
<ELLIOTTCABLE> so, make an Object about *yourself*, and put it into a variable.
<ELLIOTTCABLE> go
<ELLIOTTCABLE> remember to be super-anal about syntax. look at every character you type, and wonder if you forgot something about the rules for using that character.
<nicoou> >> { name: "Nicole", age: 20 }
<purr> nicoou: SyntaxError: Unexpected token :
<ELLIOTTCABLE> heh
<ELLIOTTCABLE> you didn't make a box for it.
<nicoou> oh
<nicoou> derp
<ELLIOTTCABLE> notice that what the computer tells you is *never* relevant to what's actually going wrong. This is an excellent life-lesson for an aspiring programmer. ;)
<nicoou> i learned that when i tried to learn js the first time around haha
<ELLIOTTCABLE> riiiiight!?
<nicoou> ugh
<ELLIOTTCABLE> so, gogogo try again
<ELLIOTTCABLE> make a box and put that blob into it.
* yorick twitches
<nicoou> so id have to make a var, then put the object in it
<ELLIOTTCABLE> mmhmm!
<nicoou> || var box
<nicoou> >> || var box
<purr> nicoou: SyntaxError: Unexpected token ||
<nicoou> oh
<ELLIOTTCABLE> no, you had it right
<nicoou> okay
<nicoou> i wasnt sure
<ELLIOTTCABLE> the bot doesn't say anything until you're done (=
<nicoou> ooohohoohohooh
<ELLIOTTCABLE> (and if it doesn't know if you're done, it just waits a while.)
<nicoou> okay
<yorick> (and then throws your input away unless you changed that too)
<nicoou> || var box
<nicoou> || { name:"nicole, age:20 }
<ELLIOTTCABLE> yorick: actually, each user gets an execution-environment that's saved for a while.
<nicoou> oop spaces
<ELLIOTTCABLE> actually, I think that may be currently disabled, too. idk.
<nicoou> did it do that right?
<nicoou> i * wow words
<ELLIOTTCABLE> close, but no cigar, you made a box, and made an object, but never put the object *in* the box.
<nicoou> oh
<nicoou> i need the =
* ELLIOTTCABLE nods
<nicoou> i geeettt ittt
<nicoou> so
<nicoou> >> var box = { name: "Nicole", age:20 }
<purr> nicoou: SyntaxError: Unexpected token ILLEGAL
<nicoou> oh no its illegal :C
<yorick> okay, what.
<yorick> oh the upper input is still saved
<nicoou> does it HAVE to be multiple lines
<yorick> try it again
<ELLIOTTCABLE> hehehehe
<ELLIOTTCABLE> what yorick said.
<ELLIOTTCABLE> try it again.
<nicoou> i cant see what hes saying
* ELLIOTTCABLE nods
<ELLIOTTCABLE> but no, you did it exactly right.
<ELLIOTTCABLE> try it again so you can see the output properly. Just my bot's fault, that time. (=
<yorick> the output will be undefined because var statements don't return things
<nicoou> >> var box = { name: "Nicole", age: 20 }
<purr> nicoou: undefined
* ELLIOTTCABLE grins
<nicoou> ....
<ELLIOTTCABLE> (yorick: already explained that to her, remember? ‘That means everything went okay.’)
<ELLIOTTCABLE> so, great.
<yorick> that's... not... what it means :'(
<ELLIOTTCABLE> now that you've got all that percolating, let's step back to trivially easy stuff for a moment, and talk a little more about A) numbers, and B) values.
<ELLIOTTCABLE> so, we've been giving names to boxes, but not doing anything else with them.
<nicoou> okay
<yorick> (actually, statements can return something: with(box) name; will actually return something but it still can't be an expression)
<ELLIOTTCABLE> but the *point* of boxes, is that we can use the name of the box, and the *value* will be the stuff *inside* the box.
<nicoou> okay
<ELLIOTTCABLE> yorick: I'd bet ten bucks that I know more about JavaScript than you. so omigod PLZ, there's no need to correct what looks like I don't know what I'm talking about. I'm simplifying to teach the stuff she really needs to knowwwwwwwwwwwww ;_;
<nicoou> i can't see anything that he's saying anyways :p
<ELLIOTTCABLE> sorry. that was a bit assholeish of me. just irl stressed.
<ELLIOTTCABLE> luckily, teaching is über-calming.
<nicoou> hooray
<ELLIOTTCABLE> using the name of the variable, *means* the value inside the box.
<ELLIOTTCABLE> so if I've previously created a variable `name`, and it's got a value inside of it,
<ELLIOTTCABLE> then `var a_box_whee = name` will store … what, into a_box_whee?
<yorick> ELLIOTTCABLE: okay I didn't mean to correct you sir, I really have no idea why statements would return anything, too.
<nicoou> name
<nicoou> ?
<ELLIOTTCABLE> elaborate. use more words to say the same thing. (=
<nicoou> the value of name
<ELLIOTTCABLE> the value *currently in* name, but yes.
<ELLIOTTCABLE> excellent.
<nicoou> oh okay
<nicoou> because it can be changed
<ELLIOTTCABLE> yep!
<nicoou> k :D
<ELLIOTTCABLE> here's a couple new ones for you in quick succession.
<ELLIOTTCABLE> we're going to dive into the meaning of ‘an expression’ later, but for now, it's just some big words for “some stuff you type that *has a value*.”
<ELLIOTTCABLE> for instance, even though `name` is the label of a variable, it's *also* “an expression.”
<nicoou> okay
<yorick> also I challenge thee to a javascript duel? :D (but we leave out E4X.)
<ELLIOTTCABLE> the literal `1895` is *also* “an expression”, because that series of digits has a value (the number eighteen-hundred and ninety-five.)
<ELLIOTTCABLE> heh! someday, then :D
<ELLIOTTCABLE> (@yorick, not you, nicoou)
<nicoou> i figured
<ELLIOTTCABLE> the important thing, is that expressions *can be put together*, into more complex expressions
<nicoou> so as long as its got a value, then it is an expression..?
<ELLIOTTCABLE> and the entire mess, all together, still *has a value*.
<ELLIOTTCABLE> mmhmm
<ELLIOTTCABLE> here's a really simple example:
<ELLIOTTCABLE> 2 + 2.
<nicoou> so putting them together is like adding them
<ELLIOTTCABLE> ` + ` is a keyword, like ` = ` was … meaning you have to type it following particular rules
<ELLIOTTCABLE> but for this one, the rules are really easy.
<ELLIOTTCABLE> you put “an expression” (remember: anything having a value!) on both sides,
<nicoou> okay
<ELLIOTTCABLE> and the whole result, is a new expression.
<nicoou> so kinda like x+y = xy
<ELLIOTTCABLE> so, to put all of that into a succinct textual representation, I'm going to use some vertical bars to wrap up every “expression” in that example.
<ELLIOTTCABLE> (important note: this is NOT syntax. This is stuff I'm doing, to illustrate. It's like drawing on a whiteboard, but in text. You would never type this stuff into a JavaScript computer.)
<ELLIOTTCABLE> | |2| + |2| |
<ELLIOTTCABLE> thus, there's three whole expressions, there.
<nicoou> okay
<ELLIOTTCABLE> still moving forward …
<ELLIOTTCABLE> every time I've said you use a value, somewhere, before? What I actually meant, now that you know the words for it, was to use an *expression*.
<ELLIOTTCABLE> two places, in particular:
<ELLIOTTCABLE> A) the right-hand side of an ` = `, the part going *into* a box, can be any expression,
<ELLIOTTCABLE> and B) the data you're stuffing *into* a slot on a sticky-Object
<ELLIOTTCABLE> or, to put it in syntax,
<ELLIOTTCABLE> `number_of_feet = <EXPRESSION>` works for any expression you can think up,
<ELLIOTTCABLE> and `{ name: "Elliott", age: <EXPRESSION> }` works for any expression you can think up.
<ELLIOTTCABLE> now.
<ELLIOTTCABLE> got all that under your belt, a little bit?
<nicoou> i think so
<ELLIOTTCABLE> okay. I want to see if you can walk me through, in intimate detail, what the computer does, to run this line of code.
<ELLIOTTCABLE> (at least, given everything I've taught you so far.)
<ELLIOTTCABLE> don't be afraid, I guarantee you'll forget a few steps, but I'll prompt you. (=
<nicoou> oh man
<nicoou> okay
<ELLIOTTCABLE> var person = { name: "Elliott Cable", age: 21 + 3 }
<nicoou> so first the computer creates the variable, then it creates the object
<ELLIOTTCABLE> break down ‘creates the object’ for me.
<ELLIOTTCABLE> give me a few ‘sub-steps’ that it has to go through before it can put that sticky-blob into the box.
<nicoou> i was just typing it!
<ELLIOTTCABLE> (;
<nicoou> it creates the expressions "Elliott Cable," as well as the two values for age?
<nicoou> then adds up the age values?
<nicoou> then puts them in the object..
<ELLIOTTCABLE> you're on the right track!
<ELLIOTTCABLE> here's what you basically said, put another way:
<nicoou> then the object is put into the variable
<nicoou> okay
<ELLIOTTCABLE> it creates **five** values: First, the string-y value for |"Elliott Cable"|, then, the numerics for |21| and |23|,
<ELLIOTTCABLE> then, in ‘evaluating’ (the word we use for ‘figuring out the result of’ … see? e-VALUE-ating, or, ‘turning into a value!’)
<ELLIOTTCABLE> (er, |21| and |3|, typo above, my bad)
<nicoou> okay
<nicoou> you confused me for second lol
<purr> lol
<ELLIOTTCABLE> then, in ‘evaluating’ |21 + 3|, it has to create a new numeric value, for 25 (the fourth value it's created here)
<ELLIOTTCABLE> and finally, it creates an Object, and sticks two of those values to it: 25, and "Elliott Cable".
<ELLIOTTCABLE> so, try running my line of code.
<nicoou> ]>> var person = { name: "Elliott Cable", age: 21 + 3 }
<nicoou> >:C
<ELLIOTTCABLE> typo'd :x
<nicoou> >> var person = { name: "Elliott Cable", age: 21 + 3 }
<purr> nicoou: undefined
<ELLIOTTCABLE> okay!
<ELLIOTTCABLE> time to show you a neat little trick.
<nicoou> okay
<ELLIOTTCABLE> if you put *an expression* (remember, anything with a value) all by itself on the last line, and wrap it in parentheses, my bot will tell you *what that value is*.
<ELLIOTTCABLE> meaning, it will ‘evaluate’ that expression, and show you the final value.
<ELLIOTTCABLE> remember that a variable's *label* has a value?
<ELLIOTTCABLE> that means variable-labels are, themselves, expressions. so, that means we can do this:
<ELLIOTTCABLE> || var person = { name: "Elliott Cable", age: 21 + 3 }
<ELLIOTTCABLE> >> (person)
<purr> ELLIOTTCABLE: TypeError: object is not a function
<ELLIOTTCABLE> you have to do it, I can't; bot is broken for me today, as I mentioned.
<nicoou> || var person = { name: "Elliott Cable", age: 21 + 3 }
<nicoou> >> (person)
<purr> nicoou: TypeError: object is not a function
<ELLIOTTCABLE> okay, this one's on me, I guess. )'=
<nicoou> :o
<ELLIOTTCABLE> time for me to grab my USB key and SSH into the server.
<ELLIOTTCABLE> he's fucking up too much to be useful, give me a quick moment.
<nicoou> okie
<ELLIOTTCABLE> for the moment, while I deal with that, we're going to take a new tack.
<ELLIOTTCABLE> What kind of computer are you on?
<nicoou> macbook pro
<ELLIOTTCABLE> and what browser(s) do you use?
<nicoou> chrome safarai ff
<ELLIOTTCABLE> okay. have you used the Terminal before?
<ELLIOTTCABLE> (don't have to be an expert. Just knowing how to open it is enough for me.)
<nicoou> once or twice
<ELLIOTTCABLE> excellent.
<ELLIOTTCABLE> Open it now, and type the following.
<ELLIOTTCABLE> (any time I prefix a line with a standalone dollar-sign, it means “type this into the Terminal”)
<ELLIOTTCABLE> $ brew
<ELLIOTTCABLE> what does it say?
<nicoou> command not found
<nicoou> or specifically -bash: $: command not found
<ELLIOTTCABLE> mkay
<ELLIOTTCABLE> copy-paste the following in, exactly
<ELLIOTTCABLE> ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
<nicoou> hit enter?
<ELLIOTTCABLE> yep
<ELLIOTTCABLE> it'll ask you some questions. Answers should be pretty straight-forward; if they're not, ask me.
<nicoou> all it asked was for my pw
<ELLIOTTCABLE> m'kay, good
<nicoou> installed line tools for xcode and then said to type brew help?
<nicoou> im sure you knew it would do this though haha
<yorick> okay, why does it give that error, that's really weird
<ELLIOTTCABLE> mmhmm
<ELLIOTTCABLE> yorick: hm? why does what give which error?
<yorick> ELLIOTTCABLE: the object is not a function error, oh ASI