Navigation

    Fuze Arena Logo
    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Popular
    • Users
    • Groups
    • Help
    • Discord

    The ref keyword coming to FUZE

    Coding
    8
    24
    1533
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • spt games
      spt games @Martin last edited by

      @Martin Thanks for clearing that up. Its good to know this in advance.

      1 Reply Last reply Reply Quote 1
      • PB____
        PB____ last edited by PB____

        Thanks for the responses, I think this is an interesting discussion, but I'm still not sure if everybody is on the same page :)

        To prevent confusion, I'd like to summarize in code some things that are clear and not clear to me about how ref will behave in FUZE:

        var list = ["a"]
        print(list[0]) // prints "a"
        var otherList = noRef(list)
        print(list[0]) // still prints "a"
        otherList[0] = "b"
        print(list[0]) // still prints "a"
        var refList = withRef(list)
        print(list[0]) // now prints "c"
        refList[0] = "d"
        print(list[0]) // I'm not sure if this will print "c" or "d" now.
        list = ["e"]
        assignRef(list, ["f"])
        print(list[0]) // I'm not sure if this will print "e" or "f"
        
        print(refList[0]) // Bonus question...
        
        function noRef(values)
            values[0] = "b"
        return values
        
        function withRef(ref refValues)
           refValues[0] = "c"
        return refValues
        
        function assignRef(ref valueList, var toAssign)
            valueList = toAssign
        return void
        

        I think it's clear that ref will only be used in the function signature. So no list = [ref a, ref b]. But the underlying mechanics pose a question:

        var list = [[1]]
        var element = list[0]
        element[0] = 2
        print(list[0][0]) // should this print 1 or 2?
        
        var linkedList = [
            .value = 1,
            .previous = [],
            .next = [],
            .hasPrevious = false,
            .hasNext = false
        ]
        
        linkedList.next = [
            .value = 2,
            .previous = linkedList,
            .next = [],
            .hasPrevious = true,
            .hasNext = false
        ]
        linkedList.hasNext = true
        
        linkedList.next.previous.value = 3
        print(linkedList.value) // does this print 1 or 3? Would this behavior be consistent with the previous print example?
        

        So even though you're not using the ref keyword, there are some expectations about references when they are used in an array or a struct. If a property or element is always a copy, then it's not possible to make a proper linked list for example (since you need multiple references to the same instance in that case).

        Of course I have my expectations about how these things will be handled, but at this point, I still don't know. And I don't need to have the answers before the release, but I thought a discussion about these questions would do no harm.

        T 1 Reply Last reply Reply Quote 1
        • T
          thedos @PB____ last edited by thedos

          @PB____
          i think the thing to remember here is what fuze actually is and how it works under the hood on the actual hardware. as i mentioned before the underlying codebase for the switch is c++, which arrays and structs are copied. the key thing to differentiate however, is when speaking to the assignment operator (aka =) vs. passing into a function.

          the default behavior is to do a shallow copy in which member elements are duplicated and initialized with their source value. this gets tricky when one of those members might point to something in dynamic memory. by virtu of the shallow copy process the value of that "location" is what is copied, not the actual "data" stored in that location. this is where deep copy comes in and it will actually allocate new memory space and take the source data from that original memory location and duplicate it, essentially "decoupling" it away from the original location and its data, to its own exact duplicate of that information.

          when passing something into a function like void myFunc(int x), it is also copied by value. however you can change this behavior to pass by reference by simply changing it to be void myFunc(int& x). so now x inside the function will actually be a reference back to the original value that was passes in.

          this is why my suspicion as i mentioned in my earlier reply is that ref is just an alias for & under the hood (which in itself is just syntax sugar for * as well)

          PB____ 1 Reply Last reply Reply Quote 1
          • PB____
            PB____ @thedos last edited by PB____

            @thedos
            I do get what your saying, but I think differently about it. You can write any type of compiler or interpreter in C++ and the language it interprets can be completely different from how C++ behaves. In the end, it should matter how the FUZE team thinks it lands with their user base and targeted audience. However, it's interesting to see the different expectations people have with this.

            I like your point about shallow versus deep copy, to put it in code:

            var data = [["0"]]
            dataCopy = makeCopy(data)
            data[0][0] = "1"
            print(dataCopy[0][0]) // if passing by value creates a shallow copy, this would print "1", if it's a deep copy, it prints "0".
            function makeCopy(value)
            return value
            

            And if I understood you correctly about ref being an alias to &, then I think this is a scenario that I had already written out in code:

            var data = [0]
            assign(data, [1])
            print(data[0]) // I think you're saying you expect this to print: 1
            function assign(ref reference, value)
                reference = value
            return void
            

            It could be that I misunderstood the second scenario though, my C++ is a little rusty.

            In the end it's interesting to see peoples expectations about this. Since the nuances in it appear to be different per person.

            T 1 Reply Last reply Reply Quote 0
            • vinicity
              vinicity F last edited by

              As for me, it does not really matter as long as it is clearly communicated what kind of behavior is actually supported. One can always get around how things work by writing the appropriate code yourself.

              Besides, I trust the Fuze team to have thought this over a lot and come up with a good implementation.

              PB____ 1 Reply Last reply Reply Quote 2
              • PB____
                PB____ @vinicity last edited by

                @vinicity
                I completely agree. I'm not trying to divide here. If anything, I think it's good if people feel like they've been heard.

                I do hope people don't get too high expectations though from the discussion.

                As @spt-games said:

                I reckon for simplicity they will go for the former. FUZE's language likes simplicity over headache inducing complexity (I am looking at you C language).

                So I think it's better at this time not to anticipate any fancy patterns to use in FUZE if you were not able to do them before the update. But rather think of this as a fix for inconsistencies. Maybe the fix also leads to new things you can do, but maybe not.

                1 Reply Last reply Reply Quote 1
                • T
                  thedos @PB____ last edited by thedos

                  @PB____
                  i would say you got it. i think a better example however would be to use two independent variables and see how they behave. i think you understand where i am going with this, but for the sake of everyone else who might find this helpful.

                  function addOneCopy(input)
                      input += 1
                  return void
                  
                  function addOneRef(ref input)
                      input += 1
                  return void
                  
                  a = 1
                  b = 1
                  
                  addOneCopy(a)
                  addOneRef(b)
                  
                  print("var a is: ", a, "\n") // <-- should print 1
                  print("var b is: ", b, "\n") // <-- should print 2
                  update()
                  

                  as you can see the first function takes the value of a and copies it to input then increments that value by 1 and returns out of the function.
                  the results of which leaving the original value of a untouched.

                  the second function takes the location of (aka makes a reference back to ) b and assigns it to input then increments the value stored at the location and returns out of the function.
                  the result of which increments the value of b by 1.

                  PB____ 1 Reply Last reply Reply Quote 1
                  • PB____
                    PB____ @thedos last edited by

                    @thedos
                    Good point, if the reference remains intact on assignment, then it would make sense to use the ref keyword for primitive data types as well, and then using an int as an example would simplify the example in code :)

                    An off topic side note:

                    The ++ operator doesn't currently exist in FUZE, and it's arguable if you would want this in a loosely typed language like FUZE. To make my point:

                    var value1 = "1"
                    var value2 = value1++
                    // what are the values of value1 and value2?
                    

                    What would be the values after running this code?
                    value1 could be 2 or "11" or even worse: "2"
                    value2 could be "1" or (and although dirty, this expectation is not invalid) 1

                    If the types don't match, there is just a lot going on with these operators that even some professional developers aren't always aware of. So leaving the operator out, even though it is quite convenient to use, seems like an understandable decision in my opinion.

                    T 1 Reply Last reply Reply Quote 0
                    • T
                      thedos @PB____ last edited by

                      @PB____
                      good catch on ++, guess my head wasn't quite out of c++ syntax. i updated my post to correct that.

                      to answer your question on the incremental operator, it should throw an error. using ++ on a string isn't something that is possible as far as i am aware. although you could probably implement ++ most loosely typed languages (python, etc) also utilize the += for the reasons you mentioned.

                      for sake of conversation however, if they were both variables were int, then in your scenario value1 would be 2 and value2 would in fact be 1. to have value2 be 2 then it would need to be value2 = ++value1

                      PB____ 1 Reply Last reply Reply Quote 0
                      • PB____
                        PB____ @thedos last edited by PB____

                        @thedos

                        guess my head wasn't quite out of c++ syntax

                        That's why I thought it would be interesting to have this discussion. Since there will be a variety of backgrounds and thus expectations to how things behave. But I also think it will help to improve acceptance to the new language feature.

                        The natural response when you are confronted with something that looks familiar by association, but does not behave as expected, is disgust. It's a defensive response for situations where something is off, but you're not sure what. Of course "disgust" is a strong word, and we don't normally value by one indicator. I just think it helps to have an open mind towards the update :)

                        ++ operator discussion
                        I think this is an interesting discussion, especially since FUZE does not have this operator. I do feel that this discussion is off topic, but it seems most natural to respond in here anyway.

                        My argument regarding this operator was indeed within the context of FUZE, that is loosely typed. I absolutely agree that the ++ operator works perfectly well in C++. But FUZE is an entirely different animal.

                        A problem I see with throwing an error for incorrect types, is that the debugging capabilities in FUZE are not the best in the industry yet. One could also wonder similar questions about floats and even vectors I guess.

                        Also because FUZE is loosely typed, a mismatch in type could occur in very specific scenarios that might not occur during play testing. Since FUZE in general is used for entertainment, not business applications, it would be more fun if the game would continue with an unforeseen bug, rather than crash with an error. However, during development, you'd want to know that something is wrong.

                        In JavaScript var value2 = value1++ would be equivalent to:

                        value1 = Number(value1)
                        var value2 = value1
                        value1 = value1 + 1
                        

                        So here the ++ operator would first cast value1 to a Number, before assigning it to value2. Then after assigning to value2, value1 is modified again for the increment. As I said, this feels dirty, but as an expectation by a developer, not invalid.

                        I guess the scenario value2 = ++value1 is more simple in any case. Because, after the fact, both value1 and value2 should be equal, both by type and by value.

                        For these reasons, I am, mildly, opposed to introducing the ++/-- operators at all. But if the operators would be introduced to FUZE, I'd probably use them. But I don't need them.

                        But at this point, I do feel like I'm rambling on and am off topic.

                        EDIT: I've edited this post a couple of times, but mostly to improve how the message comes across. The message itself generally stayed the same.

                        I would also like to add, that although I say I am opposed to introducing ++, I would be happy to use it at the same time :-)

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post