<Rurik>
I mean, it is not like one day you decided to wake up and thought I'd create a language
<alexgordon>
actually..
ec changed the topic of #elliottcable to: a
<ec>
Rurik: actually..
<Rurik>
that's exactly how it went?
<alexgordon>
pretty much
<alexgordon>
ec tweeted that he was making language, so we all got on Google Wave
<alexgordon>
and argued about it
<alexgordon>
then we all got on IRC, and argued some more
<alexgordon>
6 years later, still arguing
<alexgordon>
(plus a lot of dick jokes)
<ec>
Rurik: basically, I'd been interested in language-*design*, and the impacts it has on programming communities, for a long time
<alexgordon>
> 30 sin abs
<alexgordon>
"0.9880316240928618"
<alexgordon>
cool
<alexgordon>
> 30 ln exp
<alexgordon>
"30.000000000000007"
<ec>
I'd studied a few languages on a language-design level (as opposed to just using them heavily) before;
<ec>
most notably being intimately familiar with Ruby's semantics (from doing some suuuuuper-intense metaprogramming-y bullshit for fun)
<ec>
(that project was sort of my introduction to programming-languages being *fun* and *obscure* and *weird*, actually; before that I just wrote code to achieve a task)
<ec>
and on a syntax level, because parse.y was my introduction to programming-languages being a PAIN IN THE FUCKING ASS.
<ec>
after that I was introduced to Io, Scheme (lisp) R5RS (as an example of an absolutely *beautiful* language design / specification), and then the brand-new ES5 standard, as well
<ec>
notice, that throughout absolutely none of this did I give a shit about compiler design or performance or implementation, that's all much-more-recent-if-at-all
<ec>
for me, the *design*, the *interface*, the human considerations, were the driving factors.
<Rurik>
ec, how did you get to the point of being able to do anything you want with code?
<ec>
so shortly thereafter, the basic design for Paws came to me basically fully-formed (it's changed substantially *since*; but there wasn't a whole lot of holes in my original design, it wasn't really an … iterative process, at the start)
<ec>
Rurik: rephrase?
<alexgordon>
Rurik: write lots of it
<alexgordon>
and learn C
<alexgordon>
everything is easy after you know C
<ec>
alexgordon: eh, I hate points of view like that
<alexgordon>
well C is like... the top of the mountain, then after that it's all downhill
<ec>
that's what I mean: like, not really
<ec>
C can be a little difficult to use, in a similar way to Bash: it lets you shoot yourself in the foot; and not in inevitable-danger-to-have-powerful-tools ways, just, it's-badly-designed / they-didn't-know-about-modern-practices way
<ec>
but none of those properties and neither of those languages is some *pinnacle* of Programming™ as an art
<ec>
just like ‘assembly’ isn't some pinnacle (another point of view I absolutely despise)
<ec>
tool usage, or the learning of tools, is *not* the difficult problem in programming. In fact, it's so very *far from* the Difficult Problems of software development, that it's almost a joke
<ec>
except it's not a joke because we indoctrinate our newcomers into thinking that's some end-goal, that once they've reached it, they'll Be Real Programmers
<ec>
or worse, that any person who *has* reached it, is someone to listen to and admire
<ec>
the hard problems in programming have *no* association with any particular tool.
<ec>
“8:06 PM <Rurik> ec, how did you get to the point of being able to do anything you want with code?” what do you mean by that?
<jfhbrook>
oh man ec have you ever looked at cobol? speaking of "didn't know about modern practices"
<jfhbrook>
cobol was being used to write CRUD apps before separation of concerns was invented
<jfhbrook>
just imagine that for a minute ^__^
<jfhbrook>
also: I understand good tooling is Nice(tm)
<jfhbrook>
also: have you *used* maven? XD
<ec>
jfhbrook: oh lord
<ec>
jfhbrook: and, what about maven / tooling? sorry, which of my statements were you replying to?
<ec>
Rurik: come baaaaack
<ec>
I have gyro meat, Dr. Who, Paws to write :3
<jfhbrook>
ec: writing to disk and writing to screen were accomplished in almost exactly the same way (writing to known positions inside struct/buffer-like things)
<jfhbrook>
ec: that was a joke---you said that learning tooling isn't a hard problem, but maven's kind of a pain in the ass to figure out
<jfhbrook>
(I can copy-paste-from-stack my way out of that one though, so maybe not *that* hard)
<ec>
oh lollll
<purr>
lollll
<ec>
hi jfhbrook u wna hear aboot paws
<alexgordon>
ec: C is the essence of everything, because everything is written in C
<alexgordon>
like everything in javascript reduces down to v8, which is C++
<alexgordon>
as soon as you know C, then you can understand the whole stack. it never gets any more difficult than C, just more complicated
<jfhbrook>
I'll learn a lil' about paws
<jfhbrook>
I'm bad at learning languages and I'm pretty sure I'm gonna take the plunge on go this break, but
<jfhbrook>
I can appreciate a language feature
meowrobot_ is now known as meowrobot
<alexgordon>
ec: e.g. if you only knew Python, then there would be _some_ problems that can't be reasoned about. e.g. how do you reason about multithreading in Python? It's single threaded...
<jfhbrook>
I mean
<alexgordon>
whereas everything in Python turns into some trivial concept in C. python object? a struct with a hash table
<jfhbrook>
true insofar as the GIL is concerned
<jfhbrook>
however python does have the concept of threads
<jfhbrook>
and stackless python allows you to run your threads without a GIL
<alexgordon>
yeah but they're not real threads
<alexgordon>
kinda fake
<alexgordon>
only way to do it is import multiprocessing
<alexgordon>
which is not threads either :P
<jfhbrook>
right, that's multiprocessing
<jfhbrook>
so by "fake threads" you mean "green threads" yes?
<alexgordon>
I dunno, python is essentially single threaded
<jfhbrook>
except that assertion only really makes sense if the GIL is in place
<alexgordon>
well the GIL is always in place :P
<jfhbrook>
except it's not
<jfhbrook>
that's what I'm saying
<alexgordon>
it is
<jfhbrook>
there are forks of python which remove the GIL restriction
<alexgordon>
yeah but nobody uses those
<alexgordon>
also... I see lots of python code that would break badly if there were multiple threads
<jfhbrook>
and that's fine, except you said that there are abstractions you can't describe in python around multithreading
<alexgordon>
so if you were to use a multithreaded implementation, you would have to not use any libraries
<jfhbrook>
and yes, it's problematic to do so in practice
<jfhbrook>
but clearly, at least in the case of stackless python, it is in fact possible to describe
<alexgordon>
I don't really count that as python
<jfhbrook>
and the concept of thread-safe exists in a lot of places
* ec
yawns
<jfhbrook>
there's tons of C code that's not thread safe, does that mean that pthreads are somehow not real threads?
<alexgordon>
jfhbrook: it's more like if GCC didn't support pthreads
<alexgordon>
and most code was written for GCC
<jfhbrook>
no, that's an implementation not a language
<alexgordon>
implementations are languages
<ec>
jfhbrook: lol it's not a language you can reasonably use, so it's not a language you need to learn much of
<purr>
lol
<ec>
I just want you to know what my work is!
<jfhbrook>
C would still be fine at describing threaded programming, GCC would just be a huge piece of shit
<jfhbrook>
you have a multithreading story yet ec?
<ec>
jfhbrook: story?
<jfhbrook>
like, in paws, do you have any ideas regarding concurrency abstractions?
<ec>
Paws is basically one big concurrency abstraction. :P
<ec>
well, one big concurrency/paralellism, but simultaneously asynch, abstraction
<alexgordon>
jfhbrook: to be more precise, C is a langauge family, and GNU C is most common dialect
<ec>
I don't like questions like that because they bring out the 2012-elliott in me, and I tend to rant and rave on Paws' high-minded values and purposes too much
<ec>
trying to build a real piece of software here and answering those sorts of general questions somehow makes that more difficult for me.
<ec>
alexgordon can tell you all about it. ;)
<jfhbrook>
I, uhh
<ec>
concurrency-wise, Paws is going for a shared-object-space solution
<jfhbrook>
I just don't buy the argument that ANSI C doesn't count as a language because specific implementations of probably-pretty-close-to-ANSI-C are popular
<ec>
there's plenty of actor-related solutions, ones that allow the program to *pretend* they're working single-threadedly, while still writing imperative code, for small sub-sets of their code, and then preform the paralleization work at a ‘combinatory’ layer, higher-up
<alexgordon>
jfhbrook: well with C it's more complicated
<jfhbrook>
the details are totally beside the point
<ec>
I have no desire to attack that same solution-space in a very slightly different way; not to mention I think it's a red-herring of a solution-space
<alexgordon>
because you often end up with #ifdef GNU_C ... #ifdef MS_C ...
<alexgordon>
but no, any sufficiently large system written in C doesn't _just_ use ISO C
<jfhbrook>
ec: so threads? :D
<ec>
nope! there is not explicit concurrency system; everything is implicitly parallelized
<ec>
the only real innovation is that I move a bunch of the effort of shared-data locking *into the data space*, by requiring that authors express dependency information about the data they're manipulating; and that's not much of an innovation. it's pretty mundane.
<alexgordon>
words
<ec>
yeah, really not sure there's much else to say. you lock against any data you're working with, always, all the time, in all code; that makes it pretty trivial to safely process adjacent / unrelated blocks of code concurrently?
<alexgordon>
that was almost pretty coherent
<ec>
the interesting stuff is in the small corner-cases of interactions
<alexgordon>
but HOW, elliott?
<ec>
for instance, my language work has always been verrrrrry abstract: I like dynamic languages, languages where you can do dirty tricks, override things, meta-program
<ec>
Paws is no different; so here's an interestingly important case:
<ec>
if you, let's say DogModifier, want to mutate an object in a shared space … but you need to delegate some of that effort to somebody *else*, let's say DogAgeIncrementer,
<jfhbrook>
surely there's a way of executing code sequentially?
<ec>
locking is all well and good for really simple cases: lock TheDog, do some of your own work on it, then use some atomic lock-passing tool to give that lock over to DogAgeIncrementer, and then immediately block on that again … so as soon as DogAgeIncrementer is done (gives up the lock you gave away to it), you receive it again, and continue work
<ec>
*but*.
<ec>
that doesn't play well in a dynamic system if you want to enable good design choices, like black-box design / encapsulation:
<ec>
let's say somebody uses ReallyCoolLanguageTrick to *wrap* DogAgeIncrementer, invisibly. cool, now DogAgeIncrementer is super-cool and makes your computer shoot laser beams and produce fog when you invoke its' interface in some way.
<ec>
cool cool cool.
<ec>
wait: your atomic-lock-giving tool is now giving *a third party*, that neither you (DogModifier), nor your delegate (DogAgeIncr), knows ANYTHING about.
<ec>
(this is especially important in the context of Paws 'cuz you're supposed to basically build the language from inside the language by building giant towers of abstraction; there may be *two dozen* things like ReallyCoolLanguageTrick between yourself and the interface you *think* you're working with.)
<alexgordon>
•_•
<ec>
and that's just one of the hundreds of corner-cases I've ironed out in the locking system (what Paws calls ‘responsibility’, for code-owning-data, and ‘ownership’, for data-owning-data, respectively). this is the stuff that I think is really cool.
<ec>
basically, ‘How does A atomically give C a lock over data, without intervening B having to *know about* that process, or in any way provide for it happening; and without X, an arbitrary interloper, gaining that lock in the meantime, exposing the code to race-conditions where X defeats some sequential process underway between A and C?’
<ec>
sorry, did I just ramble on too long? alexgordon, why the face >,>
<alexgordon>
well, you haven't explained how it works yet
<ec>
what do you mean by ‘how it works’
<alexgordon>
that is the question I've been asking for 6 years!
<ec>
it works almost precisely the same as it did six years ago -_-
<jfhbrook>
ec: I see---I'd have to see some code examples
<ec>
jfhbrook: yeah, code-examples don't really work with Paws; it doesn't have a syntax.
<alexgordon>
ec: make a prototype yo
<jfhbrook>
like I follow conceptually but aren't sure what it would look like
<jfhbrook>
surely paws code "looks" like something
<ec>
Paws is a VM for following *one* graph (a graph of instruction-nodes), and in the process, permuting a second graph (a graph of data-nodes)
<ec>
the former graph has no defined syntax; the closest thing I have is a pseudo-syntax for debugging.
<ec>
there's a big part of the Making This A Useful Software Project puzzle that's nowhere near complete, hence why I don't run around advertising Paws :P
<jfhbrook>
but presumably there's some rationale for how the vm chews up bytecode? like instruction codes, etc?
<ec>
oh, of note, the graph of instructions and the graph of data are homogenous.
<ec>
actually, glowcoil came up with a bytecode for Paws a long time ago, come to think of it
<ec>
but no, I have no compiler, that's far outside my skill set. My reference work is all on a super, super slow interpreter. :P
<jfhbrook>
"bytecode" if you must---whatever you feed to the vm
<ec>
ugh see this is bringing out my bullshit again. I hate talking about Paws! I'd better just go write.
<ec>
… or teach akshat to write. RURIK! :D
<jfhbrook>
I see
<ec>
omg the Doctor
<ec>
“I just watched my best friend die in agony, *my* day can't get any worse ...
<ec>
... let's see what we can do about yours.”
<ec>
jesus christ Capaldi can pull off *bad. ass.* really well
<jfhbrook>
yeah?
<ec>
jfhbrook: yeah, sorry if I'm being obtuse. I don't like talking about the parts of Paws I consider boring; because language implementation is super-boring to me,
<jfhbrook>
I've watched the first 2 episodes of the capaldi dr whos
<alexgordon>
MATT SMITH FOREVER
<ec>
and the parts of the language *design* that just ‘fill in space’ instead of being innovative, are to me, instead part of the *implementation*.
<jfhbrook>
but like
<ec>
Like, what syntax it takes right now is super, super irrelevant to the parts that I've put a lot of effort into, I guess? so I get frustrated as soon as anybody asks any question about those parts.
<jfhbrook>
do you feel like words like "is" and "they" are boring?
<ec>
failing on me. (=
<ec>
alexgordon: ugh no
<jfhbrook>
they're pretty important because it's how you assemble most sentences
<ec>
alexgordon: david tennant is the hottest human being
<ec>
the hottest
<alexgordon>
eh
<jfhbrook>
even if it's something people take for granted
<alexgordon>
matt smith is the only doctor I could stand
<jfhbrook>
I like the Tennant one where they meet satan
<alexgordon>
when I watch capaldi I keep thinking I'm watching the thick of it
<ec>
jfhbrook: oh, I don't disagree.
<ec>
just observing a shortcoming in myself.
<ec>
alexgordon: probably contributed heavily to you never grasping anything I was saying, all those years ago :P
<alexgordon>
I think he probably works better for americans who aren't familiar with his previous sweary persona
<ec>
jfhbrook: well, if we're going to talk syntax, we have to talk object-model a bit, because the syntax is like Lisp, in that its mostly an expression of the object model
<jfhbrook>
I see
<ec>
again, super-boring: objects are nodes in aforementioned graph(s), all objects are homogenous; call them Thing
<jfhbrook>
homogenous?
<ec>
there are only Thing(s)
<jfhbrook>
ever? no custom properties or methods?
<ec>
there are no Class, or Function; there are *especially* no String or Number or DOMNode or,
<jfhbrook>
shit
<ec>
yep, so, hold on a sec tho
<ec>
as that's misleading: am not done
<ec>
objects can hold ‘data’ (I'll get to why I'm calling it that in a sec), but don't necessarily; it's a little bit like JavaScript's box-types, if you *also* couldn't tell that they where box-types instead of just Object
<ec>
to be a little more explicit: there's a `class Label` type in the source-code for Paws.js, alongside `class Thing`
<ec>
(think Label == ruby's Symbol or lisp's atom, mby)
<jfhbrook>
or javascript's symbol
<ec>
but *from within the language* they're in differentiable: there's no classes, or `instanceof`, or `typeof`
<ec>
yeah that's right I forget ES6 is a thing now >,<
<ec>
or is that ES2016?
<jfhbrook>
no idea
<ec>
so, ‘data’ is like JavaScript's primitives: a string, for instance
<jfhbrook>
I, uhh
<ec>
unlike in JS, you can't *unbox* a primitive, and then store that raw data, without a wrapping Object, somewhere
<jfhbrook>
kinda stopped caring about what it's called and started caring about the implementation of specific features
<ec>
jfhbrook: riiiiight? >,<
<ec>
pretty sure something's gone srsly wrong when we've all started doing that
<jfhbrook>
like apparently the only people that can get their shit together are implementors
<ec>
feature-testing is a symptom of a really sickeningly serious problem
<jfhbrook>
I mean, I can understand feature testing kind of
<jfhbrook>
just because I don't expect browsers to implement everything at once
<ec>
so, Things, nodes in this graph, are ordered-lists of other Things (directed edges to other nodes)
<jfhbrook>
but it would be nice if I could be like, "if I write against spec x it'll work in all browsers which support spec x"
<ec>
see, that's what I hate, jfhbrook: I'd much prefer to see JavaScript deployed in browsers like software is deployed on servers; by individual release
<jfhbrook>
and still get to, like, use features that aren't 10 years old
<ec>
i.e. you write your code *for ES6*, and then it works in every browser that fully implements all of ES6, and doesn't in browsers that don't
<ec>
and browsers expose various versions of the engine that can be activated based on the code being run.
<jfhbrook>
Right, like that's how I would like to operate, as a developer
<ec>
makes so much more fucking sense if all of the features and interfaces are a *designed whole*, rather than a hodgepodge of what's enabled, and what version of the interface-design is being used by which, and blahblahblah
<alexgordon>
oops zoned out
<jfhbrook>
I don't necessarily need an engines field, per se, like if the language is backwards compatible it's okay
<alexgordon>
-clouds
<purr>
alexgordon: is stuck up in the clouds; hilight 'em if you want 'em.
* ec
nods
<ec>
iiiiiidk, nah,
<ec>
omg alexgordon
<ec>
omg you just made my night ;_;
<jfhbrook>
I'm still probably going to start using es6 features in node 4
<alexgordon>
ikr never used that thing before
<ec>
alexgordon: lies.
<jfhbrook>
well except I want to support old versions of node still
<ec>
lessee. where was I.
<jfhbrook>
and I don't find any of the features so compelling that I'm willing to break backwards compat
<ec>
okay: JavaScript objects are dictionary-ish kinda, Paws objects are correspondingly ordered-list-ish kinda
<jfhbrook>
sure, makes sense
<alexgordon>
aren't all lists ordered?
<jfhbrook>
no
<ec>
nope
<alexgordon>
they're not?
<jfhbrook>
unordered lists
<alexgordon>
pretty sure they are
<jfhbrook>
<ul>
<ec>
there's lots of languages that differentiates strongly between those types
<alexgordon>
ec: all lists are ordered by the indexes
<ec>
nope
<alexgordon>
yes....
<jfhbrook>
not all lists have proper indexes
<ec>
list: either does-include or does-not-include
<jfhbrook>
or rather, order-able indices
<ec>
does not provide index, does not provide uniqueness
<ec>
can include multiple times
<alexgordon>
yes they do, if x is the ith element and y is after x, then y is the i+1th element
<ec>
set: does-include or does-not-include
<ec>
provides uniqueness (can only ‘include’ something, boolean.)
<jfhbrook>
there might not *be* an ith element alexgordon
<alexgordon>
jfhbrook: yes it could be empty
<jfhbrook>
like, given a bag of oranges, which one is the 5th orange
<alexgordon>
that is true
<alexgordon>
jfhbrook: but that's not a list
<ec>
ordered list: provides indices for each item; is really a mapping of index-to-presence-of-item
<jfhbrook>
it is a list
<alexgordon>
no it's a set
<alexgordon>
or a bag
<alexgordon>
but not a list
<alexgordon>
why are we arguing about this?
<ec>
ordered set: provides indices for each item, and each item uniquely maps to a single index
<ec>
oh
<jfhbrook>
because you're wrong alexgordon
<ec>
I see
<ec>
you're arguing terminology
<alexgordon>
I'm never wrong
<ec>
I thought you were saying ‘a bag’ cannot exist
<ec>
and I was like … dude, indices can totally not-be-a-thing
<alexgordon>
ec: well you said ordered list in opposition to ordered set
<ec>
as for terminology I Don't Care
<ec>
it's definitely not a set.
<ec>
set has a very specific definition: that it is unique.
<alexgordon>
well ok let's talk in math speak
<ec>
a set only includes <object #DEADBEEF> a single time
<ec>
sure! I like that
<ec>
love it when you teach me math things
<ec>
that sounded like sarcasm that was not sarcasm
<alexgordon>
there are sets (unordered), there are multisets (unordered) and there are sequences/indexed families
<ec>
ANYWAY, not important, jfhbrook:
<alexgordon>
I don't know of any unordered list
<alexgordon>
except in HTML :P
<ec>
a node's edges are 1. directed, 2. not unique (can include two edges to the same OtherNode), and 3. are indexed (ordered)
<ec>
so we'll call it an Ordered List, and argue about this later :P
<alexgordon>
ec: iirc it's something like an associative array
<ec>
now, switching rails over to syntax briefly (we'll be going back and forth exposing earlier lies, because I dunno how else to teach this shit, sometimes)
<alexgordon>
((1, x), (2, y)) something like that
<ec>
there are only two *operations* in a set of paws instructions. we'll talk about these both abstractly, in terms of the instruction-graph,
<ec>
and I'll try to speak concretely, about the syntax that you can download Paws.js and run *today*, because I get that everybody gets annoyed at my ivory-tower bullshit
<ec>
the single active operator, like message-sending in SmallTalk or application in lisps, is what I call ‘combination’
<ec>
syntactically, `a b`
<ec>
way back when we called it the ‘space operator’ simply 'cuz that sounds cute and sic-fi-opera-y
<alexgordon>
pretty sure I invented that name
<ec>
you or micah for sure
<ec>
not me, I'm way too high-minded for that ;)
<ec>
now, speaking abstractly, a Combo(a, b) is :: Thing -> Thing -> Thing
<ec>
(alexgordon aren't you proud! lookit me trying to use Grown-Up Adult Haskell Things!)
<ec>
(I probably fucked it up.)
<alexgordon>
nope
<alexgordon>
although you could also say (Thing, Thing) -> Thing
<ec>
thought that was verboten 'cuz currying
<ec>
so speaking syntactically, in `<a> <b>`, both of those need to be *things*.
<Rurik>
ec, I am back
<ec>
notice that I didn't say references to things, or ‘identifiers’, or anything like that.
<Rurik>
sorry, had gone to Gym
<alexgordon>
ec: don't _have_ to use currying
<ec>
here's where it gets gnarly: Paws' instruction graph is *composed of nodes that also exist in its' data-graph*. Like, actual nodes, not representations of nodes.
<ec>
(I don't know how else to phrase that but it never goes over well. I remember arguing with alexgordon about this for like, a whole day once. >,>)
<Rurik>
ec, What I meant was that how do you handle all the knowledge that is handed to you by language documentation
<jfhbrook>
I mean
<jfhbrook>
that sounds plausible
<jfhbrook>
plausible *enough* anyway
<ec>
(so to express it another way, if you think about it, a Paws *program* is expressed as additional edges between objects in the object-space.)
* ec
nods
<jfhbrook>
I'm grabbing a smoke but I'll try to read up
<ec>
it's fine lol
<purr>
lol
<jfhbrook>
oh I see
<jfhbrook>
interesting
<ec>
you've given me a chance to rant on my work, I'm happy as a pigeon
<ec>
it's not important or innovative, just hard to explain
<ec>
which is a good sign I fucked up that design-choice, but whatever
<ec>
>,<
<ec>
so, moving on, read when you get back:
<ec>
that's *one* of the two elements of the syntax (still haven't expressed how to *type* ‘a’ or ‘b’, so don't worry too much if you're confused), the `a b`
<Rurik>
There is classes, protocols, delegates, namespaces blah blah blah...
<ec>
which we can express a little more clearly in this discussion as a <- b: “juxtaposing B to A” or “combining A with B”
<ec>
Rurik: I'll respond a bit later, ~involved~
<Rurik>
ec, O7 aye
<ec>
so the reason Paws code doesn't just look like this:
<ec>
a b c d e f g h i j
<ec>
(yay stack languages)
<ec>
is because there's a second basic component of ‘indirection’:
<ec>
`a [b c]`, which means, ‘take the result of `b c`, and combine that *result* with a.’
<ec>
we'll come back to that. time to step back and look at what the ‘a’ and ‘b’ in `a b` literally mean, and what that *whole statement* does, in that faux-syntax, as it's used today; because I glossed over that. :P
<ec>
as I mentioned earlier, I've a Label non-type, basically a Symbol; and when reading in this text-code and turning it into instructions, every word (as in, unicode-sequence-not-including-whitespace-or-brackets) is turned into a new instance of that Label: i.e. Label('a') and Label('b')
<ec>
or to use our <- syntax, Label('a') <- Label('b')
<ec>
but that's pretty meaningless, isn't it. that's kinda like the JavaScript for `'a'['b']`. like, what?
<ec>
so the final piece of the syntactic puzzle, is that each *expression* is implicitly juxtaposed against an implicit node, one we call ‘locals’: this stands-in for any concept of local-variables or lexical scoping, neither of which Paws has.
<ec>
so, the *full meaning* of `a b` is this: («locals» <- Label('a')) <- Label('b')
<ec>
or, in pseudo-JS, locals[String('a')][String('b')]
<ec>
alexgordon: you know all this already, I hope. this suuuuper-banal shit should have been hard to forget, I imagine?
<jfhbrook>
okay, I see
<jfhbrook>
kind of
<jfhbrook>
have you ever read jones forth ec?
<ec>
yeah it's not obscure or magical, I'm just laying it all out so future stuff will make sense
<alexgordon>
ec: 1 sec, had a really good idea about how to structure code
<ec>
this is elliottcable-level documentation, if I do say so myself, and I do. say so. (myself.)
<jfhbrook>
hah
<ec>
I've truly wasted my life up to now by not programming in the one true language -BASIC- -assembler- -C- -Java- -Scheme- -Erlang- -Emacs- -Lisp- -Common- -Lisp- -Smalltalk- Forth!
<ec>
hah I laughed
<ec>
okay. so.
<ec>
fast-forward back to ‘indirection’, and we've nearly covered the entire syntax:
<ec>
the expression within [] is the same as the external expression, in that both are implicitly combined with the locals-node:
<ec>
`a [b c]` translates to `locals['a'][ locals['b']['c'] ]` in our pseudo-JS alphabet
<ec>
now, let's talk about the brackets in that alphabet, that is, ‘combination’ itself. What does it *do*?
<ec>
so this is where I get to go back and tell you I lied earlier, every educator's favourite moment:
<ec>
while, yes, our object-flavour is ordered-list-slash-non-sizehomogenous-array,
<ec>
it's *treated* as a dictionary or map by Paws' semantics.
<jfhbrook>
sure, okay
<ec>
that is, it's like the JavaScript object, but flipped on its' head: JavaScript's semantic implements Arrays on top of dictionaries, by having the indices of the array members be the key and that member be the value
<jfhbrook>
but paws does key lookups based on Label
<ec>
in Paws this is flipped on its' head: all objects are lists, but we fake associativity by nested-lists.
<ec>
yep!
<ec>
so in JavaScript you have { '1': 'a', '2': 'b' } looking like an array; but in Paws you have ( ('a', 'foo'), ('b', 'bar') ) looking like a dictionary
<ec>
so the *most basic* purpose of the combination: preforming a faux-dictionary-lookup on the list. Given Combo(that-object, 'a'), for instance, you'd get 'foo' from the above.
<jfhbrook>
I see
<ec>
of course, that's not very useful if that's the only operation in Paws. we've basically now built ourself a language that can resolve a complex tree of identifiers to find a particular value somewhere in the tree. not v. cool at all.
<ec>
so of course what-a-combination-does, for a given object, is completely dynamic. that ‘lookup’ behaviour is just the *default* behaviour, for bare objects created anew.
<ec>
the implementation of what-a-combination-does is called the ‘combination receiver,’ SHOCKINGLY.
<ec>
and that brings us, ~dundundunnnn~, to the fun stuff!
<ec>
ARE YOU READY JOSHUA
<ec>
there's like, an announcer on a stage, and a stadium-full of cheering people, and you're standing there in the hoodie from your Twitter avatar, looking confused
<ec>
in my head
<ec>
fyi
<ec>
I'm a very visual person
<ec>
hope u like that abt me
<jfhbrook>
hah
<ec>
so that's all super-mundane data-retrieval and parsing stuff, the most boring parts of *most* languages that aren't super-exotic. (paws isn't super-exotic. (at least in those ways.))
<ec>
but I haven't touched at *all* on how you encapsulate behaviour and manipulate it, i.e. functions or whatever
<ec>
and that's where Paws *is* super-exotic.
<ec>
so I've mentioned two underlying-boxing-types-that-are-indistinguishable-from-within-the-language; Thing and Label
<ec>
and now I get to touch on the third of only-three, and that's ‘Execution.’
<ec>
jfhbrook: you know enough languages to be at least distantly familiar with continuations *or* coroutines, I suspect?
<jfhbrook>
well, familiar enough yeah
<jfhbrook>
I've played with goroutines once or twice
<ec>
well, to sound a bit inflated of myself for a moment, executions are something *completely* new; but they're very very very similar to continuations, with one suuuuper-subtle difference
<ec>
but because of that difference, they form an even-lower-level building block that allows them to be used to *implement* true continuations, *or* true coroutines, *or* closure, *or* functions, all within the language.
<ec>
k </marketing speak>.
<ec>
syntactically:
<ec>
just as `a` is a literal that is constructed into Label(String-content) at parse-time, so is `{ ... }` a literal that's constructed into Execution(AST-content) at parse-time.
<ec>
so our earlier example can be wrapped up as an execution, rather obviously,
<ec>
{ a [b c] }
<ec>
(and there, by the way, you have the entire ‘syntax’ available in my implementation.)
<ec>
(well, I should add that you can use quote-marks to encode Labels that have spaces/braces in them, `a ‘elliott cable’`, but that's not really important.)
<jfhbrook>
okay
<ec>
now, and this is important, that Execution instance, is *not* something that represents all of that code: that code is represented by a, well, *abstract* syntax tree, existing somewhere in the aether, having no presence or relation to the data-graph, yet
<ec>
a ‘procedure’ or ‘function’ type would do that.
<ec>
instead, much more like a simple continuation might, it represents a pointer *into* that structure.
<ec>
here, I'll use this cute unicode caret: ⎬
<alexgordon>
Rurik, ec: making this stack based interpreter today has given me a whole new perspective on programming language design
<ec>
so if you type `{ a [b c] }`, what you're actually *getting*, is this: { ⎬a [b c] }
<ec>
bah, nowhere near as cute as expected
<ec>
let's use a hand
<alexgordon>
suddenly all of the stuff that's been floating around my head all year has become clear
<ec>
☛
<ec>
anyway.
<ec>
So, most simply put, an execution is basically a ‘first-class program-counter,’ as inimino put it waaaaaaybackwhen
<ec>
I'll get to *how* evaluation proceeds in a moment, but for now, just notice this:
<ec>
as evaluation of that `execution` proceeds, that ‘pointer’ is moving through the opcodes of the evaluation
<Rurik>
alexgordon, glad I could be of help
<ec>
or more abstractly, jumping around in the AST
<ec>
this is in contrast to a continuation, which has the rather important property that if you're *holding* a particular continuation, and then you *invoke* it ... the next time you invoke it, precisely the same chunk of code will be executed.
<ec>
a particular execution, meanwhile, will unfold along the instructions *further* every time it's invoked.
<ec>
a lot more on that in a sec, but do you think you're still with me, yah?
<ec>
this is where I usually lose alexgordon, so, lol just checking in jfhbrook
<purr>
lol
<jfhbrook>
oh, kind of
<alexgordon>
Rurik :D
<jfhbrook>
like I'd have to hear it a few times, but I can accept that there's a thing that represents a sort of pointer to a spot in an AST
<jfhbrook>
and that the thing that this pointer points at can/will change
<ec>
k good that's enough for now
<ec>
so, evaluation! we now have the tools that Paws puts together to provide a truly *asynchronous* language. (we'll get to the concurrency very last, once you understand the basics of the evaluation model in an imperative/ordered/‘single-threaded’ context.)
<Rurik>
alexgordon, now I hope you could be of help to me :>
<ec>
another thing I'll put off until later: the ways to actually *invoke* an execution, like you would a function; but for now, you already know of one!
<ec>
when it's the ‘combination receiver’ for another object.
<jfhbrook>
ahhhhhhh
<ec>
so let's arbitrarily, and rather uselessly, wave our hands and say that our example above Has Been Invoked somehow, and is about to be evaluated a little bit.
<ec>
(the ‘a little bit’ is important.)
<ec>
we'll call it BOB: { ⎬a [b c] }
<ec>
because I like palindromic names.
<ec>
it's going to produce, and then evaluate, a series of combinations, one by one.
<ec>
first: `locals <- 'a'`, where I'm now assuming that all 'string-quotes' from here on our refer to a Label object
<ec>
so our locals-object, if you'll remember that, has the default receiver, in this case: `locals` is treated as a dictionary;
<ec>
so *hand-wavey* well say it has something like this in it: `( a: foo, (b: (c: bar)) )`
<ec>
where : is me being lazy and not wanting to type ('a', foo)
<ec>
yes i'm getting really hand-wavey now but right now we're interested in evaluation model, not syntax, with any luck :P
<alexgordon>
Rurik: sure
<ec>
so! `foo` there, will be an object with a special `receiver`: an execution that we'll call ANA
<ec>
again because I like palindromic names. (hi BOB! hi ANA!)
<ec>
this means ANA is going to get invoked! (obv., parameterized with the information it needs to come up with some sort of combination of `foo` and `bar`, because that's what BOB needs ... but parameterization is a complex topic, especially when it gets to receivers; and that'll come much later.)
<jfhbrook>
I'm going to bed soon
<ec>
jfhbrook: *shrug* that's cool
<purr>
¯\(º_o)/¯
<jfhbrook>
like not that I don't find this interesting but it's almost midnight and I have to work tomorrow
<ec>
purr, go away
<ec>
how soon; should I bugger off and come back to this? :P
<jfhbrook>
oh, it sounds like I'll get to see emily
<jfhbrook>
oh, next 20 minutes? like finish your thought
<ec>
k, I'll move quickly :D
<ec>
meh, I'll truncate all of that to this:
<ec>
1. procedures/functions in Paws do not *return*,
<ec>
because 2. there is no *stack*,
<Rurik>
alexgordon, have you read this fantastic book called 'How to Solve It' by G. Polya?
<alexgordon>
nope
<ec>
Rurik: I have it on my shelf!
<ec>
Rurik: haven't touched it yet
<alexgordon>
Rurik: I know polya though
<ec>
because 3. all exchange of information is through fall-forward parameterization: that is, your caller gives you its' current execution (like call-cc, sort of, but implicitly), and then instead of ever returning by popping a *stack*, you return by calling that execution.
<ec>
hence fall-forward: you're always travelling forward, everything is just *calling*, instead of ever *returning*.
<ec>
so, that's just CPS, but there's some interesting twists, when you're using executions instead of continuations.
<ec>
oh ugh yeah maybe I shouldn't try to stuff this all in too quickly, I completely missed something important.
<ec>
when you invoke an execution, you *can* pass it information (obviously); and this happens in a similar fashion to call-cc, but *syntactically* instead of with a special faux-function:
<ec>
when you invoke an execution for a currently-paused chunk-of-code, the information you pass into it, the ‘resumption value’ as we call it, becomes the result of the previous combination. yah?
<ec>
the should hopefully be pretty straight-forward sounding
<ec>
so if `a b` invoked some exec, OTHER, as the receiver; it does whatever work it's going to do, and `a b` is paused for the moment; but when OTHER is ready, it does something like caller(VALUE), and VALUE becomes the result of Combo(a, b)
<jfhbrook>
okay, that sounds reasonable
* ec
nods
<Rurik>
ec, Its great
<Rurik>
Cured my math phobia
<ec>
so, evaluation of a Paws program now has a *third* graph, just to confuse you some more:
<ec>
evaluation proceeds by jumping back, forth, and amongst trains-of-thought, those ASTs.
<ec>
(we call those scripts, I forgot to mention that. the body of a procedure, the thing an execution points into.)
<ec>
now, each individual script is synchronous *appearing*: syntax is directional, evaluation is ordered and procedural. not very asynchronous or concurrent sounding, is it?
<ec>
but the *evaluation overall*, is not, because it can so freely proceed between these trains of thought. (sounding a bit like threads, aren't they?)
<ec>
now here's a crucially-crucial bit for yeh: an execution can be branched.
<ec>
although a *particular* execution-object is exclusively move-forward; that is, *over its lifetime*, it represents a single evaluation of the entire script it points into,
<ec>
that execution-object can be *cloned*; which we call ‘branching’. and the effect is what it sounds like.
<ec>
if my `caller` yields themself and invokes me, giving me a handle to them, then I can *both* invoke that execution, so that control continues to flow through the caller, *and* clone them before I do so, so that I can then *re-invoke* the caller, with a different value the second time.
<jfhbrook>
oh I see
<ec>
this is where things start to get v. cool. let's draw a few patterns:
<ec>
1. caller invokes me, pausing himself. there, we have a synchronous ‘procedure call.’ I can then, later, synchronously invoke his execution again, providing him with a result to some question that he has asked.
<ec>
oops, sorry for gendering programming-language constructs. >,<
<ec>
been trying, mostly failing, not to.
<jfhbrook>
I try not to personify PL constructs myself but I understand the instinct to do so
<ec>
well, you really need pronouns when talking about exchanges between two procedures or processes
<ec>
not for personification, but for the basic purpose of pronouns; not re-specifying which is which at every turn in the sentence :P
<ec>
2. caller invokes me, I *immediately* re-invoke them with a meaningless value, without pausing myself: there, we have something like a thread, or process.nextTick. I can preform work, if the caller doesn't *depend on* (that's important, will come back to) a result from me, in parallel with the caller.
<ec>
(yes, I haven't touched on true concurrency, or on locking yet; but can you start to see how this is a system for expressing interdependencies in tasks? just like All Programming, basically?)
<ec>
3. caller can invoke me, pausing themself, and I can *not* re-invoke them ... but I can store their original `caller` execution,
<ec>
and then (say, every time a network request comes in), I can invoke a *new branch* of them.
<Rurik>
alexgordon, as in 'know him personally' or 'aware he exists'?
<ec>
the consequences of that are probably immediately obvious. :P
<jfhbrook>
so each time the request (or whatever) knocks, clone your prototype context and execute?
<ec>
`puts [start-server request path]`
<ec>
as a random made-up example
<alexgordon>
Rurik: not personally, he's dead :P I know his math
<Rurik>
ah cool
<ec>
notice there's no callbacks, no assignment, no promises, nothing. the combo for `start-server request` simply never returns, and then returns a new request-object every time.
<ec>
(so yes this system lends itself to some really nasty-magic APIs)
<ec>
there's actually about 7 common ‘invocation patterns,’ as it turns out, that can be preformed amongst a set of procedures; most everything else boils down to variations upon one of these
<ec>
I have them written down somewhere, but suffice to say They Are Really Fucking Cool™
<ec>
let's move on 'cuz sleep soon:
<jfhbrook>
yeah I gotta crash
<alexgordon>
ec: [when jfhbrook goes to bed I'll explain this idea]
<ec>
okay that's 'k
<jfhbrook>
sounds like interesting work though
<ec>
thanks! I'm really proud / excited.
<jfhbrook>
you should write these details down somewhere
<ec>
they kind of are, but scattered around.
<jfhbrook>
so that you don't have to type it all out again at a later date
<ec>
seems pointless until there's a functioning implementation.
<jfhbrook>
fair
<ec>
(there's a huuuuuge hole in the design as currently implemented that makes it completely useless; I'm in the middle of a large rewrite to solve this.)
<ec>
(unfortunately.)
<jfhbrook>
oh bummer
<jfhbrook>
anyways o/
<ec>
o7!
<ec>
Rurik: hi!
<ec>
Rurik: any chance you followed along with any of that? :3
<Rurik>
ec, yes
<Rurik>
ec, sounds a bit like Rust
<ec>
some of it actually is; at least in terms of the locking
<ec>
(but I don't know much about Rust, I've just heard some of these comparisons before)
<ec>
what were you asking about knowing things about programming?
<Rurik>
oh yeah
<Rurik>
Umm so...
<Rurik>
[09:10:18] <Rurik> ec, What I meant was that how do you handle all the knowledge that is handed to you by language documentation
<Rurik>
[09:12:25] <Rurik> There is classes, protocols, delegates, namespaces blah blah blah...
<ec>
basically, don't.
<Rurik>
how do I use these in solving problems
<ec>
Start with a tutorial, then write code to do something; then when you have trouble doing it, ask a *human*, or at least find a tutorial/newbie-oriented description of how to idiomatically solve that problem in this particular environment
<ec>
basically: when you first start using a tool, you're going to be using it wrong. you're going to use it like you have used other, similar tools; and you're going to keep doing so until somebody tells you you're wrong.
<Rurik>
or is just getting hands dirty is the best approach
<ec>
yep.
<ec>
accepting this fact is kinda part-and-parcel with learning lots and lots of new programming tools.
<Rurik>
hmmn, I will try that
<ec>
like, my approach is basically this:
<ec>
‘Look! I got a screwdriver!’
<ec>
google ‘how do I use screwdriver tho’
<ec>
read it badly and imperfectly, get the wrong idea, start banging screws in with the handle
<ec>
because all I've ever used is a hammer
<Rurik>
ec, do you have exercises in mind that I could implement
<alexgordon>
Rurik: to process documentation, you use ctrl-F :P
<ec>
then take my board and screw and screwdriver and show it to somebody in IRC, and get laughed at, and be okay with that while some nice person explains how to twist a screwdriver to me.
<Rurik>
I got a really bad habit of being spoonfed because of my shitty high school and cram school after that
<ec>
alexgordon: that only helps for *formulaic* documentation: ‘What are the arguments to this function.’ ‘Which class allows me to do this.’ ‘What's the syntax for <task.>’
<ec>
alexgordon: his question is about understanding the *core semantics* of a new paradigm, basically.
<ec>
as far as I can tell.
<Rurik>
yes
<ec>
Rurik: exercises for what? learning-to-learn-better?
<ec>
pick up seven new languages in the next month.
<ec>
no excuses.
<alexgordon>
ec: well... google :P
<Rurik>
ec, coding basically
<ec>
preferably, no two from the same family.
<Rurik>
getting my hands dirty
<ec>
Rurik: if you mean in terms of getting-hands-dirty with *lang shit*, come work on paws with me.
<alexgordon>
just got to think of words that are related to what you're doing, and search for them until you find the correct resource
<ec>
desperately want extra hands, so.
<ec>
Rurik: yeah, alexgordon isn't wrong. StackOverflow and IRC are *the two best resources* for newcomers to a new tool or paradigm.
<ec>
there are situations where this is wrong (shell-scripting, for instance; there's *loads* of misinformation on SO and Google, and *even more* misinformed people on IRC); but you'll quickly find out if the usual SO/IRC approach isn't doing well by you.
<alexgordon>
shell scripting: not even once :P
<alexgordon>
ec: so so so I want to explain this shit
<alexgordon>
the idea is to combine modules, macros and an interpreter
<ec>
explain what shit
<ec>
alexgordon: you really need to learn from me as much as I need to learn from you
<alexgordon>
haha
<ec>
give me the 10,000 foot overview, why it's cool, the marketing buzzwords of PLT, so to speak, first
<ec>
like, entice me with high-minded bullshit before showing me how it's possible
<alexgordon>
hmm ok
<alexgordon>
ec: so think about what "code" is
<ec>
yess I like the sound of this
<alexgordon>
:D
<alexgordon>
in any programming language there are different kinds of code
<alexgordon>
like data structure definitions, functions, ...
<ec>
Rurik: and yeah what time is it there, and how much longer are you going to be awake? let's talk Paws and ‘how I'm building a programming language.’ I can directly assign you tasks, and walk you through them when you have trouble, until you've convinced yourself that yeah, this really is not black magic at all. I'm super-excited because this sounds very
<ec>
everybody-wins: I badly need help!
<alexgordon>
but they're all just code, right? even if we think of them as being related only through the semantics of the language
<alexgordon>
well code needs to be better organised
<Rurik>
ec, I have to leave for college in an hour and then german class after that
<ec>
Rurik: omfg you're trilingual?
<Rurik>
Bilingual currently
<Rurik>
Trying to get to B2 in German in the next 1.5 years
<ec>
B2?
<Rurik>
CEFR level
<ec>
CEFR?
<ec>
(Im going to be inordinately happy if this is just a never-ending stack of acronyms)
<Rurik>
B2 = can understand most of info and hold a conversation
<Rurik>
Took me 3 years to move from B2 to C1 in English
<alexgordon>
ec: so there's two observations: 1) what if you could make a module of "code" without the module knowing anything about the code... like a module of _tokens_. THEN 2) what this leads to is thinking about defining new kinds of code within an abstract module
<Rurik>
ec, and yeah, that assignment idea is great
<Rurik>
but I'll available for it tomorrow
<alexgordon>
um that was not a very good explanation actually
<ec>
yeah what
<ec>
you need practice at this as much as I need practice speaking concretely about my ideas :P
<ec>
Rurik: cool!
<alexgordon>
ec: you're right though, I was trying to explain it in terms of the implementation, but the buzzword elevator pitch is a better strategy
<ec>
Rurik: want to dive in rn?
<Rurik>
ec, would love to
<ec>
omg
<ec>
well, lessee
<ec>
early-on I'll have to put some effort into familiarizing you with the codebase
<alexgordon>
ec: in normal programming languages, modules are containers for things that already exist. e.g. you have a module of functions, constants and datatypes, etc
<ec>
we'll have to take about the language *itself*, to.
<ec>
maybe go re-read everything I was writing to jfhbrook above for now, and then come talk to me about what you read.
<alexgordon>
ec: but if you free yourself from the constraint that the things already exist, you can define an *abstract* module, of "code stuff"
<ec>
probably unintuitively, I don't think you need to fully understand the language to start to be helpful on it, actually
<ec>
but yeah you'll need to know basics.
<ec>
luckily, I cover a lot of those above: how ‘objects’ are modeled from inside the language, stuff like that.
<ec>
alexgordon: so, an include-able java-interface?
<alexgordon>
nope :P
<alexgordon>
a module, a collection of code
<alexgordon>
like node modules
<alexgordon>
small ones
<ec>
mmhm
<ec>
looooove npm btw
<ec>
one of the best things to have come out of JavaScript, *period*
<ec>
so what is code-stuff
<ec>
what is an ‘abstract module’
<ec>
rephrase
<alexgordon>
a collection of "code stuff" :P
<alexgordon>
ok I'll give an example
<Rurik>
alexgordon, language neutral modules?
<alexgordon>
Rurik: no it is in this one language
<ec>
‘The day you lose someone isn't the worst. At least you've got something to do.
<alexgordon>
ec: i.e. the source code is a dynamic language, that calls into the compiler as a library, to compile _itself_ again
<ec>
yep
<ec>
that's precisely what Paws does, basically
<alexgordon>
really? maybe paws is interesting after all :D
<ec>
except without me having plans for that last, final code-generation step, because idk compilers yet and am not too worried
<ec>
but: it self-interprets, over and over, with access to APIs *into the parser and code-generation*
<alexgordon>
well I really want code to be able to define functions to define its own type checking
<ec>
but with all other APIs basically disabled (i.e. slow things like filesystem access, or network)
<ec>
hundreds and hundreds of times possibly
<ec>
but the final time, when it's executed the entire Unit w/o filesystem access or network or anything, and no more calls are made into the code-generation or parsing APIs, it's considered ‘static’: that is, all new parsing rules have been learned, basically.
<alexgordon>
ec: the other thing I was thinking re our discussion the other day, was that -- what the hell -- most functions should be coroutines
<ec>
and then it's flipped: the dynamic parsing is all disabled, and it's run as static code (or possibly compiled?)
<ec>
no fucking kidding
<ec>
I love coroutines so much, and it's terrible that less languages use them as a model
<alexgordon>
yeah
<ec>
dude, ugh, if I could just explain it to you, you'd clearly *love* Paws
<ec>
idk what happened to you in the last year but in the last few days you've been describing Paws' actual *purposes* back to me, if not its actual *design*.
<ec>
if left in a vacuum, you'd basically design a strongly-typed Paws all on your own. lol.
<purr>
lol
<alexgordon>
haha I think it must be convergence
<alexgordon>
cause I for sure don't understand paws
<ec>
oh definitely
<ec>
wasn't saying you were copying me lol
<ec>
just wish I could talk you into joining forces, 'cuz I could use some help.
<ec>
this goes *so*, so slowly alone
<alexgordon>
I dunno, you need micah for that stuff. even if I apparently undestand the purpose of paws, I don't understand the implementation
<ec>
yeah, that's my fault
<ec>
I just dunno why I can't put it in alex-words /=
<alexgordon>
ec: the other thing -- as a point of compiler engineering -- is that everything is represented as an object with a "kind"
<alexgordon>
so the lexer generates kind:number, kind:ident
<ec>
ofc
<alexgordon>
but these stick around... so the macros can process these kinded objects