Know what your functions are doing? - Side effects in 12+ languages
Vložit
- čas přidán 3. 07. 2024
- Code: github.com/contextfreecode/pr...
Thanks much to my patrons for their support! And to others who've contributed on specific videos and to everyone else who watches and supports the channel in any way.
Also thanks much to Brandon Blanker Lim-it for hi and bye in Filipino! / flam8studio - And also thanks to Brendan Zabarauskas for finding the link to the Haskell `catchStateT` solution and to the Koka maintainers for adding readline to the standard library for me!
0:00 Intro
0:52 JavaScript
2:02 TypeScript
2:51 Java
4:34 Zig
7:10 C++ (cpp)
9:54 Rust
11:37 C# (csharp)
12:04 Swift
12:41 Odin
13:29 Octave / Matlab
15:05 Haskell
16:14 Koka
18:32 Nim
19:56 Thanks to patrons!
20:16 Epilogue - Věda a technologie
Thanks much to Brandon Blanker Lim-it for hi and bye in Filipino! twitter.com/flam8studio
And for those interested, I got some feedback on Twitter from Zig creator Andrew Kelley. He recommends std.crypto.random.int(u64) for seeding the prng and possibly even just std.crypto.random for a random source overall, depending on the use case. For the docs, see: ziglang.org/documentation/master/std/#std;crypto.random
You can use 'out var' in c# to create the variable in the function call and avoid declaring without initialization
I think you can use a RefCell in rust to avoid unsafe. The bigger issue is that everyone can take a reference or mutable reference at any time during the programs execution, which makes it impossible to reason the borrow rules at compile time. RefCell enforces those rules at runtime and provides a safe interface for it.
Yes but in the real world RefCell has some overhead wich may not always be acceptable.
In Rust when a function does something to a argument reference,
you have to declare that in the call of the function with &mut:
modify_game(&mut my_game);
So when you see references passed around with just & and not &mut,
you know those cannot be modified.
Was surprised this clarity of side effects on the arguments wasn't mentioned
in the video.
“42 is the answer!”, nice way to end the video
2:27 - you glossed over this point, but I feel like its the most important part. Too many people say "its just a small project, its ok if I write it this way", only to find out a year later it becomes a poorly written large program that many people rely on, and no one wants to touch. Just do it right the first time!
I learn tons of new things and get inspired to learn new languages and more about the ones I work with in each of your videos! Amazing content
Great video! I think Koka is really cool and would love to see how it evolves in the future. Nim also looks promising, but that syntax for effects is kinda off-putting. In general, I wish effects where more common, knowing what your functions might do is a very powerful idea.
Thanks for the thoughts! And I should probably also have mentioned the Effekt language as another language in this space. effekt-lang.org/
@@contextfree Sounds interesting, I'll give it a look.
When I first started using Nim, the pragma syntax was a bit strange to me too, but it definitely grew on me the more I used it, I'd recommend checking it out.
Koka seems really cool, will have to check it out!
Great video, thanks! Really enjoyed the narrative and comparisons.
I hope one day I will be writing microservices in a koka-nim-like language with all the good tooling that doing so requires.
I loved this "magical mystery tour" as always! It's great to learn about languages I've never heard of before like Koka and how they compare with more "mainstream" paradigms. I know you feature Nim and Zig a lot, and I'd really like to see V (vlang) in some of these videos too! It's my favorite language to use at the moment and there are some really cool design choices like static memory management, no null, options, concurrency, and "auto" pass-by-value or by-reference! Such a breeze to learn too.
Excellent video! I learned a lot!
Yes you include all the languages I wanted, even Odin!
Great video! The talk of in and out parameters reminded me of Mercury, which allows the same predicate to be used in multiple different modes. For example:
% Standard append predicate:
% append(Start, End, List) is true iff
% `List' is the result of concatenating `Start' and `End'.
%
:- pred append(list(T), list(T), list(T)).
:- mode append(di, di, uo) is det.
:- mode append(in, in, out) is det.
:- mode append(in, in, in) is semidet. % implied
:- mode append(in, out, in) is semidet.
:- mode append(out, out, in) is multi.
:- func append(list(T), list(T)) = list(T).
...
append([], Ys, Ys).
append([X | Xs], Ys, [X | Zs]) :-
list.append(Xs, Ys, Zs).
append(Xs, Ys) = Zs :-
list.append(Xs, Ys, Zs).
It provides both the ability to use append like a predicate, or like a function call.
- github.com/Mercury-Language/mercury/blob/09e82ab9443ab11d3e90c3da895cbb4c2b1a7355/library/list.m#L88-L104
- github.com/Mercury-Language/mercury/blob/09e82ab9443ab11d3e90c3da895cbb4c2b1a7355/library/list.m#L2198-L2203
More information on the mode declarations can be found here (Mercury's docs are notoriously impenetrable, alas): www.mercurylang.org/information/doc-release/mercury_ref/Modes.html
Its approach to determinism is fascinating as well: www.mercurylang.org/information/doc-release/mercury_ref/Determinism.html
Thanks for the info. I definitely need to try out Mercury sometime.
Is that like Prolog? Please don't remind me of that horror, on the other hand, a language design discussion on that would be neat since it does things very uniquely
Yeah, Mercury is a logical language like Prolog, but I personally can't speak to the differences at the moment. But I totally want to spend some time in such languages and see what I can learn. (I get the basic gist but haven't spent nearly enough time.)
@@contextfree I was recently surprised that Logical languages actually get used in production. terminusdb and the original Erlang interpreter are written in Prolog. It was fun learning it, but I'm not sure if you are really gaining much from using them over other languages (the same with Haskell)
I teach Prolog at my university and wrote the vs code parser for it. If you ever want someone to ping for questions/explainations, feel free to reach out! I might not know all the answers, but starting out can be pretty brain crushing. Students often tell me it's their most hated language by far 😅. I'd love to see a video someday with your your thoughts/comparisons of it.
Thank you for the privilege :) happy to represent the filipino devs
Edit: in Rust.
I use AtomicU32 & friends for global integers. If you use Relaxed for the ordering parameter to load and store, it compiles down if you have any compiler optimisations.
Damn, I didn't know nor about Koka nor about Nim, and these explicit effect features look really nice.
i didnt know i'd see you here! hello from Discord
@@ribosomerocker Wait what's your username? 👀
@@Speykious GalacticColourisation
@@ribosomerocker Oh I see
How is this guy so proficient in so many languages. At best I'm almost quite good in one language while being kinda ok in like 2 or 3 others. This guy is a savant!
Well, I'm not expert in all of them by any means! But I do study the specific topics for each video and don't always entirely mess them all up.
In C# you can use in to make references that cannot be changed
Thanks
Awesome! Thanks so much for the support!
This would have personally been more interesting to me to see your perspective in this example based context of how Go(lang)'s paradigms compare.
- "How many languages do you want to learn?'
- ContextFree: "yes"
19:38 I'm getting the itch thanks to Go, Erlang and friends about state in global variables. Now that I'm thinking deeper about it, the languages that seek to reduce communication by sharing memory make a trade in terms of implementing scheduling systems (runtimes?) for how coroutines interact (either actors directly, or like goroutines sharing channels). Is there an efficiency trade-off between using shared state in global variables compared to using message-passing for transmitting updates?
Is this a series building up to parametric region and effect types?
Using Deno to run JS code butters my buns
In the Zig program, is it intentional that you write stdout.print for the error count message?
Reviewing my code across languages, I think I was just being sloppy there. Very reasonable question for sure.
I happen to know MatLab; and taking off the 'game =' does not discard your result; it just saves it to 'ans'. If you have a function return 'ans' it will just return the output to whatever the last thing you ran was. In this case, ans would have been set to the value returned by play(game), then the number of bytes sent to the console by the first fprintf, then the number of bytes sent to the console by the second fprintf.
Returning ans is a very stupid thing to do if you are making a real program because it gets reset so often, but on Cody, the official matlab code competition, saving to a variable costs you 2 complexity points, so you always have to save as much to ans as possible.
Yeah, I tend to think about `ans` only the context of interactive use. Thanks for the reminder!
@@contextfree Yeah, that's probably the best way to think of it XD. It's soo hard to debug code when half of your statements are just referring to ans and you have to keep track of what each line is going to output rather than being able to name it something sensible...
Gulat ako sa kamusta!
And this is the perl version, as you can see the whole thing is a single line that looks like a cat walked over the keyboard.
And unlike other languages that have variables and functions that cannot be modified, perl whole code can never modified again after being written... As no one really can tell whats is going on here, but i assure you it is the most clever of all versions
Curious if you’ve taken a look at Swift’s new async features, I’m biased but they seem more comprehensive than in other languages I’ve seen
In which ways swift's async/await better than c# or js syntax? As far as i know they have same semantis as evryone has.
@@TheRPGminer as far as async/await syntax… yes it’s the same. But it also has priority and grouping scheduling of “tasks”, actors as a first class type, and many compile time checks.
I've looked at it some but I haven't tried them out. Probably should sometime.
@@contextfree I think there are many great features worth covering in Swift. I’m a Rust advocate, but Swift’s design is amazing in many ways (doubly named arguments i.e. function calls reading like sentences, memory management with Arc, and more). Would be great if you could cover it. Graydon Hoare's working on it, so that’s at least one reason to show it some love.
13:24 named return values.
ahw, thats nice. so, the named variable is still passed as an argument right?? its just its separated in the fxn body?
14:04 copy on write in octave for efficiency.
Do you know all the languages that you show ? If yes, then how long have you been programming for ?
I know some of them pretty well and some only a little, but I do study for each video, so that helps. I've been programming since I was a kid in the 80s.
@@contextfree that's so coool
Does the notion of pure functions make sense in python?
Yep, for instance, it's the difference between `my_list.sort()`, which changes the list, and `sorted(my_list)` which calculates and returns a new list. The only problem is that Python gives you no help for tracking whether your functions are pure or effectful. Too many times I've accidentally tried to do `my_list = my_list.sort()` (which overwrites the list with None), or called `sorted(my_list)` but ignored the sorted return value.
It also makes sense for running things fast on GPU. Here's a video that another CZcamsr and I made on this topic. czcams.com/video/ljT7FGgjO3I/video.html
Put your patreon link in the first line of the video description.
Trust me bro.
Ok. Trying it out. Thanks for the advice!
kamusta ka
Rust quick trick: you can make your global safe... they just have to be atomic!
Thanks for the tip!
8:50 Pure functions are annotated with attribute pure in GCC, not attribute const.
Thanks for the comment! "The const attribute imposes greater restrictions on a function’s definition than the similar pure attribute." gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
Also on this topic: stackoverflow.com/questions/29117836
What I learned:
Every language is trash, just use C.