Earlier quoted context omitted.
> The real world is all about mutable state. At some point, you need to take the training wheels off. Funny enough, I think the opposite is true. For example, if you have a moving point in the real world, there is never a point where only the x coordinate is mutated, yet you have that in your mutating code.
There are no points in the real world, the are things, like chairs. In the real world, if you were to move a chair to the right, the natural way to do it would not be to build the same kind of chair at the desired coordinate and then, upon discovering that you do not need the extra chair, to discard it. Yet, this is how immutable datastructures often work in practice. That may or may not be a worthy tradeoff, but ple…
Is your programming language unreasonable? (2015)
131–138 of 138 posts
Re: Is your programming language unreasonable? (2015)
#132In example #6, he gives this as the unreasonable approach: var repo = new CustomerRepository(); var customer = repo.GetById(42); Console.WriteLine(customer.Id); with the issue being customer can be null, which is not being accounted for. The reasonable approach he says is to use a sum type: var repo = new CustomerRepository(); var customerOrError = repo.GetById(42); if (customerOrError.IsCustomer) Console.WriteLine(c…
No. In languages like F#, you can encode in the type system that the result can be either a customer or an error. And the compiler won't let you "access" the customer until you've safely checked that the result is, indeed, the customer rather than an error. In this way you end up encoding more intent within your types and behaviours rather than implicitly letting the consumer figure it out themselves.
/u/anw's example shows that, in fact, the benefits of the type system are greater than that. Not only can the type system prevent you from accessing data before confirming that the data is present (which is, at the end of the day, not much better than an Optional type, already available in Java and others), but it can also prompt you to "handle" all possible cases.
Re: Is your programming language unreasonable? (2015)
#133Earlier quoted context omitted.
They do that because they want to keep a history of each transaction. I don't want to keep a history of all the positions of a character in my game.
> They do that because they want to keep a history of each transaction. It's about more than just history. Logging would (maybe) suffice for that. It's about getting cause and effect right when there's more than one computer separated by a distance. > I don't want to keep a history of all the positions of a character in my game. Sure - not in a single-player game. But can you take the same approach in a multiplayer g…
For one, the client must not be able to tell the server "what happened" (e.g. "I shot player B"), because that would make cheating trivial without significant extra development effort.
Rather, the client simply transmits only its own input for the server to process in its simulation. The server then gives the authoritative answer as to "what happened" to all clients. The client may need to patch up any visual discrepancy that may arise from differences in the client-local simulation.
What you propose of course isn't impossible and it's exactly what I'd expect people with a DLT background to attempt, it just doesn't really have much of an upside for what it requires. It's the wrong trade-off for the domain.
Re: Is your programming language unreasonable? (2015)
#134"Objects containing the same values should be equal by default." No. This breaks down as soon as you have references to other objects in your objects. If you compare by reference, you probably don't get what you want. If you compare by value, you need to go arbitrarily deep, which is not a sane default, because of possible reference cycles. You need a distinction between objects and value types. C# has that (record t…
> The real world is all about mutable state. At some point, you need to take the training wheels off. So the C#, VB, and F# compilers (all huge, "immutable data representations" codebases serving millions of developers worldwide) are training wheels?
Of course immutable data structures, like training wheels, make some things easier. You don't have to worry about certain classes of errors, because they just can't happen. It's the same with garbage collection, you can stop worrying about managing memory, for the most part.
However, if you can't do your job without these helpers at all, that's going to be a problem. At some point, there will be something that your garbage collector can not clean up for you. There will be state that is going to be mutated, whether you like it or not. Your brain should be prepared for that.
Re: Is your programming language unreasonable? (2015)
#135Earlier quoted context omitted.
> The real world is all about mutable state. At some point, you need to take the training wheels off. So the C#, VB, and F# compilers (all huge, "immutable data representations" codebases serving millions of developers worldwide) are training wheels?
Not sure what you mean, the C# compiler source code I looked at seems to be using a lot of mutable data structures. Of course immutable data structures, like training wheels, make some things easier. You don't have to worry about certain classes of errors, because they just can't happen. It's the same with garbage collection, you can stop worrying about managing memory, for the most part. However, if you can't do you…
I work with the C#/VB codebase for my job (at Microsoft on compilers and language tooling) and with the compiler and tooling engineers who also use this codebase. It uses nearly everything under the sun, but is most definitely based on immutable data representations at many layers of its "stack". The very notion of a compilation and a syntax tree are immutable.
> Of course immutable data structures, like training wheels, make some things easier. You don't have to worry about certain classes of errors, because they just can't happen. It's the same with garbage collection, you can stop worrying about managing memory, for the most part.
I know. I work on a language that is immutable by default.
> However, if you can't do your job without these helpers at all, that's going to be a problem. At some point, there will be something that your garbage collector can not clean up for you. There will be state that is going to be mutated, whether you like it or not. Your brain should be prepared for that.
It's not quite how you characterized it, but yes there are circumstances where a "mutable core" or even just a mutable domain make sense. Usually it's related to performance. The GC "not cleaning things" doesn't really have much to do about that though. You can create all kinds of mutable data (e.g., very large arrays) that the GC won't clean as a part of a gen0 collection.
Re: Is your programming language unreasonable? (2015)
#136Earlier quoted context omitted.
I'm not going to claim that mutability is never useful for performance, but many large scale simulations can be expressed quite elegantly using bulk operations on arrays or other structures, with no mutability in sight. Both particle simulations a la n-body and stencil operations are in this category. An efficient low-level implementation of such bulk operations involves mutable updates, just like any functional lang…
Interesting. Can you explain, with a somewhat simple example, how this can be efficiently implemented, or at all? I mean preserving the appearance of immutability at the source language level, while mutating the original structure under the hood for performance.
So there are "effects" (non-functional state changes) that are encapsulated ("benign").
I learned this term in reference to Standard ML at CMU.
This is different from what you're asking because it isn't a compiler optimization and it isn't actually checked by the language at all, but it works pretty well in practice.
It's like unsafe in Rust: you write most of your code assuming a useful property that you then break in the small percentage of code that needs to break it.
Re: Is your programming language unreasonable? (2015)
#137Earlier quoted context omitted.
> They do that because they want to keep a history of each transaction. It's about more than just history. Logging would (maybe) suffice for that. It's about getting cause and effect right when there's more than one computer separated by a distance. > I don't want to keep a history of all the positions of a character in my game. Sure - not in a single-player game. But can you take the same approach in a multiplayer g…
I don't think anybody has ever shipped anything like what you propose to simulate a real-time game, but if they did, it would be more of a curiosity. For one, the client must not be able to tell the server "what happened" (e.g. "I shot player B"), because that would make cheating trivial without significant extra development effort. Rather, the client simply transmits only its own input for the server to process in i…
The distinction I'm making is not between "I'm now moving forward" and "I'm at x position", it's between "I'm now moving forward" (mutation) and "I started moving forward at time t" (what happened).
> Rather, the client simply transmits only its own input for the server to process in its simulation. The server then gives the authoritative answer as to "what happened" to all clients.
This glosses over too much and doesn't pick a side - direct mutation or event log? How does the server simulate the game state in the face of out-of-order or dropped events?
> I don't think anybody has ever shipped anything like what you propose to simulate a real-time game, but if they did, it would be more of a curiosity.
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
The lag compensation system keeps a history of all recent player positions for one second. If a user command is executed, the server estimates at what time the command was created as follows:
Command Execution Time = Current Server Time - Packet Latency - Client View Interpolation
Then the server moves all other players - only players - back to where they were at the command execution time. The user command is executed and the hit is detected correctly. After the user command has been processed, the players revert to their original positions.
https://www.jfedor.org/quake3/
Everything in Quake 3, both client and server, happens in response to events. Player input like mouse movement and keypresses, and also packets received from the network, all go through a unified event system. Even the passing of time is communicated to the engine using a separate type of event. In addition to decoupling the engine from operating system specific code, this opens up an interesting possibility. During normal gameplay it’s possible to record all the events going through the queue in a journal file.Re: Is your programming language unreasonable? (2015)
#138Earlier quoted context omitted.
I don't think anybody has ever shipped anything like what you propose to simulate a real-time game, but if they did, it would be more of a curiosity. For one, the client must not be able to tell the server "what happened" (e.g. "I shot player B"), because that would make cheating trivial without significant extra development effort. Rather, the client simply transmits only its own input for the server to process in i…
> For one, the client must not be able to tell the server "what happened" (e.g. "I shot player B"), because that would make cheating trivial without significant extra development effort. The distinction I'm making is not between "I'm now moving forward" and "I'm at x position", it's between "I'm now moving forward" (mutation) and "I started moving forward at time t" (what happened). > Rather, the client simply transm…