« first day (4412 days earlier)      last day (436 days later) » 
00:00 - 04:0004:00 - 00:00

12:02 AM
In Python3, these two pieces of code are evaluating differently:
            b = a.push(function).evaluate()
vs.
            b = a.push(function)
            b.evaluate()
 
i never even realize there was a .push() method in python lmao
 
Well what does a.push() return
Why is it returning anything at all?
 
lmao, yeah, lists have .pop() and .push(), although in this case i implemented those myself
 
If it's a stack you're pushing to, it shouldn't return anything
Even a list shouldn't return anything on push
 
def push(self, a):
    self.stack.append(a)
    return self
@lyxal i know, except i had just changed it so it would return something on .push()
 
12:05 AM
@AviFS i thought it was append, not push lol
 
so i don't see how return self can be any different from function chaining
 
and also whats evaluate(), its like eval()?
 
@AidenChow given that i implemented it with append myself, you must be right, haha. it does have pop, though!
 
@AviFS how do they differ in their results?
 
@lyxal i'm... not sure
the second one is the desired behavior
i had the first one, and it wasn't working properly
so i changed it to the second, and now it's better
 
12:07 AM
u need to explain more than that...
 
but i didn't expect it to change anything
@AidenChow :(
 
what does the first one give vs what does the second one give
 
@AviFS well you know the results of executing both, so how do those results differ?
 
well i haven't figured out why the first one is bugging
 
I'm not asking technically, I'm asking literally lol
 
12:08 AM
i know
 
what does the first output?
 
it's just the most unreadable piece of code i've written in this whole codebase haha
 
and what does the second one output?
 
but basically i have this:
    def _reduce(stack, function=Element(FUNCTION, "+")):
        # naively apply function to stack, until you can't anymore, then return the last one before error
        b = stack
        while True:
            a = b
            try:
                b = a.push(function)
                b.evaluate()
            except:
                return a
The comment should explain it, I hope.
 
I can only assume there's some nasty reference sharing happening there
 
12:09 AM
whats ur code for evaluate()?
 
So with an input of 1 3 2 4 5 reduce, the first one returns: 1 3 2 9 +.
Whereas the second one returns 15 +.
 
Oh
Well duh
 
Ie, the first one executes the try block successfully once, then errors.
Whereas the second one reduces until the end.
 
maybe try using .copy() on everything lol
 
?
 
12:11 AM
@AviFS evaluate returns a value, not a stack, right?
 
No, it's returning a stack
Although, it does both:
def evaluate(self):
    temp = Stack([])
    for elem in self.stack:
        ...
    self.stack = temp.stack
    return temp
Returns and modifies in place.
 
Well that seems like it's the problem
Modifying things in place will do that to you
 
WHAT AM I DOING haha
do all "friendly" scripting languages have all these reference sharing or whatever annoying things python does
i never bothered to learn about it, and i was really hoping i shouldn't have to with a python-level language
but, ie self = temp didn't work
i had to do self.stack = temp.stack
which i figured had to do with one of those things
@lyxal mind explaining?
oh wait, shoot. by chaining the two function calls, am i modifying a?
 
I just know from experience that modifying things in place like that can lead to strange bugs
@AviFS I think so
 
@lyxal why python why, is there any good reason?
i expect to pay attention to this stuff with languages emphasizing memory management and/or performance
but you'd think a scripting language could get out of your way for these things, no?
 
12:18 AM
Wouldn't you just do a.push(function).evaluate instead of assigning to b?
 
@AviFS heres an annoying issue that i always come across when modifying in place: tio.run/##K6gsycjPM7YoKPr/…
 
The codebase isn't organized enough yet for experimenting with buggy behavior to be fun, so I'm gonna stop and just use the one that works for now. But I did try making both push and evaluate non-self-modifying, and it didn't fix it.
But, I may have done something wrong, or something.
 
def push(self, a):
    # self.stack.append(a)
    return Stack([self.stack+[a]])
        # self.stack = temp.stack
    return temp
 
That looks much better
Immutability 👍
 
12:22 AM
Now, chained, it doesn't execute the try block even once. It just returns 1 3 2 4 5 reduce
I made an overcomplicated cat program, haha
 
I would argue that push shouldn't return anything
Just append to self and don't return
 
@lyxal well, i'm sorry, it's going away :p
 
@AidenChow yeah it is actually kinda fucked up that python augmented assignment can be either in-place modification or reassignment
 
@lyxal that's how i had it, but i just had something where it was useful to have it do that
and None types in python (without type checking) are a pain
so i'd rather not deal with it
@UnrelatedString i wonder how ruby compares in these domains
it seems off-hand like it must be better since it's more seriously object oriented, and lisp-inspired/macro-supporting. it seems like it'd be hard to use those patterns if you had to worry about in-place modification bugs
well thank you, guys!!
oh shit
i think... i messed something up 😂
crap
alright, all good
 
12:27 AM
yeah, i might have to make push not self-modifying
cuz that trailing + also shouldn't be there
@AviFS ^
@AviFS ^
 
I've had a few weird experiences where stack = [stack] would look like it should work, but it doesn't, meaning I have to do something like temp = stack.popAll(); stack.push(temp)
Python objects can be a bit funky when you start modifying things that aren't passed by value
 
oh yeah, it's the vyxal-king, of course you have!
just put that together, haha
@lyxal which is passed by value, again?
passed by reference is all objects?
i do feel like something might be off, or i'm just missing something, because even after the try block to:
    try:
        b = a
        b.push(function).evaluate()
 
yeah i don't think python actually passes anything by value
 
i'm still getting a trailing + in the output
@UnrelatedString i believe so?
 
you can just usually pretend some immutable built in kind of types are
 
12:31 AM
oh
maybe that's what it was
 
@UnrelatedString it passes everything by value
 
i also remember there being some thing with frozen_sets
the one time i actually read that section in the docs
 
It's just that all the values are references :p
 
true :P
 
@lyxal lol
 
12:32 AM
2
A: Python pass by value

noskloPython always passes by value. However the values are references. The only value type you have in python is "reference". Variables are names and values are references. Here is proof that python is passing by value: def myfn(x): x = 2 a = {} myfn(a) If python passed a reference to the fun...

 
i mean i could just forget the trailing function, and prepend the except block with a stack.pop()
 
@UnrelatedString unironically too :p
 
but i'd wanna be pretty sure this is actually consistent behavior haha
 
@UnrelatedString reminds me have you heard about reference equality for integers
:)
>>> int("11") is int("11")
True
>>> int("111111111111") is int("111111111111")
False
 
wait, guys, so is there any way to fix this without the stack.pop(1) botch? or should i just leave it for now?
def _reduce(stack, function=Element(FUNCTION, "+")):
    # naively apply function to stack, until you can't anymore, then return the last one before error
    b = stack
    while True:
        a = b
        try:
            b = a
            b.push(function).evaluate()
        except:
            a.pop(1)
            return a
 
12:36 AM
what's the
wait what
what's with the b = stack a = b stuff
 
idk, is there a better way to do it?
 
@UnrelatedString lol exactly my question, and whats with the b=a after that...
 
i think it's easier to digest if you read it in the original form
 
since you're using push it does, as far as i can tell, literally nothing
 
? it's def doing what it should be doing
 
12:38 AM
@AidenChow and yeah about that, if an exception comes up the assignment isn't magically getting undone just by virtue of having been in the try block
 
@AviFS here's a better question: in the call to reduce, should the original stack be left unmodified or should it be modified?
 
it naively pushes the function on the stack, then evaluates it, and repeats forever, until it errors.
once it errors, it returns the last stack state before erroring
 
So if I call with a stack of [1,2,3,4] should my stack be 15 after the function call or left unchanged
 
in other words, something like 1 3 4 5 + reduce would reduce while there are at least 2 elements on the stack. once n<2, evaluating + would error, and it would return what's left.
 
@AviFS the assignments, not the function overall
 
12:39 AM
@UnrelatedString oh, idek
 
could u explain whats the point of each of the assignments, starting from b=stack...
 
i mean, i'm happy to take any other piece of code that accomplishes the above
 
i think the play is to either make it easier to use immutable and/or copied stacks or make function application more abstract in general
 
but i'd rather get a working prototype and then come back to this hell hole of a function
 
this is the kind of thing where doing the working prototype wrong can make it unsalvageable :P
 
12:41 AM
the rest of the codebase is pretty clean, imo, so i'll just black-box this in a hidden function for now
 
3 mins ago, by lyxal
So if I call with a stack of [1,2,3,4] should my stack be 15 after the function call or left unchanged
@AviFS ^
 
wait is the stack a regular list or some sort of object?
 
@UnrelatedString not if the blackbox hidden function is tested by itself, and is used sparingly
@AidenChow object, but also basically just a fancy list
 
it feels like what's happening here is rooted in deeper problems
 
@lyxal great question
 
12:43 AM
@AviFS and the answer to the great question is...
 
this particular blackbox function isn't actually accessible to the user so you can't do 1 2 3 4 5 reduce
 
@AviFS You don't know?
 
that's just my way of testing it
but it does have a type signature
so it can only be used if there's a function on top of the stack
@lyxal tl;dr, that's illegal and would give a type error
but you couldn't do it right now anyway, because it's not a front-facing function
 
@UnrelatedString ikr, at this rate we r gonna be asking for the entire code just to debug this problem lmfao
 
oh wait, do you mean because of the default function = + thing? that's just for my testing right now, then i'll remove it. but it does need a function on top.
@AidenChow sorry, sorry lol
i thought i gave what was relevant
it's pretty small
it just relies on the .push() and .evaluate()
and i showed the relevant parts earlier
they are self-modifying, and returning
guys, i promise it's not that bad a mess, haha
but i can push it to github if someone wants
it's ~200 lines only
 
12:47 AM
maybe not make self-modifying. idk about u but ive had quite a few cryptic issues from self-modifying before
 
stack = [1, 2, 3, 4, 5]
_reduce(stack)
# or is it
# value = _reduce(stack)

print(stack)
# [1, 2, 3, 4, 5]
# or
# [15]?
assume I'm in a context where I'm allowed to call _reduce
and that stack = [1, 2, 3, 4, 5] assigns a stack object not a list
 
@lyxal v
stack = Stack([...])
stack = Function._reduce(stack, function)
 
def _reduce(stack, function):
    # naively apply function to stack, until you can't anymore, then return the last one before error
    while True:
        try:
            stack.push(function)
            stack.evaluate()
        except:
            break
no?
oh
 
my bad
 
so it's not a stack attribute
 
12:52 AM
no, it's not
this one isn't
it's an external helper function
 
def _reduce(stack, function):
    # naively apply function to stack, until you can't anymore, then return the last one before error
    temp = stack.copy()
    while True:
        try:
            temp.push(function)
            temp.evaluate()
        except:
            break
    return temp
no?
 
@lyxal it would have self, haha
but we both missed that-- my brain is fried, sorry
 
stack.copy() returns a copy of the stack object that doesn't share the same reference/id
 
@lyxal oh yeah, temp is much cleaner than a,b
ohhhhh, is temp = stack.copy() way safer than temp = stack?
 
@lyxal You do need to remove the pushed function before returning temp
 
12:55 AM
thanks a bunch
@Bubbler hey bubbler!
oh i see, no more alternating between two copies
i don't know how easy it'll be to remove the pushed function
 
@AviFS that's the idea
 
i haven't really gotten to this next step yet, but this is a joy interpreter so although i'm testing it with a function primitive (which can just be popped), it will actually take a quoted stack as a function
and i don't know yet how easy (it'll either be trivial or impossible) it'll be to un-push a quoted list, since they're of arbitrary length
i have to finalize my implementation of evaluate(), and that will determine whether the list stays quoted, or is unquoted
if it stays quoted, it's trivial to pop off. if it gets unquoted though, it shouldn't be possible to remove it. and i do believe i have to unquote it before evaluating.
 
@AviFS thats what i was talking about when i was saying copy() way back lol
 
@AidenChow i'm sorry, i just realized that
i totally didn't process that suggestion. i've never seen such a thing before, actually. (or don't remember it)
certainly not in python
 
@AviFS from copy import deepcopy exists
 
1:01 AM
@Bubbler oh neat, thanks
deepcopy is for arbitrarily nested/complex objects, i take it?
 
yes
 
1:34 AM
0
Q: Consolidate a 6-axis 2-dimensional Vector

PavelTypically, when we want to represent a magnitude and direction in 2D space, we use a 2-axis vector. These axes are typically called X and Y: This isn't always convenient, however. The game BattleTech is played on a hexagonal grid, and it's convenient for the axes to line up with the sides of the...

 
Apparently, I can't use def evaluate(self, temp=Stack([])) as a default argument for a method in class Stack.
Am I doing something wrong to be running into so many circular-import related bugs in Python?
 
I got a world record, guys.
During handling of the above exception, another exception occurred:
I've never seen that before.
I got two full sets of tracebacks in Python.
 
really?
 
... in the _reduce function, hahahahaha
 
1:42 AM
@AviFS Default arguments are only evaluated once, when the method is created. So when you do that, it tries to evaluate Stack([]) before the Stack class is created
 
@Seggan really haven't seen, or really got?
 
You might want to do temp=None instead and assign it inside the method
 
@user ohhhhhhhhh, thank you so much
 
@AviFS havent seen
happens to me all the time when dealing with io or coroutines
 
oh really? damn
@user i'm def gonna do that
 
1:43 AM
Pun intended? :P
 
1:54 AM
@Seggan Having to deal with negatives makes it a non-dupe imo
 
@Bubbler Do you mind helping me apply this to my new evaluate function?
b = stack
while True:
    a = b
    try:
        b = function.evaluate(a)
    except:
        return a
No matter where I put the deepcopies, it's still not working quite right.
 
Change a = b to a = deepcopy(b) and it should work I think
oh wait
 
Bewilderingly, if I put a print(a) statement right above the return a statement in the except block, it seems to print a different value than it returns.
 
Did you say evaluate modifies its argument?
 
The value it prints is the intended one. The value it returns is not?
@Bubbler Not anymore. It just returns a value.
Although internally, it's modifying a, and then returning that modified version.
Ooh--- do I have to do a deep copy inside there, too? It's an object so it could be doing some pass-by-reference stuff.
def evaluate(self, temp=None):
    if temp == None:
        temp = Stack([])
    for elem in self.stack:
        if elem.is_constant():
            temp.push(elem)
        if elem.is_function():
            temp.apply_function(elem.value)
    return temp
Hmm, that hasn't quite done it yet.
 
2:01 AM
cur = stack
while True:
    prev = deepcopy(cur)
    try:
        cur = function.evaluate(cur)
    except:
        return prev
 
I'll try copying it in exactly as is.
 
This way evaluate is fine to modify its argument
 
@Bubbler Thanks, the naming is much more idiomatic and easy to read.
You're now doing cur = function.evaluate(cur), too, where I had cur = function.evalute(prev)
Unfortunately, it doesn't quite have the intended behavior.
But it's not worse, either
@Bubbler So the issue is that with this version, it iterates one too many times. It returns an empty list, instead of 15.
 
CMC: Output the numbers in range [0,9] in binary.
I'm curious as to how compact this is in various languages, despite it most certainly being a duplicate.
 
1 3 2 4 5
1 3 2 9
1 3 11
1 14
15
         # <--- empty
Oh yeah, this is that thing.
except:
    print(prev)
    return prev
This prints 15, as intended, but it's returning an empty list. Two different values.
@Bubbler Help needed.
 
2:11 AM
Can you show the code around where the function is called?
 
Finally found a botch that fixes it:
            except:
                stack.stack = prev.stack
                return stack
Weirdly though, return deepcopy(prev) didn't work. Nor did any other number of permutations of ideas involving that in the except statement.
@Bubbler Where?
 
@AviFS I don't know the name of this function, but assuming it is f, the point where f is called
@AviFS Also the full function that includes this code
including the def line
 
def _reduce(stack, function=Stack([Element(FUNCTION, "+")])):
    from copy import deepcopy
    # naively apply function to stack, until you can't anymore, then return the last one before error
    curr = stack
    while True:
        prev = deepcopy(curr)
        try:
            curr = function.evaluate(curr)
        except:
            stack.stack = prev.stack
            return stack
 
Hmm
 
@Bubbler The parsing and evaluation steps essentially call it like this:
 
2:18 AM
Does stack have only one field called stack?
 
  Stack([Elem(NUM, 1), Elem(NUM, 3), Elem(NUM, 2), Elem(NUM, 4), Element(NUM, 5)]).apply_function("_reduce")
If Elem=Element, and NUM=NUMBER, that's:
Nope, it still spans two lines. :((
 
> Does stack have only one field called stack?
 
Actually, that in turn literally just becomes:
_reduce(Stack([Elem(NUM, 1), Elem(NUM, 3), Elem(NUM, 2), Elem(NUM, 4), Element(NUM, 5)]))
@Bubbler processing
@Bubbler yes, yes it does
    class Stack:
        def __init__(self, stack=[]):
            self.stack = stack

        ...
I promise I didn't do anything too crazy. I'm happy to push it to Github.
 
@AviFS I think the fundamental problem here is that "try modifying and then rewind" doesn't work well with functions that modify the argument
 
I mentioned it earlier, but it's only ~200 lines.
@Bubbler Well I know it isn't optimal, or elegant, but I didn't think it would be this bad.
 
2:25 AM
Now you learned it is this bad.
 
I mean, it would add a whole 'nother layer of complexity to the interpreter that I'm not quite ready to add, if I had to keep track of the arity of all the functions.
I'm not even sure it's possible, since Joy is TC.
So in principle, a quoted function seems like it could be undecideable-- maybe?
And this is iteratively applying an arbitrary quoted joy program. It's not one function, as the name implies, it's an arbitrary quoted program.
 
def evaluate(self, temp=None):
    if temp == None:
        temp = Stack([])
    else:
        temp = deepcopy(temp)
    for elem in self.stack:
        if elem.is_constant():
            temp.push(elem)
        if elem.is_function():
            temp.apply_function(elem.value)
    return temp
 
@Bubbler Yup, that's what I tried also.
It didn't fix the problem of the disappearing 15. I think it might have made it worse? I don't remember exactly.
 
And you'll need to apply this change everywhere
 
@$#!
 
2:28 AM
that is, every function that takes a stack must keep its input unchanged and return a new stack
 
I don't understand how this happened.
So what's my take-away, then?
@Bubbler Is that only because of this? Or should I have done that all along anyway?
 
@AviFS the take away is dont modify arguments in place :P
 
I mean every function in Joy operates on the stack. That's the whole beauty.
    def add(stack):
        a,b = stack.pop(2)
        stack.push(Element(NUMBER, a.value+b.value))

    def subtract(stack):
        a,b = stack.pop(2)
        stack.push(Element(NUMBER, a.value-b.value))

    def multiply(stack):
        a,b = stack.pop(2)
        stack.push(Element(NUMBER, a.value*b.value))

    def divide(stack):
        a,b = stack.pop(2)
        stack.push(Element(NUMBER, a.value/b.value))

    def dup(stack):
        a = stack.pop(1)
        stack.push(a)
        stack.push(a)
 
I'm off for lunch
 
I'm just struggling to understand how the original interpreter was made in C, then.
@Bubbler Is there any way not to do this given that quoted programs in Joy are TC?
@Bubbler Alright, o/
Anyway, it does work with the botch I added in the except block, on top of the deepcopy in the try block. I just don't know why the other botches in the except block don't work, and why it's returning a different value than it prints one line above.
@RydwolfPrograms o//
 
2:36 AM
The curse continues...I'm at work :p
 
Do we actually have a ToBinary challenge..?
 
@ATaco theres no way we dont
 
I canny find it
Y'know, I could Cunningham's Law it and just post it as a question and wait for someone to mark the Duplicate.
 
2:56 AM
ok there aint no way we dont have a simply convert to binary challenge
it must not have the tag or some shit
 
3:08 AM
0
Q: Number to Binary

ATacoIt seems we've managed to go all this time without a plain vanilla Number-To-Binary challenge! Whilst this will inevitably be only one element in many languages, it should put a few esolangs through their paces. I truly looked for this challenge to no avail. If it already exists, comment as such ...

 
@ATaco damn u actually did it lmao
 
3:38 AM
How do we check what interpreter Dennis used for TIO, again?
I'm interested in the Joy interpreter.
 
@NewPosts I like it, but I think we should have a discussion about that in meta.
Specifically, about making new challenges for basic/important-seeming things, when there's already an old version with restricted-source, or other constraints that go against modern CGCC sensibilities.
@user Thank you. Damn. I'm shook.
I thought it was the original implementation, but I had to make sure.
I discovered what seems to be a pretty big implementation error in the reference Joy implementation.
And I know exactly what Thunn did to have that behavior, too. His paper seems to imply it works differently.
@AncientSwordRage ⍤/
From Manfred Von Thunn's An Informal Tutorial on Joy:
> The factorial of a number is the product of successive natural numbers up to the actual parameter. The following compute instead their sums and the sum of their squares:

[0] [+] primrec
[0] [dup * +] primrec
However, applying the "sum of the squares" program to an input of 3, yields 12. Not 1+4+9=14.
I can explain what went wrong under the hood, if anyone's curious. But in the meantime, don't you guys understand it should yield 14, based on his claim in that paper?
Which is right? His implementation, or my reading of that paragraph?
@lyxal @UnrelatedString This is super related to that function you guys were helping me with from before.
@Bubbler & @AidenChow, too
It's easier to read with this TIO link:
 
00:00 - 04:0004:00 - 00:00

« first day (4412 days earlier)      last day (436 days later) »