News for hackers. Stuff that matters.
Re:Copying data is wasteful, mutating data is dangerous by perfunctory on Thursday January 09, 2020 @02:25PM (#22004571)
> But mutation is a cognitive burden: you need to think much harder about what your code is doing.

One way to alleviate the problem is to use naming convention.

  normalize(a)       # mutates in place. note: no return value.
  b = normalized(a)  # no mutation. returns a new instance. note the adjective.
Python does this in the standard library

  a.sort()
  b = sorted(a)
Re:Copying data is wasteful, mutating data is dangerous by kburman on Thursday January 09, 2020 @03:37PM (#22005416)
I like how ruby way of declaration if a method does mutate object or not but a exclamation mark at end to tell it modifies the object

a = a.sort or a.sort!

Re:Copying data is wasteful, mutating data is dangerous by jonnycomputer on Thursday January 09, 2020 @09:38PM (#22007943)
I like the idea of adding an exclamation or some other mark to the individual parameters in the method declaration since a method might mutate some but not all parameters.
Re:Copying data is wasteful, mutating data is dangerous by mirekrusin on Friday January 10, 2020 @02:01AM (#22008920)
Julia has this pattern as well.
Re:Copying data is wasteful, mutating data is dangerous by jszymborski on Thursday January 09, 2020 @02:46PM (#22004835)
in-place operations give me the heebie-jeebies.

I think this is something that is a slightly less obvious when dealing with classes. I see stuff like this in academic code all the time:

  class SomeDataObj:
    def __init__(self, data):
      self.data = data
    
    def normalize(self):
      self.data = normalize(self.data)
I'd much prefer for there to be variable `self.data_normalized` which is initialized to None or even better a getter `getNormalizedData()` that computes/caches a normalized variable.
Re:Copying data is wasteful, mutating data is dangerous by UncleEntity on Thursday January 09, 2020 @04:55PM (#22006334)
The pythonic way would be to have sort() and sorted() which either sort in place or return a sorted copy. Best of both worlds.
Re:Copying data is wasteful, mutating data is dangerous by ajuc on Thursday January 09, 2020 @07:01PM (#22007211)
Command Query Separation is a very good general idea in programming that should be followed more often. Sadly it went out of fashion in 90s when everybody got hyped about OOP.
Re:Copying data is wasteful, mutating data is dangerous by chewxy on Thursday January 09, 2020 @05:13PM (#22006459)
I write an maintain a generic multidimensional array package for Go, and I had come into the same problems as the OP.

The solution was to dictate that the API is copying. But also provide ways to allow the user to manage their own memory.

e.g.

    a = tensor.New(tensor.WithShape(2,2), tensor.Of(Float64))
    b, err := a.Apply(sigmoid)                      // copies
    c, err := a.Apply(sigmoid, tensor.WithReuse(a)) // mutates
Docs: https://godoc.org/gorgonia.org/tensor#Dense.Apply
Re:Copying data is wasteful, mutating data is dangerous by FridgeSeal on Thursday January 09, 2020 @04:08PM (#22005775)
It’s convention to do this in Julia as well, every package I’ve used that mutates marks the explicitly mutating function with a ! at the end.
Re:Copying data is wasteful, mutating data is dangerous by cestith on Thursday January 09, 2020 @04:35PM (#22006079)
This is consistent with Ruby. It often includes both in the core. There's .gsub() and .gsub!() for text substitution in the String class, for example, or .select() and .select!() for the Hash class.
Re:Copying data is wasteful, mutating data is dangerous by kwertzzz on Thursday January 09, 2020 @05:01PM (#22006370)
This is interesting to know, because Julia uses exactly the same approach[1] (now I know where it comes from). To me it seems to be the ideal solution: use the in-place normalize!(X) where performance is important, otherwise use the more convenient allocating variant normalize(X). The exclamation mark makes it clear that the array is modified.

[1] https://docs.julialang.org/en/v1/base/collections/#Base.sum!

Re:Copying data is wasteful, mutating data is dangerous by fasquoika on Thursday January 09, 2020 @05:15PM (#22006480)
>(now I know where it comes from)

Both Julia and Ruby got this from Scheme and it might be even older than that.

Re:Copying data is wasteful, mutating data is dangerous by anamexis on Thursday January 09, 2020 @05:22PM (#22006545)
Unfortunately it isn't completely consistent, for example Array#delete and String#concat
Re:Copying data is wasteful, mutating data is dangerous by cestith on Friday January 10, 2020 @12:08PM (#22012478)
Well, yes. Julia here is consistent with something in Ruby. In my experience it's one of the three major complaints about Ruby is how inconsistent it can be within itself.

The other two major ones are the number of core ways to the the same thing and the slowness of the interpreter. The first is a matter of taste. The second is a technical issue with the interpreter mostly independent of the language and/or a question of fitness for specific projects.

Re:Copying data is wasteful, mutating data is dangerous by benibela on Thursday January 09, 2020 @05:29PM (#22006587)
I use this convention whenever I can

I spent far too much time yesterday figuring out why nothing was being replaced, when I called replace on a string in Javascript

Re:Copying data is wasteful, mutating data is dangerous by Flicki on Saturday January 11, 2020 @03:07PM (#22021958)
Or better yet only have normalize(), mark it [[nodiscard]] and it will be pretty much impossible to fuck up.