My favourite Gleam feature confuses people...

Поділитися
Вставка
  • Опубліковано 7 січ 2025

КОМЕНТАРІ • 61

  • @giacomo_cavalieri
    @giacomo_cavalieri Місяць тому +19

    That's a great explanation!! Visually seeing the transformation take place makes it a whole lot easier to grok

  • @ChristopherDeVries
    @ChristopherDeVries Місяць тому +14

    Implementing defer as an example is brilliant! Really great video.

  • @tiggax2000
    @tiggax2000 Місяць тому +3

    Isnt there one too many parentheses after the "zorua" at 1:43 ?

  • @zill_laiss
    @zill_laiss Місяць тому +7

    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 :(

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +2

      You'll start to love it as you write more Gleam. It's so great

  • @Metruzanca
    @Metruzanca Місяць тому +8

    Already know this because of Giacomo. Take my view though of course

  • @CalebCleavinger
    @CalebCleavinger Місяць тому +2

    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...

  • @consciouscode8150
    @consciouscode8150 Місяць тому +2

    Reminds me of continuations, monads, and coroutines but in a pretty nice abstraction

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      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

  • @dupdrop
    @dupdrop Місяць тому +7

    Looks a lot like Haskell's do-notation

    • @nathansnail
      @nathansnail Місяць тому

      Seems very similar, lets you write a heavily nested lambda in a procedural way. Other than not using monads it seems almost identical.

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +2

      It was probably somewhat inspired by that for sure

    • @vytah
      @vytah Місяць тому +1

      ​@@nathansnailit uses monads though

    • @nathansnail
      @nathansnail Місяць тому

      @@vytah how so? it doesn't seem to add any additional monadic structure from what the video shows.

  • @asdqwe4427
    @asdqwe4427 Місяць тому +4

    This will be my language for advent of code, no doubt

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      Go for it! And check out the gladvent package

  • @funkdefied1
    @funkdefied1 Місяць тому +1

    Using gleam for advent of code this year. Thanks, Isaac!

  • @JakoTheWacko
    @JakoTheWacko Місяць тому +1

    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?

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +2

      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.

  • @ivanjermakov
    @ivanjermakov Місяць тому +1

    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).

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +4

      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

    • @ivanjermakov
      @ivanjermakov Місяць тому

      @@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
      @IsaacHarrisHolt  Місяць тому

      Thank you :)

  • @khai96x
    @khai96x Місяць тому

    That's a great innovation! I wonder if more languages should adopt this pattern.

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      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

    • @khai96x
      @khai96x Місяць тому

      @@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?

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      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)

  • @disguisedpigeon5465
    @disguisedpigeon5465 Місяць тому +5

    Got spoiled on Giaccomo's stream 0/10

  • @jazzkid_
    @jazzkid_ Місяць тому

    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
    }

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +1

      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.

  • @BorisBarroso
    @BorisBarroso Місяць тому

    Gleam is nice ❤. I will start learning it soon

  • @NuncNuncNuncNunc
    @NuncNuncNuncNunc Місяць тому

    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?

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      You could possibly use it in a similar way, but `use` is a lot more general than that

  • @RuySenpai
    @RuySenpai Місяць тому

    Minior gleam

  • @leenderz
    @leenderz Місяць тому

    So it's essentially async / await?

    • @asdqwe4427
      @asdqwe4427 Місяць тому +5

      No

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      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.

    • @Diamonddrake
      @Diamonddrake Місяць тому +1

      @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”

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому

      It does! You can comma separate them

  • @HomeEngineer-wm5fg
    @HomeEngineer-wm5fg Місяць тому +1

    Gleam is Woke AF.....

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +7

      Gleam is very inclusive for sure ☺️

    • @HomeEngineer-wm5fg
      @HomeEngineer-wm5fg Місяць тому +1

      @@IsaacHarrisHolt in the most annoying way.... Ask Jaguar.

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +9

      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.

    • @ahdog8
      @ahdog8 Місяць тому

      @@HomeEngineer-wm5fg who's Jaguar? I never heard of them

    • @HomeEngineer-wm5fg
      @HomeEngineer-wm5fg Місяць тому

      @@IsaacHarrisHolt if you are so inclusive, why so exclusive on diversity of opinion? Fake altruism....your religious movement is almost dead.

  • @Llenne
    @Llenne Місяць тому

    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.

    • @IsaacHarrisHolt
      @IsaacHarrisHolt  Місяць тому +3

      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...