Тёмный

Fast F#: Abstraction Addiction 

Fast F#
Подписаться 2,2 тыс.
Просмотров 1,4 тыс.
50% 1

I wanted to unpack an article I recently wrote and provide more context behind my thinking on whether we are addicted to abstraction. Perhaps we are too quick to abstract? Maybe we need a way of costing abstractions before we add them ad infinitum to our code.
=== Contact ===
Email: hi@fastfsharp.com
Mastadon: mastodon.sdf.org/@fastfsharp
Twitter: / fastfsharp
=== Tags ===
Tags: #fsharp, #dotnet

Наука

Опубликовано:

 

21 май 2023

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 20   
@FastFSharp
@FastFSharp Год назад
Are we too quick to turn to abstraction to solve our problems? Have there been times where Abstraction has actually made a problem more difficult for you?
@tullochgorum6323
@tullochgorum6323 8 месяцев назад
As others are saying, the value of abstraction is very dependent on the domain. I started out writing ecommerce sites for small businesses. In that field, even a few requests per second would have been unusual. Budgets and timescales were tight, and I was using the highest practical levels of abstraction to speed the work - because performance was a non-issue. Now I'm working on financial backtesting software that is processing billions of ticks. The performance of the code inside this super-hot loop is critical, and with a little care I've achieved improvements approaching a couple of orders of magnitude. Having a little background in C has been enormously helpful, because I have at least a hazy understanding of what's happening at the coal face. Often working with languages like Python and JavaScript, so many of today's script kiddies have entirely lost touch with the world of the CPU - with the notable exception of real-time gaming..
@talwald1680
@talwald1680 Год назад
This is a tough battle. At my workplace there is a noticeable difference in development time in places where we have abstractions in place and where we don't. However, places where performance was not taken into account when designing the architecture perform horribly compared to the places where we took the 5 extra minutes to say how to do this effectively (that is not waste time on premature optimization, but not completely ignore the fact that things take time). However, this point is incomplete. If the processing time of a system is a few minutes instead of a few seconds, then the development loop is enormous and so dev velocity goes down. I think that your point on automatic feedback of performance is critical - we are programming in python, and the tools available pail in comparison to dotnet, and our performance has always degraded from month to month. Our main product started off 2 years ago with a 30 seconds processing time per item, and now we are at 5 minutes!! This has more impact than just the cost of running the items - every QA process, system test, A/B tests, they all take hours to run instead of minutes. In summary, dev time is money, but processing time is time and money.
@tropictiger2387
@tropictiger2387 10 месяцев назад
There is a Dijkstra quote: "The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise." I think we get into trouble when we don't know what we are abstracting over. If you pick up a book on any higher level programming language it will contain explanations about things like what the primitives are or what an array is, but what will be missing is how they actually work and what are the implications of using one thing instead of another. Its only when things get large and complex that you start to notice the difference. Abstraction is an aid to reasoning, because it allows us to set aside the implementation of how something is done and focus on what it does. Abstraction can cause harm when it happens that what is being abstracted isn't understood, because at that point we don't even know if we are working with the right abstraction or not.
@AnythingGodamnit
@AnythingGodamnit Год назад
I believe it was Rico Mariano who was talking about surfacing "cost" metrics in the IDE and how much nuance there would be. Can't remember if it was his blog or a talk or whatever, but it was super interesting.
@BentRasmussen
@BentRasmussen Год назад
Depends on the domain and application as well. A simulation engine will probably naturally lead you in a specific direction (and it is fun to follow that path). We should have languages that allow precise and succint specification with as little overhead as possible and “zero cost” abstractions where possible - it should’nt necessarily be a choice between clarity and performance. Isn’t Span a good example of a zero cost abstraction? But if performance starts with awareness, having a performance “enlightened” IDE sounds fantastic - such IDE features will lead to a faster iteration loop.
@mccGoNZooo
@mccGoNZooo 6 месяцев назад
I don't think that "zero cost abstractions" are necessarily the way to go either. Oftentimes the feedback that you are doing something that will be slow is actually in the construct itself. Many zero cost abstractions in languages that tout them as being important and ubiquitous (Rust and C++ come to mind) are actually very costly; it's just that the "zero cost" part refers to the difference between what you'd implement yourself and what the abstraction costs when you use it, and you don't pay for it if you don't use it. So a zero cost abstraction doesn't actually help you identify slow things or make them clearer somehow. It's an abstraction that doesn't actually lose you efficiency (in theory), but it can be an almost completely opaque mess that you still can overuse to get something that runs very slow in the end. Overusing string concatenation and interpolation is a good example of this when combined with something like operator overloading. The ease with which you can create new strings make it more likely that you'll end up allocating tons of new strings. It's not necessarily slower than what you'd have if you had a less abstract interface to it, but it's definitely slow regardless. This is how Chrome at one point allocated memory 25000 times every time you typed one letter in the address bar. Zero cost abstractions did nothing for them in terms of accidentally causing this to happen. The only thing that could've actually saved them was having a much, much simpler code base in a less convoluted and complex language: groups.google.com/a/chromium.org/g/chromium-dev/c/EUqoIz2iFU4/m/kPZ5ZK0K3gEJ
@robertlenders8755
@robertlenders8755 Год назад
I wonder if many or most software developers are simply not up to the task of writing high performance versions of the systems they work on. To truly get high performance you need to simultaneously hold the problem domain model in your head along with a model of the CPU. You then need to refactor the data flow of your domain from whatever state it's currently in, to a state sympathetic to the CPU architecture. How many developers can take that 10,000ft view of their system? Particularly for decades old software with millions of lines of code
@FastFSharp
@FastFSharp Год назад
I hear what you are saying but I'm not sure I fully agree. I think we can make significant progress by just laying out and accessing our data in a way that is easier for the CPU. For example, use an int with a Unit of Measure to model an entity. Use Arrays instead of List (F# Lists are Linked List under the hood). Prefer to use a mutable accumulator and then present the result as an immutable set of data at the end.
@torarinvik4920
@torarinvik4920 9 месяцев назад
Im a huge fan of this channel, and of course a F# fanatic(needless to say). But I have to disagree with some of what you are saying here. The reason why OOP got popular was because of two things: The GUI was taking off, and programs started to have millions of lines of code. So OOP and abstraction became the solution to the problem of managing complexity. Now we have a new problem which is that so many system are critical and the world will suffer greatly if they fail. FP is a tool that helps us write correct software. Since hardware has become faster it enables us to focus on correctness as well as fast production speed, since the world is so competitive with new features. So it's sort of like if you have a ton of money(CPU power) you can afford to spend some on a maid, and a cook, and a gardener, and a driver, and a personal trainer, jet, butler ect. But if you are poor(embedded systems?) you have to do all those things yourself meaning you won't get as much done. If you aren't writing system that are performance critical like for instance game/graphics/audio/search engines, OS/system software, file compression software, ect. Then there isn't much reason to use a data-oriented approach as it will just complicate things. Also as far as the feature your are talking about, Visual Studio has an incredibly good profiler that is really easy to use. You can easily find the hotspots in your code. And I do agree with Casey, Blow, Acton, and those guys that there are some software out there that should be a lot faster than it is. There just isn't enough incentive to make it faster.
@Grimsleeper86
@Grimsleeper86 Год назад
I think this can extend beyond cpu architecture. Consider the common pattern of "I have some middleware web server and I have a database" Something like sql is already a high level abstraction, but often times devs use expensive abstractions in their middleware server. Like large Entity Framework queries written in linq that on every request will build up the same sql query over and over, maybe they could have just use a sql string?. Often times we say things like "Well, its just X ms per request, how bad is it really?" but when we keep layering these things on top by adding say, federated graphql on top of that we really start burning human noticeable time. We create high level abstraction matryoska dolls, where they keep seeming to do the same thing again and again (We need graphql for dynamic queries on top of REST for dynamic queries on top of Linq for dynamic queries on top of SQL for dynamic queries....) I am not sure what the fix is, because often times this does help people bring software to market where they might not have been able to earlier. I am sure squarespace is not the most CPU efficient way to make a website, but it does help lots of businesses have a website. But at the same time, every time I use a slow unresponsive app or service, I feel these things make my life worse too. In my own smaller projects, I just endeavor to have a smaller number of high level abstractions, like sql and to use those well with less overhead.
@KamillaMirabelle
@KamillaMirabelle Год назад
What i here you are saying, is that devop are done in a industrial way. It is the same as when we made thing to last a long time and should be easy to fix instead of just buying a new "better" of that thing.. it is the throw away culture in another context..
@FastFSharp
@FastFSharp Год назад
I can see this analogy. I think we need to step back and ask ourselves if we have over abstracted software development.
@torarinvik4920
@torarinvik4920 9 месяцев назад
@@FastFSharp One could make a claim that Java uses the design patterns a little bit too liberally. But when you system is that large, one starts to create a lot of mediator and delegator classes, plus factories ect. So I think it is perhaps just a symptom of having a system that is that huge. One needs to find some sort of structure that makes it practical to navigate a code base that is truely gigantic as painful as it might be.
@KamillaMirabelle
@KamillaMirabelle Год назад
Abstractions are only as bad as the person making them, understanding of the problem.. an example many people uses alot as bad example for inheritance in a OO style abstraction are the image class. Here they first comes up with a somewhat good abstraction namely the image and with methods like rescale, load and safe. It fits the normal behaviour of what you want to do with an image, invariant of the underlying format. Then they want to make a Drawable Image class. But it does not fit the image abstraction.. It is here we se the problem with abstractions, people that don not understand the problem they are trying to solve. There is no such thing as a drawable image. What they want is a canvas. You can paint a image onto it, and the change the image on the canvas and when you are done you can save it as an image, but the canvas is not an image, it is the final product of those drawings that is the image. Stating it another way, an abstraction are only as good as the understanding of the problem. The ascii character encoding made the world a much better place for most programmers because it gave a uniform way of reading and writing text in an effecient way. Your abstraction need to take into account the problems core essens, not only in form of the logic you are trying to solve, but also in the form of how you are trying to perform it. Regex are fine if you just want to do small searches, but a Determanistic finite automata are much faster if you are tokenizing long time streaming data or just huge amount of data.
@KamillaMirabelle
@KamillaMirabelle Год назад
Sorry for the many typos, auto correction on a new phone with multiple languages included at once 🫣 there are many funny autocorrects from Danish to English
@FastFSharp
@FastFSharp Год назад
I hear what you are saying, and I agree with you. I think OO leads us to overloading abstractions instead of creating separate, distinct abstractions that better model the problem we are trying to solve. In this case, Abstraction is not the problem, it's conflating abstractions.
@torarinvik4920
@torarinvik4920 9 месяцев назад
@@KamillaMirabelleYes it's the problem of poor modelling or perhaps just poor software architecture.
@KamillaMirabelle
@KamillaMirabelle 9 месяцев назад
@@torarinvik4920 f.x serde in rust are a good example of an excellent abstraction. Or given that the translation schemes are good the "plug and play" abstraction it gives the user a initiative way of using it without miss use, and it is in many cases near optimal
@mccGoNZooo
@mccGoNZooo 6 месяцев назад
The beautiful irony of your image example is that both the `Image` and the `Canvas` are entirely superfluous concepts that don't need to be abstracted at all if you realize that the only thing you actually need is a byte buffer and functions that operate on it. There is zero meaningful difference between writing into that buffer or writing the buffer itself out to disk in terms of what the meaning of the buffer is in that it doesn't matter at all to the operation. I think in many ways this reasoning of "There is an *Image* and a *Canvas*" is actually exactly the problem. Neither of those are useful abstractions in the vast majority of cases. The buffer doesn't start being a canvas when you write into it and it also wouldn't stop being one when you write it out to disk, or copy it to another buffer.
Далее
Fast F#: Who Has Inspired You?
22:55
Просмотров 779
Fast F#: Intro to Classes
22:23
Просмотров 854
Despicable Me Fart Blaster
00:51
Просмотров 4,7 млн
Fast F#: Intro to Options
23:30
Просмотров 666
Integration Tests and Unit Tests
9:01
Просмотров 98
Why Does Scrum Make Programmers HATE Coding?
16:14
Просмотров 503 тыс.
Fast F#: Intro to Active Patterns
25:21
Просмотров 1,4 тыс.
Fast F#: "Clean" Code Chat
53:16
Просмотров 4,5 тыс.
Bjarne Stroustrup: Why I Created C++ | Big Think
4:48
Rust Functions Are Weird (But Be Glad)
19:52
Просмотров 129 тыс.
Gleam for Impatient Devs
8:46
Просмотров 55 тыс.