so it's just a syntactic sugar which allow to move a function, that is a parameter to a function, below it instead? it makes sense I guess. and honestly, as someone coming from Go, I don't really like it :(
As much as I love Kotlin and the functional-ish approach of jetpack compose for UI the sheer amount of nested lambdas is a pain. Also love your videos on Gleam! Might give it a try for my next backend...
Yep, it can help with a lot of styles of programming you'll see elsewhere, for sure. `use` with `result.try` gives you that nice railway programming experience
A use-case I'm unsure about is fold/map/filter. If a function's entire purpose is to wrap one of these operations, would it be acceptable to use `use` at the start of the function to un-indent the fold/map/filter body? Or would it be clearer to just indent the function body?
I generally don't like using `use` with recursive functions, but I've seen it used okay for fold. Apparently the argument is that it kinda looks like a for loop? I'd generally avoid using it for map or filter though - it can make it more difficult to grok what's going on in my experience.
It's great in a couple of cases, but I expected some disadvantages to be mentioned. This messes up semantics that care about what function scope they are in (meaning of return, break, etc. changes). Also because the rest of the function body gets swallowed, it does not look this elegant when you need some expressions beyond callback scope (have to surround use expr in another block).
Well it's a good job Gleam doesn't have returns or loops to break out of then! And if you need things behind the function scope, you'd either a) not use `use` or b) pull your `use` usage out into a function. While you can use a block to change the scope, you're right in that it's pretty pointless
@@IsaacHarrisHolt I admit it is a great sugar for languages that rely heavily on callbacks. Use is great because it does not propagate to the function's caller (like with async/await syntax). Great video, as usual.
@@IsaacHarrisHolt One thing I noticed is that the type of `return` must necessary change from the return type of the outer function to that of the callback function. Also, early return for the outer function is no longer possible. Is that correct?
It doesn't necessarily have to change. It'll depend on what function you're using with `use`. You'll get the return type of that function, not the callback. Of course, that function MAY return the same type as the callback (e.g. result.try, the defer example) but it doesn't have to (e.g. with list.map)
This is a great video for simple cases, but I disagree that use is always as simple as is shown here. Everything under 'use' that isn't held as a single expression (in curly braces or in a function) is being passed up and called back to the 'use' line in ways that are very hard to conceptualise. fn foo(mylist: List(Int)) { list.fold(mylist, 0, fn(x, y) { x + y }) |> int.to_string } == fn bar(mylist: List(Int)) { { use x, y int.to_string } != fn bad(mylist: List(Int)) { use x, y int.to_string // Error: Type mismatch. Expected type: Int, Found type: String }
I think this is something you get used to. Everything under `use` in the same scope becomes your callback. You're right though - this is one of the ways `use` can be misunderstood.
All this and not a single mention of the M-word. Video went a little fast for this Gleam sub-novice, but the use of use seems to resemble Scala's for comprehension construct. Is this an accurate comparison or is this something totally different?
It can be used to flatten out callbacks in Promise-based code, yes. That said, like I hopefully demonstrated in the video, it's not the only use for it.
@leenderz it would certainly feel like that since promises are a typical reason you’d use callbacks, but it’s really just waiting to execute the rest of the scope when the final callback would be called. Its not clear from the video if use supports multiple arguments to the “callback”
Useless video, defer in go doesn't exist for code alignments sake and language features in general do not exist for code alignments sake. 2000 callbacks isn't better just because it isn't nested either.
I don't think I ever said defer existed for that reason, and like I showed, you can implement it perfectly fine without `use` in a functional language. `use` just makes things a lot nicer. And I dunno, being nested 2000 levels deep would be pretty gnarly. Even the tabs v spaces folks would gang up against you there! And lastly, this video is definitely not `use`less. Seems to me that there's quite a lot of `use`ful stuff happening here...
That's a great explanation!! Visually seeing the transformation take place makes it a whole lot easier to grok
Thank you Jak!
Implementing defer as an example is brilliant! Really great video.
Thank you!
Isnt there one too many parentheses after the "zorua" at 1:43 ?
You're right!
so it's just a syntactic sugar which allow to move a function, that is a parameter to a function, below it instead? it makes sense I guess.
and honestly, as someone coming from Go, I don't really like it :(
You'll start to love it as you write more Gleam. It's so great
Already know this because of Giacomo. Take my view though of course
Much appreciated 🙇♂️
As much as I love Kotlin and the functional-ish approach of jetpack compose for UI the sheer amount of nested lambdas is a pain. Also love your videos on Gleam! Might give it a try for my next backend...
Thanks! Let me know how you get on
Reminds me of continuations, monads, and coroutines but in a pretty nice abstraction
Yep, it can help with a lot of styles of programming you'll see elsewhere, for sure. `use` with `result.try` gives you that nice railway programming experience
Looks a lot like Haskell's do-notation
Seems very similar, lets you write a heavily nested lambda in a procedural way. Other than not using monads it seems almost identical.
It was probably somewhat inspired by that for sure
@@nathansnailit uses monads though
@@vytah how so? it doesn't seem to add any additional monadic structure from what the video shows.
This will be my language for advent of code, no doubt
Go for it! And check out the gladvent package
Using gleam for advent of code this year. Thanks, Isaac!
Check out the gladvent package!
A use-case I'm unsure about is fold/map/filter. If a function's entire purpose is to wrap one of these operations, would it be acceptable to use `use` at the start of the function to un-indent the fold/map/filter body? Or would it be clearer to just indent the function body?
I generally don't like using `use` with recursive functions, but I've seen it used okay for fold. Apparently the argument is that it kinda looks like a for loop?
I'd generally avoid using it for map or filter though - it can make it more difficult to grok what's going on in my experience.
It's great in a couple of cases, but I expected some disadvantages to be mentioned. This messes up semantics that care about what function scope they are in (meaning of return, break, etc. changes). Also because the rest of the function body gets swallowed, it does not look this elegant when you need some expressions beyond callback scope (have to surround use expr in another block).
Well it's a good job Gleam doesn't have returns or loops to break out of then! And if you need things behind the function scope, you'd either a) not use `use` or b) pull your `use` usage out into a function. While you can use a block to change the scope, you're right in that it's pretty pointless
@@IsaacHarrisHolt I admit it is a great sugar for languages that rely heavily on callbacks. Use is great because it does not propagate to the function's caller (like with async/await syntax). Great video, as usual.
Thank you :)
That's a great innovation! I wonder if more languages should adopt this pattern.
It's absolutely fantastic, but I don't know if it'd work in every language. I'd be curious to see what it's like to use in JS, though
@@IsaacHarrisHolt One thing I noticed is that the type of `return` must necessary change from the return type of the outer function to that of the callback function. Also, early return for the outer function is no longer possible. Is that correct?
It doesn't necessarily have to change. It'll depend on what function you're using with `use`. You'll get the return type of that function, not the callback.
Of course, that function MAY return the same type as the callback (e.g. result.try, the defer example) but it doesn't have to (e.g. with list.map)
Got spoiled on Giaccomo's stream 0/10
Good video though
Oh yeah 100%
This is a great video for simple cases, but I disagree that use is always as simple as is shown here. Everything under 'use' that isn't held as a single expression (in curly braces or in a function) is being passed up and called back to the 'use' line in ways that are very hard to conceptualise.
fn foo(mylist: List(Int)) {
list.fold(mylist, 0, fn(x, y) {
x + y
})
|> int.to_string
}
==
fn bar(mylist: List(Int)) {
{
use x, y int.to_string
}
!=
fn bad(mylist: List(Int)) {
use x, y int.to_string // Error: Type mismatch. Expected type: Int, Found type: String
}
I think this is something you get used to. Everything under `use` in the same scope becomes your callback. You're right though - this is one of the ways `use` can be misunderstood.
Gleam is nice ❤. I will start learning it soon
You're gonna love it!
All this and not a single mention of the M-word. Video went a little fast for this Gleam sub-novice, but the use of use seems to resemble Scala's for comprehension construct. Is this an accurate comparison or is this something totally different?
You could possibly use it in a similar way, but `use` is a lot more general than that
Minior gleam
Except Lucy is always pink!
So it's essentially async / await?
No
It can be used to flatten out callbacks in Promise-based code, yes. That said, like I hopefully demonstrated in the video, it's not the only use for it.
@leenderz it would certainly feel like that since promises are a typical reason you’d use callbacks, but it’s really just waiting to execute the rest of the scope when the final callback would be called. Its not clear from the video if use supports multiple arguments to the “callback”
It does! You can comma separate them
Gleam is Woke AF.....
Gleam is very inclusive for sure ☺️
@@IsaacHarrisHolt in the most annoying way.... Ask Jaguar.
If you're not a fan of being inclusive and supporting people from all backgrounds, I kindly ask that you remove yourself from my community.
@@HomeEngineer-wm5fg who's Jaguar? I never heard of them
@@IsaacHarrisHolt if you are so inclusive, why so exclusive on diversity of opinion? Fake altruism....your religious movement is almost dead.
Useless video, defer in go doesn't exist for code alignments sake and language features in general do not exist for code alignments sake. 2000 callbacks isn't better just because it isn't nested either.
I don't think I ever said defer existed for that reason, and like I showed, you can implement it perfectly fine without `use` in a functional language. `use` just makes things a lot nicer.
And I dunno, being nested 2000 levels deep would be pretty gnarly. Even the tabs v spaces folks would gang up against you there!
And lastly, this video is definitely not `use`less. Seems to me that there's quite a lot of `use`ful stuff happening here...