<ljharb>
imo tho, semver is glorious, and is the best versioning system we've come up with so far. the argument "you can't enforce it except with humans!" forgets that we do enforce it now, with humans, and it works, per https://twitter.com/ELLIOTTCABLE/status/682723444987924480 :-)
<ec^>
ljharb: Honestly, not sure I want to re-hash this argument. ¯\_(ツ)_/¯
<ec^>
I'm going to continue *versioning* my packages completely aside from semver, and publishing/tagging different ‘versions’ than are stored in npm, while respecting semver only in the `version` field of a package.json.
<ec^>
I think it's disgusting that I need to do that, but I also think it's really *not* that big a deal. A lot of this is unrepentant bikeshedding.
<ec^>
I think I need to add a ‘happily ceded’ or ‘calmly argued’ clause to my “strong opinions / held loosely” schtick
<ec^>
hello all
<ec^>
I love most of you
<ec^>
except ljharb, he's just okay ;)
<Rurik>
ec^, When can we begin paws stuff?
<ec^>
Rurik: I'm always down! How long you around for rn?
<Rurik>
2+ hours
<ec^>
I just sat down at my desk, finished breakfast, got medicated (still sick as fuuuuck), and am prepared to work
<ec^>
if you'd like me to focus on you instead of diving into writing, I can do that :3
<Rurik>
please do
* ec^
laughs
<ec^>
okay!
<ec^>
Rurik: let's see. I've let myself lapse. What were we talking about?
<ec^>
first off, msg me your e-mail address of choice
<ec^>
Rurik: and GitHub account?
<Rurik>
akshatj
<ec^>
lol wtf github
<purr>
lol
<ec^>
ELLIOTTCABLE invited akshatj to the Paws organization (United States)
<ec^>
ELLIOTTCABLE added akshatj to the Paws/paws-js-developers team (India)
<ec^>
Rurik: so, my overall plan is this: 1. give you the overview of Paws' design, so that you have the slightest idea what I'm talking about, 2. walk you through the broad strokes of my current implementation, and then 3. assign you ‘tasks’ on the task-manager I just sent you an invite to.
<ec^>
Any code you write I'll review, and hopefully *that* process will get you familiar with the project more than anything else.
<ec^>
Once you're involved in the *code*, I want to start talking you through my *design* process, which always leads (is-ahead-of) the implementation by about a year's work (loldepressing)
<ec^>
If you get excited about the project, you can stick around indefinitely; feedback and contributions are always desperately welcome :P
<ec^>
if not, you can part ways whenever you think that you have a feel for what building-a-language actually *involves*.
<ec^>
capisce?
<Rurik>
ec^, yep
* ec^
nods
<ec^>
sp!
<ec^>
so*
<ec^>
a couple weeks ago, I was walking, errrrrrr, was it ljharb? through Paws. I know you were around, but I don't know if you were following along. Do you remember anything?
<Rurik>
nope
<ec^>
hm k
<ec^>
Lessee. Basics. as quickly as possible.
<ec^>
Paws is a dynamic, interpreted (right now), stackless language;
<ec^>
the semantics are defined over an arbitrary graph of data (that is, bits of data acting as ‘nodes,’ attached to other bits with semantic assocations acting as ‘edges’);
<ec^>
it focuses on asynchronicity, which it achieves through fall-forward semantics: there is no ‘return.’ (see: stackless, above)
<ec^>
Rurik: did all of the words above land? I don't remember how much programming-langauge stuff you already know. I'm happy to expand on anything.
<Rurik>
what does it mean to be `stackless`?
* ec^
nods
<ec^>
A huge percentage of popular programming languages nowadays are built on top of a ‘stack’, and a ‘heap.’ These are, at their core, memory-management concepts; but they very strongly affect the *flow* of programming as well.
<ec^>
Not going to go into detail on the data-structures (hell, I'm not even sure how much I remember from programming 101), but one effect of a stack-based language (let's take JavaScript as an example), is that it's *inherently synchronous*:
<ec^>
(For most of my discussion w/ you, I'm going to talk about chunks-of-code-to-be-evaluated as “procedures” instead of functions; but for most of these purposes, a JavaScript ‘function’ means the same thing. This is because a ‘function’ has a very specific mathematical / PLT, meaning with very specific requirements.)
<ec^>
when we have a chunk of functionality in a procedure, and we *invoke* (cause-to-become-evaluated) that procedure, the caller is, itself, *blocked* until that sub-procedure is complete.
<ec^>
in JavaScript and friends, this is signaled by a `return` statement.
<ec^>
now, this behaviour is *implemented* in something called a stack:
<ec^>
if `foo()` just called `bar()`, then the context and information necessary for `foo()` to continue to evaluate is stored in what's called a ‘stack frame’:
<ec^>
it often includes things like arguments-to-`foo()`, lexically-local variables' contents, so on and so forth.
Rurik has quit [Ping timeout: 246 seconds]
<ec^>
ack
<rarik>
ok
<ec^>
oh! you're still here
<rarik>
yep
<rarik>
connection problems
<ec^>
a stack is very efficient for lots of tasks; but as mentioned above: it's only useful/possible *because* the languages it implements are inherently synchronous.
<ec^>
(This is something often taken for granted: People talk about ‘async’ tasks, and they're almost universally talking about an *event-loop* in a stack-ful language. Nobody stops to think that the core operation of procedure-invocation could *also* be asychronous. >,<)
<rarik>
ah, i see
<ec^>
Interestingly enough, I know of some stackless *implementations* of traditional langauges; but very few stackless *languages*.
<ec^>
so, a ‘stackless language’ is one that has no `return` statement, or one in which the `return`-style statement is optional.
<rarik>
what's a heap?
<ec^>
the heap is everything (NOT the-stack).
<ec^>
sorry, that was an awkward logic syntax
<ec^>
in lots of non-memory-managed languages, stack space is not dynamically sized: I don't want to dive into detail on this right now (ask me later!), but basically, at compile time, the language must know the *size in memory* of every thing stored in the stack-frame for a given `func()`.
<rarik>
I see
<ec^>
additionally, the stack-frame is, probably obviously, deallocated at the end of the function: when you `return`, your local variables are discarded.
<ec^>
the “heap” is the space in memory where *persistent* things are stored in such languages, or things of variable size. Basically, you can either Get A Space To Store Some Data by doing `int foo;` (which allocates that space in your function's stack-frame, but then that data disappears when you `return`), or you can do so by doing `malloc(sizeof int)`,
<ec^>
ish.
<ec^>
it's more complicated than that, but that gives you the idea, I hope?
<rarik>
yep
<ec^>
so. Paws is stackless: that is, although there *is* a form of packaged-up-code-to-be-run, a sort of procedure, they are *not* functions: there is no return keyword, and thus they are not synchronous.
<ec^>
in a language with a stack, you have, well, *the call-stack*: You can, at any point in the code, look ‘up’, and see all of the things that called you.
<ec^>
you've seen this in “stack traces” in things like JavaScript:
<ec^>
“Something went wrong in `widget()`, after being called by `bar()`, which was called by `foo()`.”
<rarik>
yeah
<ec^>
now, what happens if you have no `return`? your ‘call stack’, that history of who-invoked-whom, will become arbitrarily / infintiely long.
<ec^>
thus, you might think of Paws invocation as being *one long series* of such invocations, since there is no `return`:
<ec^>
hence the phrase “fall-forward.” If we view `return` as falling-back *down* the call-stack, in Paws, you can only progress by falling *forward*, into *another* procedure.
<ec^>
So, specifics. First off, is any of the above confusing?
<rarik>
nope
<ec^>
good!
<rarik>
except for the fall-forward semantics
<ec^>
I'm usually very confusing when talking about Paws. I'm aware of this. I won't be offended at all, or think less of you, if you go ‘... wtf.’
<ec^>
literally the smartest people I know go ‘wtf’ when Paws is happening. <,<
<ec^>
Yah, there's more to be said there; but we're going to start getting into more concrete things. All of the above was largely philosophical / a high-level descriptor of the language's semantic.
<rarik>
How can you work without returning anythng
<ec^>
Good question!
<ec^>
Shows you're keeping up.
<ec^>
Let's imagine JavaScript without a `return` statement, very briefly.
Rurik has joined #elliottcable
Rurik has quit [Changing host]
Rurik has joined #elliottcable
<ec^>
Show me one way you can re-write this interaction between two procedures, *without* using the `return` statement:
<ec^>
|| function mult(a, b) { return a, b }
<ec^>
|| function square(n) {
<ec^>
|| result = mult(n, n)
<ec^>
|| console.log(result)
<ec^>
>> }
<purr>
ec^: undefined
<ec^>
derp, I didn't actually invoke square()
<ec^>
(the answer is, of course, to ‘fall-foward;’ show me how to do that)
<Rurik>
function square(n) { console.log(n * n) };
<Rurik>
like this?
pikajude has quit [Ping timeout: 260 seconds]
<ec^>
oh, nah. that's inlining.
<ec^>
¯\_(ツ)_/¯ this isn't crucial, I can easily demonstrate instead, if you'd like.
<ec^>
not sure how interactive you like your tutoring. :P
<ec^>
katymoe: hi!
<Rurik>
hmmn, please demonstrate
<katymoe>
ec^: hello!
<katymoe>
I'm doing everything on one screen rn so it took a while for me to find my IRC tab...
<ec^>
|| function mult(a, b, $cb) { $cb(a * b) }
<ec^>
|| function square(n) {
<ec^>
|| mult(n, n, function(result){
<ec^>
|| console.log(result)
<ec^>
|| }
<ec^>
|| })
<ec^>
>> square(3)
<purr>
ec^: undefined; Console: 9
<ec^>
Rurik: You see, of course, what I did there: JavaScript is an ideal language to convey this in, because we already do this often. We called them ‘callbacks.’
<ec^>
hold on brb, ~4 minutes
pikajude has joined #elliottcable
<ec^>
so.
<ec^>
That's all normal and such,
<ec^>
but that'd get *really* annoying, *really* fast in a *whole language* with no returns, wouldn't it?
<ec^>
so let's take the obvious way out, in our javascript-with-no-returns: we'll do that automatically, for the programmer.
<ec^>
function mult(a, b, $return) { $return(a, b) }
<ec^>
function square(n) {
<ec^>
result = mult(n, n)
<ec^>
console.log(result)
<ec^>
}
<ec^>
looks remarkably similar to the original example, ya? let's talk about what it's doing, in our theoretical languge
<Rurik>
hmmn
<ec^>
let's imagine our language takes *all of the rest of the code*, when a function-call happens, and packages it up into a new function, to be passed forward “in place of a callback”; then, the user doesn't have to type all of that mess
<ec^>
in this example, what `mult()` receives would be: [ 3, 3, {{result = *; console.log(result)}} ]
<Rurik>
but you supplied only 2 args to mult
<ec^>
yes!
<ec^>
that's the magic here:
<ec^>
where {{}} is our little automatically-generated-procedure type, and `*` is a hole where the ‘continue’ value goes. where the value will be ‘returned’ *to*, when that automatically-generated-procedure is invoked.
<ec^>
sorry, pasted
<ec^>
One of the innovations of Haskell, is that all functions have *implicit* inputs and outputs: One of those, in the case of a stackful language, is the stack itself.
<ec^>
A function does not operate in a vacuum; amongst other things, it is given an *implicit* argument of “where `return` goes”. (This becomes immediately obvious when working with assembly, where you manually push-and-pop those return-locations onto the stack as pointers.)
<ec^>
in our little language above, we've done nothing more magical than making that *explicit*: Now, you receive that return-location *explicitly*, through that `{{...}}` value, the last argument, instead of *implicitly*, as the target of `return` stored on some stack somewhere.
<ec^>
Rurik: you with me at all?
<ec^>
(I got sidetracked in answering your question, and I'm pretty sure I've failed to make my point. Oops!)
<ec^>
Well, while you're afk, I'll continue:
<ec^>
that {{}} type is called a “continuation”, and it's a popular construct in some of the more obscure, older, or more powerful languages
<ec^>
A continuation is a lot like taking that ‘stack frame’ from a stackful language, storing it in the heap somewhere, and then allowing the programming-language-user to pass it around in a variable, or *invoke* it just like a function.
<ec^>
in our pretend-language above, $return() is such a continuation.
<ec^>
Let me demonstrate how it could be used differently from a traditional stack:
<ec^>
instead of using `*` to multiply, what if we wanted to check with a remote server as to the result of the multiplication?
<ec^>
this would be impossible with `returns`: when submitting a network request, as the stack cannot exist for long enough for the operation to complete (and more importantly; this would mean *no other effort* could be preformed while waiting hundreds of milliseconds for that network request.)
<ec^>
but with continuations, it becomes trivial:
<ec^>
something like `function mult(a, b, $return) { contact_server(a, b, $return) }` allows us to *pass the continuation we received* onwards.
<ec^>
either you're totally AFK, or I'm losing you :P
Hrorek has joined #elliottcable
<rarik>
I am here
<ec^>
rarik: :D
<ec^>
rarik: Okay. Where are you in the above? With me? Lost? Annoyed? :P
<ec^>
ugh realllllly want coffee
<ec^>
katymoe: bring me coffee quick use teleportation
<ec^>
katymoe: no idea why I have selected you, but I promise it is a great honor
Rurik has quit [Ping timeout: 246 seconds]
<katymoe>
ec^: I'm in no state to go anywhere right now
<katymoe>
still recovering from NYE
<ec^>
katymoe: hungover?
* ec^
laughs
<ec^>
I went to bed at 9pm, and slept 12 hours.
<ec^>
That was *my* introduction to the new year.
<katymoe>
nice
<ec^>
“HEAL ME, BED. HEAAAAAL MEEEE.”
<katymoe>
I went to bed at 8am, woke up at 10pm on new year's day
<ec^>
katymoe: if *I* go get coffee, you want some? :P
<katymoe>
then went to bed again at 4am
<ec^>
jesus christ. you go hard.
<katymoe>
woke up at 12pm today
<katymoe>
and now I'm confused
<katymoe>
ec^: thank you. but I've already had a lot of coffee today
<Hrorek>
ec^, how does the language know to call `*` on the arguments?
<ec^>
Hrorek: rephrase?
<Hrorek>
{{result = *; console.log(result)}} ]
<Hrorek>
how does it know result=* ?
<ec^>
Ah! so the `*` in my example is what micah calls a ‘hole.’
<ec^>
here's another way of expressing it:
<ec^>
{{ result = |mult(n, n)| ; console.log(result) }}
<ec^>
it's just an indicator of *what the last thing that happened* was. That is, “When you invoke this continuation, |here| is where you put the value.”
<ec^>
so if you invoke our continuation with, for example, `$return(123)`, then our continuation becomes:
<ec^>
{{ result = 123 ; console.log(result) }}
<ec^>
simple. yes?
<ec^>
Hrorek: hilight me when you reply, going mobile
<Hrorek>
ec^, I don't get how $return(a, b) knew to apply multiplication
<ec^>
oh
<ec^>
oh lord god damnit that was a tpo
<ec^>
typo.
<ec^>
|=
<ec^>
|=<
<ec^>
Hrorek: If that's what's been confusing you this whole time ... lol.
<purr>
lol
<ec^>
function mult(a, b, $return) { $return(a * b) }
<Hrorek>
ah
<Hrorek>
haha
* ec^
grins
<ec^>
SO HOPEFULLY THAT IS ALL AT LEAST 100% CLEARER NOW
<Hrorek>
yep
<Hrorek>
all clear
<ec^>
So, recap, without the typos:
<ec^>
a `continuation` is basically a *part* of a procedure, wrapped up along with all of the information you need to, well, continue that procedure,
<ec^>
that can then be invoked as if it were a whole procedure of its' own.
<ec^>
“continuation == the last half of a procedure.”
<ec^>
Now! Paws! Let's move on and bring it back.
<ec^>
Paws is designed around an old concept called ‘CPS.’
<ec^>
CPS stands for ‘continuation-passing style’, and is something you'll hear a *lot* about when working in PLT.
<ec^>
Strangely, very few modern programming languages actually *implement* CPS, explicitly: often, CPS is a *transformative stage* within the implementation itself.
<ec^>
(This brings us back to our earlier discussion about stackless languages: lots of languages are *actually* stackless in some form or another, nowadays; often, this is by CPS-transform.)
<ec^>
(That's where they take code that has function-calls and `return` statements and stuff, and internally translate it into a bunch of `function(a, b, $cont)`-style calls, replacing `return foo` with `$cont(foo)`, again all internally.)
<ec^>
(The reasons for this are many: A pervasive and simple pattern like that is easy to reason about and manipulate; and it allows for a lot of well-understood optimizations to be done on the code.)
<ec^>
(anyway.)
<Hrorek>
I see
<ec^>
CPS is what we see, in JavaScript, when the remainder of a function is wrapped in an anonymous-func, and then passed as a callback: i.e. precisely the pattern we were converting above.
<ec^>
CPS is what I've been calling, above, “fall-forward semantics.”
<ec^>
Now, CPS is *generally* implemented *alongside* functions: A `function` is a chunk of code, that you can call; a `continuation` is a function *plus* the context of its' partial execution.
<ec^>
Paws differs in two ways:
<ec^>
First off, we drop the words ‘that you can call’ from the above sentance. Our *blocks of code*, our procedures, are completely abstracted away from the programmer. You can't put a Paws block-of-code into a variable, you can't call such a block of code directly. You can *only* hold on to, pass around, and invoke our continuation-ish type. (I'll come back
<ec^>
to this.)
<ec^>
Second, our ‘continuation’ replacements aren't *invariable*, whereas traditional continuations are: When you “take a continuation” (the traditional terminology) for a running function, you get all of that state packaged up and frozen. When you invoke a continuation, it's *restored* into a living stack, that then executes normally. It's basically a
<ec^>
second-class tool.
<ec^>
ours, which are called `Execution`, are variable: they represent not a single point in the evaluation of a software-procedure, but rather one *entire evaluation* thereof.
<ec^>
That is, when a procedure is evaluated from start to finish in a Paws program, there exists an `Execution` object representing that evaluation, and encapsulating all of the state involved in that evaluation.
<ec^>
This execution is first-class, just as continuations are in a language explicitly supporting them: you can store an execution in a variable, pass it around, so on and so forth.
<ec^>
In our toy language above, $return would be a variable holding an execution.
<ec^>
Hrorek: If you're not lost, let me elaborate now on point two, above: the fact that they represent multiple states over time. (You still with me?)
<Hrorek>
ec^, hmmn, this stuff is a bit hard to absorb
<ec^>
that's okay!
<ec^>
it's not an easy concept, it's very foreign to the vast majority of imperative programming we do nowadays.
<Hrorek>
This might be a dumb question: How do we know that a continuation is finished and then evaluate it?
<ec^>
continuation, or execution? (Paws question, or PLT question?)
<Hrorek>
PLT
<Hrorek>
or paws
<Hrorek>
Paws, yeah
<ec^>
and second; not sure what you mean, because … evaluation doesn't wait until it's … finished?
<ec^>
I lost you there somehow.
<Hrorek>
ok so
<Hrorek>
Once we hit $return it is evaluated (?)
* ec^
nods
<Hrorek>
I see
<ec^>
oh, that's the question?
<ec^>
yeah, none of this is a lazy system; it's all eager
<ec^>
just like a function, the evaluation of a `continuation` proceeds as soon as it is invoked.
<ec^>
Hrorek: I need to go get some coffee, I'm dying over here.
<ec^>
Hrorek: you're leaving soon, anyway, yes?
<Hrorek>
yes
<ec^>
Hrorek: here's some supplemental reading, to make sure you're firmly familiar with what a continuation is. (It's extraordinarily important to understanding Paws, or for that matter, a lot of modern PLT stuff.)
<ec^>
what's your schedule like? What days, and what times of day (GMT) are you likely to be available?
<ec^>
let's set up a time to continue this. (=
<Hrorek>
I am free 11:30 - 19:30UTC on Tue/Thu/Sat
<Hrorek>
and free on sunday full day
<ec^>
what time do you normally get up? UTC?
<ec^>
so, 5:30AM to 1:30PM, my time. (purr should do time conversions)
<Hrorek>
1:30 UTC
<ec^>
Hrorek: what's your time-zone, again?
<Hrorek>
GMT +5.5
<ec^>
-find aksh
<purr>
ec^: Could not find `aksh`.
<ec^>
-find rik
<purr>
ec^: Found: :3, erika, erica, and rurik
<ec^>
-rurik
<purr>
ec^: Рюрик
<ec^>
-learn rurik =~ s/$/ [GMT +5.5]/
<purr>
ec^: Changed `rurik` to: Рюрик [GMT +5.5]
<ec^>
K, converted. Up at 7:30pm, free from 5:30 AM to 1:30 PM, presumably thence to bed.
<ljharb>
ec^: lol what you do on your github repo is your own crazy business, as long as your npm modules follow semver that's fine.
<purr>
lol
<ec^>
ljharb: see, npm pisses me off even *ignoring* comparison logic that drives me nuts; it requires a three-part digital identifier. |=
<ljharb>
in the "version" field?
<ljharb>
sure, it has to be unique and have major+minor+patch - is that what you mean?
<ec^>
Hrorek: so, see you tomorrow? (=
<ec^>
Hrorek: (tonight, my time.)
<brixen>
ec^: definitely don't want to rehash any versioning nonsense (rbenv rehash is bad enough :P)...
<brixen>
but wanted to point out that rbx versions aren't "mutable"
<ec^>
brixen: nnods
<ec^>
I was using your actions to support a more-radical viewpoint of my own; not implying your own views thereto aligned
<brixen>
a version is essentially a tuple of (label, sha), and just like MRI releases many versions of 2.2.0 with that stupid little invisible (until recently) p thing, there may be more than one sha per v3.1
<brixen>
the *only* thing people are bitching about, besides the completely clueless ones, is that all arbitrary (label, sha) are not available at any point in time
<brixen>
to which, I answer, ¯\_(ツ)_/¯
<brixen>
ec^: please do use me to support radical views :)
* brixen
points at new Twitter bio
<brixen>
ec^: btw, unsure if you saw this part, but Rubinius releases can now be made by *any* contributor with a bit
<brixen>
and that was the most important tradeoff
<brixen>
if someone fucks up, I'll delete the tag and probably repush it
<brixen>
or they can
<brixen>
but ultimately, I've decentralized releases now, which is o/~ awesome o/~
<ljharb>
why not just bump the version tho
<ljharb>
like, what are you gaining by mutating it?
<brixen>
btw, adding auto-updating to rbx very soon, and I'll be dog-fooding that *in production*
<brixen>
come at me, internet bros lol
<purr>
lol
<brixen>
ljharb: nothing is being mutated
<brixen>
tuple, (label, sha)
<brixen>
nothing. is. being. mutated. :)
<brixen>
people's tools suck, welcome to software
<ljharb>
brixen: the *github tag* is being mutated
<brixen>
the hilarious part is that given how terrible software is, people want to stack out a claim that semver is going to make that better
<brixen>
that is *hilarious*
<ljharb>
it's not a tuple. it's a pointer.
<ljharb>
label → sha
<ljharb>
and you're mutating which sha the label points to.
<ljharb>
(because a released version has nothing to do with the git repo)
<brixen>
yep, but a release is a tuple (label, sha)
<ljharb>
i get that you're claiming so. but the sha isn't part of the release.
<brixen>
every release is a definite, immutable thing
<ljharb>
the sha deals with development. not with the way it's consumed.
<brixen>
it absolutely is
<ljharb>
like, a ruby gem doesn't have a sha, it has a version.
<brixen>
why are we suddenly talking about a ruby gem?
<ljharb>
just as an example
<ljharb>
certainly a given sha is associated with a given release
<brixen>
this is my favorite part of this debate
<brixen>
no one can argue with the facts, so they add irrelevant stuff and then claim I'm somehow wrong
<brixen>
¯\_(ツ)_/¯
<brixen>
later folks, going to fix a GC
<ljharb>
"it is a tuple" isn't a fact, that's your opinion tho.
<brixen>
it is a fact
<brixen>
it's absolutely a fact
<ljharb>
if we accept that as fact, then obv your argument is logical
<brixen>
go look at a release
<ljharb>
but it's *not* a fact.
<ljharb>
where is "a release" then
<brixen>
it is *absolutely* a fact
<brixen>
go to any release tarball and you'll fine a label and a sha
<ljharb>
perhaps, for rubinius, say, that's how releases work. but it's not universal.
<ljharb>
so that may be a choice you've made, which makes it true for you
<brixen>
all I'm talking about is rbx
<ljharb>
ok
<ljharb>
so i think that's the communication problem
<ljharb>
everybody else is talking about "everything all at once"
<ljharb>
and you're talking about your snowflake project :-)
<ljharb>
saying "a release is X" means "a release of everything is X" to most people, i think
<ljharb>
if a release of rubinius is a tuple of label + sha, then great
<ljharb>
but that also means that rbx doesn't interoperate with most other software, in which the sha has nothing to do with the release.
<ljharb>
and that's totally your right to do it that way, obv
<brixen>
ljharb: people don't like to read, or listen
<brixen>
** For Rubinius, it's a function from a version number to a commit SHA. **
<brixen>
I can't be more clear
<ljharb>
i'd never read this post (just skimmed the GH thread when ec pointed me to it)
<ljharb>
but yes you are right
<ljharb>
that is clear
<ec^>
oh no are we doing this
<ljharb>
but no matter how clear or explicit you try to be, you're still deviating from the pattern most other software follows, and most other devs expect
<ec^>
I'm not even here in getting coffee
<ljharb>
so, no value judgement here
<ljharb>
but *deviating obviates your explicitness* is what i'm saying
<brixen>
ljharb: software is an abysmal mess
<ljharb>
as are humans
<ec^>
‘most’
<ec^>
no.
<brixen>
I couldn't care less about supporting the existing sacred cows of software
<ec^>
Most *node*, and only because npm.
<brixen>
my "little snowflake" project wants to make the world better
<brixen>
semver ain't it, IMO, so I'm doing something else
<brixen>
it's just that simple and not the least bit important
<ljharb>
that's totally your call to make
<ec^>
For decades, a version number has been a human thing
<ljharb>
imo semver is the best thing we've got right now tho.
<ec^>
look at less: the "version number" is r481.
<ljharb>
ec^: oh right we're not talking about semver right now tho
<ljharb>
ec^: the "most" part is applying to "sha isn't part of version number"
<ljharb>
ec^: i agree that semver has largely gained popularity with node/npm, but that's not the tree i was trying to bark up
<ec^>
it's only very recently that *dependency managers* that have started to decide they need to mutate that, into a compatibility-resolution mechanism
<ec^>
ahhhhhh
<ec^>
can you elaborate sha-isn't-part?
<ec^>
can't type too fast, one-handed and Jesus it is cool
<ljharb>
ec^: i will totes have a semver debate with you later but let's not, right now
<ec^>
cold
<ljharb>
ec^: the sha thing was brixen's earlier claim that a release (which he later clarified "of rbx") is a tuple of (label, sha)
<ec^>
ljhar be you're v. likeable
<ec^>
fuck
<ljharb>
ec^: the confusion was that i thought he was claiming that a release of anything was a said tuple, which was a miscommunication
<ec^>
ljhar →
<ec^>
what
<ec^>
now my phone completions your name to an arrow plz stop phone
<ljharb>
rofl
<ljharb>
ljhar
<brixen>
ec^: omg, someone didn't semver that damn phone
<ljharb>
rofl
<ljharb>
if that was a compliment tho, ty, i try
<ljharb>
at any rate i'm not at all making claims about what "a release of rbx" is, that's rbx maintainers' right, just like i get to make those claims only about my own software :-)
<brixen>
ec^: I hope you feel better soon, just one quick Q, what are you doing these days?
<brixen>
ljharb: let me know when you get to 10 releases a day
<brixen>
I pay for you to have coffee with Allspaw
<ec^>
paws
<ec^>
more paws
<ec^>
always paws
<ec^>
I'm a human broken record
<gkatsev>
also going to conferences in between writing paws. And in between going to conferences, writing paws.
<ljharb>
brixen: definitely not at 10 a day, i think i've only had 5-10 releases in my busiest day across multiple projects, and only 3-5 releases in a single project in a single day on my busiest project.
<ljharb>
but i've also often released something broken, and i just bump the patch, unpublish or deprecate the broken one, and move on
Hrorek has quit [Ping timeout: 272 seconds]
<ec^>
gkatsev++
<purr>
Let it be known that ec^ loves gkatsev.
<brixen>
ec^: omg, Paws!
<brixen>
I feel like I've heard about this, why haven't I heard about this
<brixen>
ec^: our interests are very much aligned, I may have to fiddle with this a little :)
<brixen>
anyway, answer at your leisure, I'll probably see the msgs if my znc + limechat doesn't die
<brixen>
afaik, neither use semver
<brixen>
nor does Linux, sadly
<ec^>
oh fuck
<ec^>
dogs got into the trash while I was gone ;_;
<ec^>
brixen: Don't know Josh Cheek, have seen vvm and hlvm and similar, but only *tertiarily* related to my work, never heard of VPRI, familiar with Elm.
<brixen>
I want to say that perhaps you should semver those dogs, but I won't. Instead, oh, that sucks, I hope there wasn't spaghetti in the trash :S
<ec^>
brixen: the aspects of my work that you'd find interesting are actually secondary, to me, to some extent: I'm basically Here For The Asynchronicity.
<brixen>
I *love* Asynchronicity all day long
<ec^>
like, dynamic syntax; *viciously* low-level core language with everything in the lang implemented on top of that (thx rbx!); evolutionary semantics;
<brixen>
at night, in my own bed, it's all Synchrony though
<ec^>
all of that are *old* thoughts, things I care about, but they sort of made it into Paws because it needed to choose *some* sort of system to implement the control-flow Stuff That Matters
<ec^>
ahhah.
<brixen>
ec^: sounds super cool
<ec^>
there was toooons of old rotten shredded lettuce, they got it everywhere >,<
<ec^>
brixen: I definitely think it is! lawlawlawl
<brixen>
ugh :(
<ec^>
In some weird ways, I don't really ... care about Paws
<ec^>
I am desperate to see what kinds of things people might build *on top of*, or out of, it
<brixen>
haha, pretty sure I know what you mean
<brixen>
I feel the same about rbx
<ec^>
Like, I'm equally ecstatic if Paws becomes the Next Big Thing and everybody's writing in Paws-based languages,
<brixen>
this is my current position: I'm trying to write a protocol for implementing languages
<ec^>
or if nobody ever hears about my work for all eternity, but one of the neat people who chill out in this room *build* the Next Big Thing, and it plays with explicit asynchronicity in the same ways that Paws innovated
<ec^>
a protocol?
<ec^>
in terms of on-the-wire, because I don't get what you mean, or do you have a more humanistic definition? :x
<brixen>
"Protocols are far better than APIs because they invite multiple competing implementations of the same thing. They debug themselves over time by virtue of non-interaction between peers. And they open up the design space, rather than closing it down."
<ec^>
that image with haskell/lisp
<ec^>
oh, absolutely
<brixen>
I'm giddy about protocols
<ec^>
Specification == protocol, though?
<ec^>
it's long, I'm reading, but summarize
<brixen>
well, I'm not sure what the exact definition is
<brixen>
but that quote above is how I'm thinking about it
<brixen>
I'm focused on the instruction set and trying to make that more of a "protocol" than an "API"
<ec^>
ugh erlang
<brixen>
I want to abolish ecosystems like the JVM and companies like Oracle
<brixen>
and I want to permit people in conflict superficially to collaborate without having to agree with each other
* ec^
nods
<ec^>
that last line cements why I decided to eschew syntax or high-level semantics with Paws.
<ec^>
The *only* parts I am designing or writing, are the parts that can't be written in terms of the other parts.
<brixen>
which is why I don't like the current fascination with "RFC"-driven development in Ember and Rust (at least)
<brixen>
yeah, that's a fascinating consideration
<ec^>
Long ago I established a rule that if I could see a way to implement something I wanted *in terms of* some other part, then I'd immediately stop thinking about it, forever.
<ec^>
(With a sufficiently long value of ‘forever’ that ‘Paws exists and is usable in every other way’ by the time it arrives.)
<ec^>
Point being that if *I* could implement it in one way, on top of existing work; then *somebody else* could implement it *another* way
Hrorek has joined #elliottcable
<ec^>
and more importantly, somebody would only do so if it were necessary.
<ec^>
So two birds, one stone:
<brixen>
I've come to somewhat different conclusion: I reject the, "all you need to do is compose X and Y and you have Z, so Z is derivative and not essential"
<ec^>
1. I get to find out if it's an essential part *at all*, for free
<ec^>
2. I get to find out the most popular / best way to do it, for free
<ec^>
3. by dint of just ... not doing it at all.
<ec^>
see, I think it's essential and wonderful and important,
<ec^>
don't confuse me for the mathematical type,
<ec^>
but I also think *if it's essential*, then *I am not good enough to decide*.
<ec^>
I only want to make the decisions I *absolutely have to*, because I am very sure that I am not good enough to be making most of the decisions.
<ec^>
LOL
<purr>
LOL
<ec^>
Don't Panic
<ec^>
the title is fascinating. Have not seen. pinboard'd.
<brixen>
I do agree with only making the decisions you're forced to make
<brixen>
that's super wise actually
<brixen>
and exactly contrary to most language designers who think they need to make *all the important* decisions
<ec^>
lol The Things You Learn when working on a language for six years |=
<brixen>
yes
<brixen>
so, see my pinned tweet and watch that video if you haven't
<ec^>
I definitely have some interesting thoughts on the development of features, bikeshedding, language design ...
<ec^>
It was definitely misleading when I said ‘those are the things I don't care about’ earlier
<brixen>
consider closely what Snowden says about *exaptation* vs *adaptation*
<ec^>
I just care about them *less*. If Paws, which satisfies both of these ares of interest of mine, doesn't work out ... then I'd be a lot more devestated if nobody ever implemented my *concurrency/asynchronicity* innovations, than if nobody ever implemented my dynamic-language-communities plans. :P
<brixen>
ec^: have you been to an emerging langs sub-conf at StrangeLoop?
<ec^>
no )'=
<brixen>
me neither
<ec^>
I've missed StrangeLoop *four years in a row*
<ec^>
it hurts. deep.
<brixen>
the first one was in Portland
<ec^>
The ticket-sales are always at realllllllllly unfortunate times of day for me.
<brixen>
and I had a lot of hope for it, but unsure of the vibe there now
<ec^>
I've slept through them, despite alarms and friend-support and desperate desire to attend, four years in a row.
<ec^>
This year I said fuck it and gave a friend my credit-card information and told them to buy it for me if I wasn't answering texts.
<ec^>
It worked.
<ec^>
So, next year. :D
<brixen>
I really want a place to hang with people thinking about these things that isn't dominated by 1. "Types" and 2. "LISP is God"
<ec^>
Welcome to #ELLIOTTCABLE.
<brixen>
I will try to go next year
<ec^>
Nominally a PLT channel, sometimes, a little bit, when it's not too sujwhooeey.
<ec^>
SJWey*.
<ec^>
brixen: video you linked: I *hate* videos, give me a one-liner that convinces me this is worth an hour of my time. =3
<ec^>
er, pinned8
<brixen>
so, if I were to summarize my view on instruction sets, it's this: reductionism is a disease, life doesn't work that way, I want to provide the minimum viable complexity for ecosystems to thrive without having to kill each other off
<brixen>
dude, it will be the most you learn in one hour of time in recent memory
<brixen>
I've watched it a dozen times
<brixen>
that's why it's pinned
<brixen>
dude has a book coming, finally
* ec^
nods
<brixen>
I hate videos too, so watch it 2x playback :)
<ec^>
seems you are a veritable font of references.
<brixen>
I think about this stuff every waking moment and most sleeping ones too
<brixen>
if I were satisfied with pat answers I'd be off programming Haskell or something
<brixen>
:)
<brixen>
and rest assured, when Oracle comes out with a paper titled, "One VM to Rule Them All", I will spend my ever last moment destroying that company
<brixen>
:)
<brixen>
I despise rulers of anything
<brixen>
as if Java weren't enough of a scourge on this earth
<ec^>
holy shit
<ec^>
just re-read the abstract of smarr's paper
<ec^>
don't have time to dive in now, but there's, like, a 20% chance that his OMOP *is* paws.
<ec^>
or like, the broad strokes that I care about.
<brixen>
I love the page that just says, "Don't Panic" lolol
<purr>
lolol
<ec^>
yah that was my response up there
<brixen>
purr++
<purr>
Let it be known that brixen loves purr.
<brixen>
it's good shit, man, been reading that for 2+ years now
* brixen
sheds tears for 2 more years wasted in the bowels of shit head corporations
<ec^>
brixen: where are you located?
<brixen>
Portland
<brixen>
the one on the west coast, no the east coast :)
<ec^>
whaaaaat
<ec^>
no fucking way
<ec^>
oh wait
<ec^>
mis-read that
<ec^>
ugh
<brixen>
heh
<ec^>
last time i was there was for Realtime
<brixen>
yeah, we were in Chicago for about 14 months, but moved back in Mar 2015
<ec^>
now &yet has gotten all weird and culty
<ec^>
and it's so sad
<ec^>
my ex / best-friend / idk lives in The Other Portland, and I've never had enough of a reason to go visit
<brixen>
so much sadness
<brixen>
well, come speak at a conference here or something
<brixen>
Monitorama was fun
<ec^>
I'll never speak at anything.
<ec^>
Waaaaaay beyond me.
<brixen>
bahhh
<ec^>
But I'll definitely visit Portland; a close friend of mine lives there now
<ljharb>
if you're already using a three-part version - you just only include the first two parts in the version string - could you not just do `v1.2.0-$SHA` or something in the version string?
<brixen>
I could, but why would I want to?
<ljharb>
which i get would be awful to type and be ugly
<ljharb>
so really it just seems like you're trying to use the sha instead of a patch version, but to mean basically the same thing
<ljharb>
so i think you do use semver, you just use a different numbering scheme for the patch ;-)
<ec^>
I mean I've seen it but fuck if I remember anything
<brixen>
I basically just bought the directors cut on iTunes because I couldn't watch it whenever I wanted
<ljharb>
where it's $MAGIC.$MAJOR and then you've gotten rid of minor and patch :-
<ljharb>
:-/
<ec^>
yeah, not a fan of minor.patch at all
<ec^>
Ugh there's so much to say about it but it's *reeking* of bikeshedding right now
<ljharb>
yeah
<ljharb>
actually not gotten rid of, just squashed minor and patch into "sha"
<ec^>
brixen, ljharb, I love both of you (well, I love one of you, and am quickly coming to love the second one of you), but can we not bikeshed anymore on this particular topic in here *until* JavaScript or Ruby gets to the level of static-analysis where there's an *alternative*?
<ljharb>
and removed the ability to compare two of them independent of the repo and determine which is newer.
<ljharb>
lol k
<purr>
lol
<brixen>
indeed, I much prefer our other discussion to this version one :)
<ec^>
Like, I think we're all on the same page about what each of the other of us believes; we're not going to change rbenv or npm, nor is rbenv going to change rbx, so like. The rest of anything that could possibly be said is masturbation. :P
<ec^>
I really need to actually *try* Elm.
<brixen>
well, I think people don't understand what I've said, or why, but that's ultimately immaterial
<ec^>
And try Rust again, now that it's mature; I haven't touched it in *forever*, but everything I've heard in the last 6 months has gotten me so code-aroused that it's not even funny.
<ec^>
But I just haven't had the time or spoons for new programming languages in a whioe.
<brixen>
I doubt anyone ever understands anything, they just rationalize why they made a choice
<ec^>
Which is so fucking ironic, because I'm that guy who's always been telling people “Learn a new programming language every three months!” for yeaaaaaars.
Hrorek has quit [Ping timeout: 256 seconds]
<brixen>
ec^: I just want to make it possible for people to write whatever language they want and never *ever* be held hostage to someone else's crappy language decisions
<brixen>
this is what I live for
<ec^>
see, I don't see how that's possible.
Hrorek has joined #elliottcable
<ec^>
Unless you're building a statically compiled language for a *single* CPU architecture; and even then, you're constrained to both 1. that architecture's general decisions, and 2. the vonn neumann approach as a whole
<brixen>
well, going on 25-too-many-years now, there are two things that have prevented that for me: 1. access to a platform, 2. tools that make it feasible
<brixen>
ah, well, hardware is coming out of our ears
<brixen>
and my insn set as a protocol (IaaP ?) is aimed at making both hardware platform and OS / env (think browser) irrelevant
<ec^>
ugh how does i IRC
<ec^>
brixen: Interesting. Is this intended to be virtualized (LLVM/HLVM levels), or are you trying to get actual hardware to implement this? :P
<ec^>
understand I know literally nothing about your work
<ec^>
last time I saw Rubinius even was in 2009.
<brixen>
I think we still had the GIL then, no wonder you left...
<ec^>
I've been buried in my tiny little masturbatory oxygen-deprived Paws world for going on six years. >,>
* brixen
has a good cry
<brixen>
so, the first thing I'm doing is discarding the idea that the VM matters one whit
<brixen>
I *have* to build a VM right now because all the other ones are useless (mostly)
<brixen>
the 2nd thing I'm doing is trying to design the primitives in a way that maximizes re-use in languages, which has the nice side effect of maximizing interoperability
<ec^>
‘in languages’
<brixen>
all those JS langs, and all those Java VM langs, don't share shit
<brixen>
for the most part
<ec^>
a regular topic of conversation in here is the *variety* in paradigms
<ec^>
do you really think it's a good idea to try and find the common denominator of *all languages*?
<brixen>
yes, which is what Marr's thesis touches on
<brixen>
no, not at all
<ec^>
or did I mis-parse you, and you really just mean <imperative langs>, or,
<brixen>
there is no common denominator, it's a lie, flee with your life!
<brixen>
there's a cesspool of DNA fragments that can support an explosion of life
<brixen>
eyeballs re-invented multiple times
<ec^>
yeah, that's kinda my point
<brixen>
but exaptation is king, not composition and not adaptation
* brixen
channels Snowden
<brixen>
Snowden, Dave Snowden
<ec^>
so what are you trying to do here, specifically? are you just supporting Ruby/JavaScript-y languages? What about the logic languages, the stack languages, the Paws, for that matter? :P
<brixen>
the NSA is all over this little corner of the 'net now, sorry :'(
<brixen>
I have two pretty fundamental building blocks: 1. objects (both OO and "data", "functional", "structs" or whatever the hell you want to call them), and,
<ec^>
objects are supported at the instruction level?
<ec^>
so this is an HLVM
<ec^>
?
<brixen>
2. an instruction set that has: a) stack, b) register, c) assertion, d) instrumentation, and e) PEG parsing
<brixen>
furthermore, the insn set exposes object allocation directly
<brixen>
so that the full semantics are manipulable by languages
<brixen>
there are *no* semantics that are hidden behind some "primitive" function
<ec^>
3:56 PM <brixen> there are *no* semantics that are hidden behind some "primitive" function
<ec^>
explicate
<brixen>
here's one of the things that appears impossible to accept for instruction set designers: the instructions are not necessarily "primitive" operations that are non-de-composable
* ec^
nods
<ec^>
That I'm heavily into.
<brixen>
so, right now, to add to machine integers in Rubinius, you call the + method and it dispatches to a primitive function that untags, adds, retags the values
<brixen>
this sucks
<ec^>
For *common tasks*, that are *usefully* more powerful when implemented at the VM level, there's no reason not to include them.
<ec^>
The question is “what is a common task.”
<ec^>
/=
<brixen>
my new insn set has instructions that eg untag when loading into a register, and retag when saving back to a register
<ec^>
ban
<ec^>
shit
<brixen>
and I have registers that hold native values, not just tagged pointers or object references
<ec^>
brixen: you're quickly getting over my head; I've never written a compiler in my life.
gq has joined #elliottcable
<brixen>
for almost every language feature you can think of, some designer thought that A || B was the best choice, and I'm saying A && B is probably better
<brixen>
ok, let's back up :)
<ec^>
My design is *still* implemented only as an interpreter (although quite a few people have made attempts at JITs/VMs)
<brixen>
writing compilers is so fun, I'll help you :)
<brixen>
omg, you should play with Rubinius more
<brixen>
just go install it right now
<brixen>
don't use rbenv though :p
<ec^>
lmao
<ec^>
Another time. I *am supposed* to be working. And am failing badly.
<ec^>
Going to go refill my water, close IRC, and actually Write Goddamn Tests. #yesistilltdd #yesiknowitis2016 #fuckoff
<gq>
heh
<ec^>
also, hi, gq
<ec^>
-gq
<gq>
hello and goodbye then (:
<purr>
ec^: genderqueer
<gq>
-ec
<purr>
gq: o hater of things, a cuking jerk [b-sol: 7 162 ſ]
<ec^>
-find dev
<purr>
ec^: Found: devyn, gqbrielle, perspective, devyn devyn devyn devyn, and is it done yet
<gq>
pffff
<gq>
-elliottcable
<purr>
gq: o hater of things, a cuking jerk [b-sol: 7 162 ſ]
<ec^>
-gqbrielle @ gq
<purr>
gq: she is not devyn (I think.)
<gq>
:)
<gq>
-purr
* purr
<ec^>
Thought of you the other day
<ec^>
Cannot remember why. Will. Probably. At some point.
<ec^>
if you wish to catch up on the recent chatter
<gq>
tyvm
<ec^>
brixen: I'm not precisely *afraid* of compiler-dev, don't mistake me
<ec^>
The problem is my language work is ... very strange. There's parts of it that lend themselves to compilation, but parts that are going to be very, very difficult to wrangle.
<brixen>
I didn't think you were :)
<brixen>
if you have to work, no worries
<brixen>
we can catch up on this later
<ec^>
dynamic_method 'g'?
<brixen>
dynamic_method is a little interface directly to the compiler toolchain from Ruby
<brixen>
it's cute, right?
<brixen>
evan added it
<brixen>
anyway, g is a reference to a "Generator" object
<brixen>
you call methods on it that represent the instructions you want to use
<brixen>
and it wraps it all up in the end, after you "end" the dynamic_method block (/me made a pun), and makes an executable
<brixen>
then when you dispatch to that method name, it finds the executable and calls it
* ec^
nods
<ec^>
and this is first-class? i.e. it's compiled at the time you return from that block?
<brixen>
yep
<ec^>
and the result is a first-class, idk, method or whatever
<ec^>
it's been forever since i Ruby'd
<brixen>
CompiledCode object, yessiry
<ec^>
all I can remember is vast horror at the existence of meta-meta-singletons
<brixen>
hahahah
<ec^>
that's basically what drove me away
<brixen>
Ruby is so broken
<ec^>
that and parse.y circa 2008 or 2009
<ec^>
Oh I deeply, deeply love it
<brixen>
I've been writing a lot of Bash recently, it's demonstrably superior to Ruby
<ec^>
it just ... I kinda out-grew it? The things I wanted to do at the time, yeah
<ec^>
ugh fuck bash
<ec^>
zsh or dash, but don't go half-way
<brixen>
hahah
<ljharb>
i love bash now that i write posix all the time
<ec^>
I write *so* much shell-script. It's probably actually my favourite pas-time, but, I wouldn't call it *superior* to Ruby, as a language ...
<brixen>
oh, it's not
<ec^>
brixen: ljharb and I have had some interesting shell-scripting discussions
<brixen>
I bet
<ec^>
interesting that I've somehow acquired no less than *three* people who *actually write sh*
<ec^>
Does anybody know of any literature on avoiding deadlocks in concurrent systems?
<ec^>
basically, how do existing systems deal with the following situation:
<ec^>
(capitals being procedures, lowercases being data)
<ec^>
A needs x and y to preform its' operation; B needs y and x. A locks x, B locks y.
<ec^>
The catch: A *needs x* to determine *what the second thing is*; and by the time it's done the work and resolved that need to be y, y is already locked elsewhere.
<ec^>
(That caveat prevents an “atomically-lock-multiple-datas” tool from being a solution. This isn't just a race problem.)
<ec^>
anybody? thoughts? *Can* a system deal with this, or is this something that's just a logic error slash not my concern?
<ec^>
ugh
<ec^>
man where'd everybody useful go when I need them
* ec^
pokes ljharb / brixen / gkatsev
* ec^
and/or jfhbrook / katymoe / krainboltgreene, I don't know what kinds of dev you do. concurrent systems knowledge mebbe?
<ec^>
hate hate hate that ⌘↩ sends a message as a /me in irccloud