Комментарии:
Please post higher resolutions
ОтветитьTime is a tool you can put on the wall, or wear it on your rizd.
The past is far behind us - the future doesn't exist.
Completely disagree about the interface naming showed here. When i look at a source code and see IRepository i immediately know that is an interface and nothing else.
That would be really confusing to me:
==========ExampleContext.cs==========
class ExampleContext {
private readonly Repository _repository; // is this an interface or a class? who the hell knows?
}
==========ExampleContext.cs==========
Kevlin Henney really is a true master of explaining software patterns in a pragmatic and easy to understand language coupled to architecture and other great examples from history and art. Also he is a nice guy if you have the privilege to talk to him in person :)
He is one of my top ten house goods in my world of software development.
I think the immutability fans miss a crucial aspect of how the idea gets implemented. Immutable doesn't mean that state never changes, but that there is an essential data "flow" from immutable inputs to well defined outputs, which could change from what it was because one of the inputs changed (not universally immutable, only locally immutable).
The flipping of data from mutable output to immutable input is where we can get a lot of the performance boosts, but only if we're doing immutable everywhere.
There was an English civil war???
ОтветитьWhat is the nuget package with all these awesome immutable collection ideas already implemented for me?
Ответитьthat's not the pythonic way. if you want something to be immutable, just don't change it.
ОтветитьHow dare you, Kevlin?! I am a Timelord. I was woven on Gallifrey
ОтветитьHow many times have you been asked this question?
Ответитьloved that array example, because it makes you realize that even an array is just that illusion, since you can happily have multiple pointers to the same piece of physical memory right before you screw everythiSegmentation Fault
Received signal 11 (SIGSEGV), core dumped.
"mother was a psychotherapist and it has had no effect on me whatsoever" /sarcasm
As a software engineer with a psychotherapist mother this hits me in the solar plexus.
IMO, Rust solves the problem of mutable vs immutable perfectly: you can still use an imperative style, but you have to be explicit about when you are sharing mutable state.
ОтветитьSo to summaries an hour of talk, kill C# use F# (for .Net)
F# can't do more than C# in respect to computability. But it can do more things in respect to optimization, and your coding practice if you stay within the functional paradigm part for the most part of your code.
A rather good comparison. Assume you build a house let's call that house C#, it works but a long the way you have to alter the house because your needs changes. I.e. you get a car, kids and such. It works but it is not pretty or effecient.
Okay 20-30 years later you get a new neighbor, he to build a new house let's call that F#. From technical specification it can exactly the same as your house, the only difference is that all the extra you put into your house came by default, hence it is designet into making the house pretty and effecient to live in.
That is mostly the differences between C# and F#. Years of research of language design and complaints about C#. Indentation do make code more readable than enclosement.
A language that is build around a very strong type system do help you get less bugs at run time, and easy bug tracing when writing code. Immutable values does make 'constant copy propagation' code an other type of optimization more common, because it takes a problem of reference counting from a graph problem to making it a simple counting problem.
Explicit mutable declaretion, does enhance readability and understandability of the code, and forces the coder more offent than explicit immutability declaretion to do so. Since a mutable value can stay the same through a life cycle, (you can ignore declaring a value 'const') but a immutable can't change. (You cannot ignore declaring a value 'mutable') Hence telling a reader of what to expect without looking through hundreds to thousand if not millions lines of code to track if a value change over time. To looking at that line of code and knowing.
Replacing loops with map, filter, fold and scan, eliminates index mismatching. And make the code more understandable.
I.e.
Map : we transform a collection of elements of type 'a to a collection of elements of type 'b.
Filter : under some predicatic (function) filter the collection such that only those where the predicate holds are returned.
Fold : given a collection of element of type 'a, transform it into a value of type 'b. (Map is strict subset of this) think of you putting a IKEA furniture together, taking a collection of pieces and folding them together to an whole. (Taking it from each other is also a fold operation)
Scan: same as fold just give me a full collection containing each iteration of fold.
I enjoy watching Kevlin's talks and I actually agree with a lot of what he has to say. Something undefinable rubs me the wrong way about him though.
ОтветитьNice example, except that now() isn't constant. So passing the now() value as an argument is a thin ice ((eager) argument evaluation moment vs moment that value is being used), and having a wish to call now() twice with a function makes ice not existing at all.
ОтветитьI think these types of talks would help people understand why immutability can be a good thing by explaining why languages choose to make strings immutable. I've found asking why strings are an immutable reference type in interviews (C#) quite interesting, everyone I've asked this question to is stumped and this highlights to me that most developers don't understand or really think about why being able to change state can lead to issues especially when multiple developers are working on something or when a bug is fixed/additional functionality is worked on at a later date.
Ответить"this is just like putting needles in your eyes but without the fun"
ОтветитьYawn, functional this functional that. Copying your data on every mutation is the lamest way imaginable of solving shared state
ОтветитьThis weekend I applied some of these ideas to my favorite personal toy-program, Conway's Game of Life. I like it!
ОтветитьYawn, functional this functional that. Copying your data on every mutation is the lamest way imaginable of solving shared state
ОтветитьThe sophisticated british inexplicably pack because supply fourthly marry toward a rambunctious ferry. accessible, ugliest delete
ОтветитьThe past tiger realistically tickle because debt controversly hug unlike a serious sandwich. terrible, spurious fiber
Ответитьtechnics 1200
Ответить"Asking a question should not change the answer." - Obviously Bertrand Meyer had never studied Quantum Mechanics.
ОтветитьBoring. Nothing new here.
ОтветитьWhat the hell are you all talking about lol
ОтветитьRed is not the universal color of danger. In Italy, it's routinely used for "Order Placed Successfully!"
ОтветитьConfucius say: "Man with clock always knows what time it is. Man with two clocks is never quite certain which time it is."
ОтветитьI'm in to any insights or beneficial behaviours I can immediately deploy and its amusing to listen to Kevlin's polemics.
I'm a big fan of software anthropo-archaeology so seeing that slim Lisp 1.5 manual did bring a tear to the eye (the one with needles in it)
Anyway while I would rather drink my own vomit than perform test driven development, banning the IF statement has become a moral imperative.
"I had a problem in my code. I used regular expressions to solve it, and now I have problem*" is such a brilliant formulation of the classic quote. You have somewhere between zero and infinity problems after using regular expressions.
ОтветитьSo let me get this straight and do a real world analogy of what you just proposed
You buy a clock and make the vendor (constructor) set the clock to the current time. Then you make space on your wall to hang it up (allocate memory (though technically that's the first step)). So if someone wants to know the time, they don't look at the clock (access it by reference), you instead take the clock off the wall go to the vendor and make him give you a second, identical clock (construct a new clock object with the same values). You give that clock to the person who wants to know the time (transfer of ownership only for the copy).
Then the inevitable happens and a second passes by. Your clock now shows the wrong time. Instead of updating the clock (updating the values in place inside your clock object), you take the clock to the vendor and create a second clock (constructor, new memory allocation, copy values), only with the extra second on the display. Then you go home, pull the old clock from the wall and put the new clock in it's place (assign your clock variable the new reference to the new clock object). You put the old clock onto a garbage pile of clocks until eventually and non deterministically a garbage truck comes by to collect them all (gc collects non referenced clocks).
Did I get that right? Because that's about as ridiculous as you can make it just so that clocks are never changed. Clocks are meant to change. A Time value might not change. But clocks are. The reasonable thing to do would be to have the clock return an immutable time object when you ask for it. Aka
```c++
class Clock {
private:
Time time;
[...]
public:
const Time getTime() const { return Time(this->time); }
[...]
};
class Time {
private:
int hour;
int minute;
public:
Time(int hour, int minute) { [bounds checking and assignment here] }
Time(const Time& time) { [assignment here] }
[...]
```
You just declare your return type const and voila, immutable. a const type can only call const declared functions. And const declared functions may never call non const functions or change members. no need to do crazy stuff.
The Persistent Stack example was enlightening!
ОтветитьWhat time is it?
What time is it?
Whoops
I too wish more languages would take on units of measure as part of the type system. I didn't know F# had that.
Ответить"Your code should be reasonable" . While this idea certainly sounds like a lack of ambission, it shouldn't. At the end of the day, the spirit behind the latest best practices stems from this idea of "reasonability". And any innovation that goes against it eventually evolves so as to become "reasonable", or it gets replaced by one that does.
ОтветитьIf you put state into a class, then you are a fool. If you put state into an FP program then you stop having an FP program. ;-)
ОтветитьThis is a great if you're a beginner, and six years ago this was great. The problem is a lot of people have moved on from this, and there is a whole other list of lessons to be learned that are introduced by using this approach to coding.
For instance, how multiple threads modify their own copy of an immutable data-structure and have each of their changes get merged into the master version.
Second is that all the places where we still do loops because we're not transforming data, but instead issuing commands, eg. I need to launch 50 rockets. And also in the middle of transforming, you ma want to update status on the client screen, or you want to log the data one can monitor the results. There's different philosophies to this, including assuming logging and status updates are outside the transformation domain. That works, but is not the only option.
What we don't have is a robust debate about these various things. Instead what we have is yet another presentation such as this one, still being created that's about "hey don't use loops"