Forbidden Rust

Поділитися
Вставка
  • Опубліковано 11 вер 2024

КОМЕНТАРІ • 156

  • @liminal6823
    @liminal6823 9 місяців тому +50

    Amazing to watch someone programming so intuitively and knowledgeably in a language he doesn't even like.

  • @mantasarmalys6471
    @mantasarmalys6471 9 місяців тому +126

    Using Makefiles for rust compilation is the most cursed thing I've seen in a while

    • @leuel_a
      @leuel_a 6 місяців тому +1

      😂

  • @Mahmudul_Hasan92
    @Mahmudul_Hasan92 9 місяців тому +18

    Wasn't expecting a masterclass on procedural macros. Probably the best explanation I have come across on the topic.

  • @somebody_on_the_internetz
    @somebody_on_the_internetz 9 місяців тому +28

    I really like his organic way of teaching a certain topic

  • @apppples
    @apppples 9 місяців тому +42

    I love how you spend the time to motivate each additional design change... this is why you're my favorite youtuber

  • @Artentus
    @Artentus 9 місяців тому +31

    Concerning macro declaration order: you can write `use ;` to "elevate" the macro into a proper symbol that behaves like everything else (inlcuding being accessible by full module path etc).
    It's a weird little quirk about declarative macros in Rust.

  • @user-ju6xh7mn2z
    @user-ju6xh7mn2z 9 місяців тому +71

    You probably already know it, but there is a library "clap" that will derive CLI interface from structs using #[derive] allowing you to have declarative style of defining your cli api

    • @L0wPressure
      @L0wPressure 9 місяців тому +28

      It’s an awesome lib, I use it occasionally, but Tsoding most likely does not give a crap about 3rd party libraries :)

    • @thebatchicle3429
      @thebatchicle3429 9 місяців тому

      Fuck clap. Why do you need thousands of lines of code for what should be a single function of 40 lines

    • @igorfedenko8212
      @igorfedenko8212 9 місяців тому +22

      ​@@L0wPressurec developers love to reinvent them wheels, let him be :)

    • @L0wPressure
      @L0wPressure 9 місяців тому +5

      @@igorfedenko8212 i'm not against it, i enjoy his streams :)

    • @abtiwary
      @abtiwary 9 місяців тому +23

      @@igorfedenko8212 Reinventing the wheel is not optimal when dealing with constraints or production code... this however is recreational programming ...the whole point of this is to learn something while having fun and diving under the hood! :)

  • @OverWilliam
    @OverWilliam 9 місяців тому +2

    I very much appreciated the "motivating example" at the beginning. It's extremely helpful to see what the "naive" way of doing something looks like so that the alternative way of doing the same thing makes more sense.

  • @stanvandijk2909
    @stanvandijk2909 6 місяців тому +1

    I was searching for someone to explain Rust Macro's. Didn't really felt like there was someone with a good example or explain video (at least not for me).
    Now just watching this video because I like how you do things and explain it simple but clear, never thought you will just do the thing I was searching for/was stuck on just because you wanted to use it for yourself. Thank you

  • @jesusmgw
    @jesusmgw 8 місяців тому +2

    Just WOW. I'm programming my entire renderer, engine and game in Rust since 1.5 years ago and I'm not even at 10% of this level of efficiency and knowledge. The bell curve meme is so real.

    • @cat47
      @cat47 2 місяці тому

      what makes you think he's so good at rust? maybe it's the emacs

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

    29:23 the typing sound with the beatboxing is definitely meme potential lol

  • @korigamik
    @korigamik 9 місяців тому +75

    He got some beef with the rust foundation after that thumbnail

    • @wetfloo
      @wetfloo 9 місяців тому +17

      rust foundation doesn't own Ferris (it's borrowed instead)

    • @jesussaez6669
      @jesussaez6669 9 місяців тому

      @@wetfloo Made me chuckle lol

  • @AntonKastritskiy
    @AntonKastritskiy 9 місяців тому +5

    This might be the best tsoding stream to date, hat off

  • @RicardoSansores
    @RicardoSansores 9 місяців тому +5

    And I think that's the reason Actix, Tower and other Rust libraries don't auto register services and controllers.
    Thanks for the video. I really like it.

  • @Browsinghard
    @Browsinghard 6 місяців тому

    Thank you for walking through the problem and showing the naive solutions first. Very insightful!

  • @TehGettinq
    @TehGettinq 9 місяців тому +3

    Btw about exitcode, quite sure that when main returns a Result, the Err variant expands to 1 (which is trivial to impl by interpreting the enum as an numeric type by position, Ok variant being 0 (success) and Err variant being 1 (i.e exit code 0/1)).
    From my understanding of what you were doing it's probably simple to just make main return a Result and so Err would automatically return "exit code" 1, and then you could add info to the Err itself (instead or alongside the eprintln()).
    Edit: obviously you're then limited to 0/1 which isn't necessarily always what you would want.

  • @zahash1045
    @zahash1045 9 місяців тому +14

    44:00 you could've just done this
    struct Command
    where
    T: Iterator,
    {
    name: &'static str,
    description: &'static str,
    run: fn(&str, T) -> ExitCode,
    }
    the reason why impl Iterator is not allowed in structs is because it hides the type.
    structs need explicit generics to reveal the whole type.
    functions don't need that because the type information is revealed in both cases
    fn foo1(a: impl Iterator) {}
    fn foo2(a: T) where T: Iterator {}
    Foo
    Foo
    foo1(SomeType1)
    foo2(SomeType2)
    without generics in struct, you would instantiate two structs of different types that look the same
    let f1: Foo = Foo { run: MyType1 }
    let f2: Foo = Foo { run: MyType2 }
    both f1 and f2 are of type Foo
    instead of Foo and Foo

  • @cacheman
    @cacheman 9 місяців тому +7

    6:36 I'm watching a man slowly going insane.

    • @cobbcoding
      @cobbcoding 9 місяців тому +2

      always has been

    • @alang.2054
      @alang.2054 9 місяців тому +2

      Terry Davis arc incoming

  • @L0wPressure
    @L0wPressure 9 місяців тому +2

    That is an amazing video. I actually found out more about rust than I did from reading books. I have not touched anything proc macros related though.

  • @pwii
    @pwii 9 місяців тому +15

    Java is not the greatest language but for some usecases it makes things very convenient. With reflection you can get a list of all classes that implement an interface and turn that into a list of commands with a single function call. Something similar should be possible in other languages, but Java is where I have implemented it myself.

    • @monad_tcp
      @monad_tcp 9 місяців тому +5

      Rust macros really are another thing, most of the times you just need to do some basic processing/generation with the metadata, not some real dynamic thing at runtime, you just need to query the program structure at compiler time.
      And you don't need to care about things like performance of reflection or security problems and reflection is a PITA to use because it literally turns your static language into a dynamic one.
      I really liked the Rust solution for this problem.
      Also, F# has a cool thing with TypeProviders that allow something similar, specially when you target the TypeProvider to a Type defined in the software. TypeProviders basically allow you to direct input any structured data as Types directly to the compiler itself, you basically compile an DLL/Assembly that loads inside the compiler and thus you can provide types for the compiler, its much more advanced than reflection, and simpler to use, almost like T4 in C#, but better and typed and you don't need to do something akin to "PHP", preprocessing like its "1990 C".

    • @stysner4580
      @stysner4580 9 місяців тому +4

      Reflection relies on a runtime and is really, really slow.

  • @Edw9n
    @Edw9n 9 місяців тому +2

    thanks for this bro. i personally loved every step of the ride. rustaocean son 🦀

  • @micksayson
    @micksayson 9 місяців тому +4

    A potential fun way to avoid the dependency on macro run order. (Note: I'm only at 1:25:00, so not sure if something else has come up later int he video)
    Instead of tracking command state in the compiler plugin, you could track the state in a custom section of the elf and collect the arguments at runtime. The linux kernel does something similar for module init where it puts function pointers in an init section of the kernel elf and iterates the section at runtime. You could do something similar where you take your command struct, and essentially pack those structs into a special section of the binary at compile/link time. Then all you have to do to get the commands back is to iterate that special section as the first thing you do in main. The gcc equivalent would be to use __attribute__((section(...)))
    I've done this a few times (never in rust though), and it's the only way I've managed to think of to get a compile time registry that doesn't depend on order of compilation

    • @micksayson
      @micksayson 9 місяців тому +1

      Doing some very quick googling, it seems like you could define static variables with #[link_section] and that would probably give the desired results. Maybe with some alignment constraints to think about

    • @flyinginthedark6188
      @flyinginthedark6188 9 місяців тому

      You can do the trick with sections, but you have to modify your linker script which is a pain, and I'm not sure even possible on windows, so it won't be cross platform.

    • @flyinginthedark6188
      @flyinginthedark6188 9 місяців тому

      You can also collect the commands at runtime if you register them via ".init" section, but once again it's super unsafe because it runs before main and once again it's not cross platform.

    • @ElPikacupacabra
      @ElPikacupacabra 2 місяці тому

      That sounds like such a pain that full-on meta-programming is preferable. Just output the source code you need. Probably much more understandable as well...

  • @foxwhite25
    @foxwhite25 9 місяців тому +4

    Rust just very recently got a parallel front-end in nightly

  • @rysw19
    @rysw19 9 місяців тому +1

    I don’t know much about Rust but I think the reason a prod macro has to be its own crate type is because it’s actually changing the way that the compiler itself processes the input.
    I’d guess that rustc actually loads the dynamic library that the proc-macro crate generates for its own use.

  • @PublicAccount0
    @PublicAccount0 9 місяців тому +1

    Your explanations are lovely.
    thank you.

  • @cobbcoding
    @cobbcoding 9 місяців тому +3

    the thumbnail will haunt my nightmares for many years to come

  • @lamprospitsillou6325
    @lamprospitsillou6325 9 місяців тому +1

    One of the best streams! Incredible as always

  • @dupdrop
    @dupdrop 9 місяців тому +7

    For making `command_list!()` execute last, you would probably need an extra crate that depends on all other crates that declare any Commands. Then, you can guarantee `command_list!()` is called after all the definition proc macros executed. Annoying, but I can't think of any other way with the current tools rust gives you.
    In theory adding support in rustc for something like an `#[order(last)]` annotation for proc-macro crates should be relatively straightforward to support, I think.
    Anyway you can now do a way shorter video about how it would be way simpler in zig/jai. At the very least it's good market pressure.

    • @mattcraftien974
      @mattcraftien974 8 місяців тому

      True.
      Although the rustier way to do it would probably be to group every function inside an impl and use an attribute macro on the whole thing.
      More parsing but no dependency to undefined compiler behavior.

  • @rodelias9378
    @rodelias9378 9 місяців тому

    Thanks mr zozin! That was really fun and educational!

  • @replikvltyoutube3727
    @replikvltyoutube3727 9 місяців тому +3

    Rustc was single threaded up until very recently XD
    No wonder Gentoo users complain about Firefox build

  • @ritchielrez1680
    @ritchielrez1680 9 місяців тому

    I am trying to build my own command line application, even as a beginner I really love ur videos, they are easy enough for me to understand and I love how unique ur takes are sometimes XD

  • @akshettrj
    @akshettrj 9 місяців тому +2

    There is a crate called inventory, you can take a look into how it works to see how not to depend on the macros being called in order of their appearance in the code

    • @Ansatz66
      @Ansatz66 9 місяців тому +1

      Except that how inventory works is extremely technical with different implementations for different operating systems and it uses the link_section attribute. In other words, if you want to do it the way that inventory does it, then it's best to just use inventory.

    • @akshettrj
      @akshettrj 9 місяців тому

      I see, I never looked at the implementation myself. Maybe I will go and have a look at it first. Thanks

  • @tianned
    @tianned 6 місяців тому

    6:37 Новосибирский Джокер😎

  • @Deemo_codes
    @Deemo_codes 9 місяців тому +3

    Surely this is supported to some extent right?
    how else would rust webframeworks be able to do #[get("/")] if it wasn't registering to somewhere?

  • @ade5324
    @ade5324 9 місяців тому +6

    How much for a lisp/scheme stream?

  • @bbq1423
    @bbq1423 9 місяців тому

    The way I normally approach this is by having a command line parser struct containing the map along with methods like add_flag or add_positional_argument that takes the the name, description and a lambda which binds the string argument to a variable captured by reference. Then after having added all commands, I call parser.parse(argc, argv). For adding subcommands you'd probably want a subcommand_start and subcommand_end as well though.

  • @tekno679
    @tekno679 9 місяців тому

    This reminds me of the time I did something similarly cursed to python type introspection to create argument parsers just from types. The library is called arcparse for anyone interested.

  • @alpaslaneldemir6904
    @alpaslaneldemir6904 9 місяців тому +1

    My milkshake brings all the args to the uppercase

  • @yaksher
    @yaksher 9 місяців тому

    @58:00 I suspect that it has something to do with the fact that proc macros are effectively compiler extensions, though I dunno what additional requirements this would place on the crate over being a normal dynamic library. It might be that they explicitly don't want it possible to include both normal code and macros from the same library, so when compiling you have to say "this is a normal library" or "this is a proc macro crate and if you want to use it for something else, it's not sanctioned by the compiler". Proc macros are DLL because they behave like an other Rust and because in large projects with complicated derive macros, they need to be fast. Which means you want them to be compiled. But they serve effectively as compiler extensions, so unless you want to recompile the entire compiler with your macro crate statically linked in, they need to be a DLL which the compiler can dynamically link against.
    @1:04:00 The reason it's a token tree and not a string or an AST, based on documentation I've read is that
    - it's a more consistent thing for the compiler to target than an AST (i.e., if additional language features add new syntax, the AST is going to have to change and this might break outstanding macros, but it'd take a damn radical change to change how the compiler tokenizes things). They're confident that matching parenthesis/square brackets/curly braces are always going to matched, but this leaves the details free to change without breaking macros. Additionally, Rust proc-macros are meant to not be limited to taking in Rust syntax and spitting out Rust syntax; they're designed to be able to take in, e.g., a DSL and spit out Rust syntax, and so while "parenthesis, etc., need to be balanced" is a reasonable limitation, they don't actually want to require that the input actually parse as valid Rust.
    - it's much easier to work with than a raw string
    @1:11:10 `for _ in _.into_iter()` is always redundant because the argument to a for loop must implement into iterator and into iterator is invoked on it, rather than implementing iterator.
    @1:25:00 I think the reason to do it that way is just "able to express more things." Since you want them to be able to support DSLs which have different rules, better to have this be two tokens rather than one.

  • @omarmagdy1075
    @omarmagdy1075 9 місяців тому +2

    Can't you like wrap everything in a mutex and yolo it though?

  • @markblacket8900
    @markblacket8900 9 місяців тому +1

    procedural macros look like rust's take on ocaml's ppxs

  • @gnarusg8708
    @gnarusg8708 9 місяців тому

    You blew my fucking mind with that COUNT.

  • @rafagd
    @rafagd 9 місяців тому

    58:10 - It's probably it's own type because it's a dynlib that links against the compiler itself.

  • @meanmole3212
    @meanmole3212 6 місяців тому

    *OH BOI*

  • @user-ge2vc3rl1n
    @user-ge2vc3rl1n 9 місяців тому

    the singing was hilarious

  • @GlobalYoung7
    @GlobalYoung7 9 місяців тому

    thank you 😊 🎉

  • @berndeckenfels
    @berndeckenfels 5 місяців тому

    2:00:00 I think rust will have to gurantee the order at least per single source file. (The only other method than using your macro list would be even worse - injection in the tree)

  • @berndeckenfels
    @berndeckenfels 5 місяців тому

    1:53:30 Maybe collecting the literal (instead of String) and inserting it again avoids quote handling,

  • @zeratax
    @zeratax 17 днів тому

    actually makes sense, that it isn't a proper ast, since you want to do stuff like compile time checked sql which obviously isn't in rust syntax. at least that's what i assume why? lol
    Edit: really wonder if there is a way to keep state in a proc macro that would be "rust approved" ^^

  • @ricardopieper11
    @ricardopieper11 9 місяців тому

    1:03:03 wouldn't it be just a syntax tree, but not an abstract one? It's somewhat parsed to do the grouping, but not fully made sense yet?

  • @awfultrash888
    @awfultrash888 6 місяців тому

    zozin i LUV U

  • @monad_tcp
    @monad_tcp 9 місяців тому

    I think I know precisely what's going to happen. (when I saw that .so)
    Rust is going to load that inside the compiler itself, the compiler is going to do dlopen

  • @CrazyLuke11
    @CrazyLuke11 9 місяців тому

    Hey, like your content.
    What Linux distro do you use?

  • @warko4
    @warko4 8 місяців тому

    Is this possible to build as statically linked binary?

  • @andrewyg18
    @andrewyg18 9 місяців тому

    Could you just use something a static flag to check is the command list is generated, and if so prohibit any more #[command] macro calls?

  • @anon_y_mousse
    @anon_y_mousse 9 місяців тому +1

    That was some gnarly code. The fact that the compiler allows for plugins like that is kind of horrific in a way. Hopefully they check any crates that get uploaded to the website, because that could make it a security hole for more than just the developers if they didn't.

  • @yaksher
    @yaksher 9 місяців тому

    Something to potentially look into for the future is the Serenity crate. It has a similar collection of macro attributes groups a bunch of commands into a single collection that can be viewed at run time (or maybe only at compile time, I briefly looked at the crate once and never looked in depth, but I'm pretty sure it does something similar).
    I don't know what it does, but I'm pretty sure it doesn't rely on the compiler happening to evaluate the macros in the order you want it do and it could be worth figuring out how it does that and doing a follow up. I think it uses nested macro invocations (i.e., the Rust compiler does multiple expansion passes until everything is expanded, if I understand correctly, and from a glance at what using it like (with an outer `#[group]` attribute of some kind), I suspect that Serenity relies on this to get the necessary ordering instead of relying on internal plug in state).

  • @el_carbonara
    @el_carbonara 8 місяців тому

    6:40 lol

  • @zsomborgyenge4359
    @zsomborgyenge4359 9 місяців тому +1

    1:09:35 it looks like a security vulnerability waiting to happen

    • @belst_
      @belst_ 9 місяців тому +1

      not really, it is at compile time. not runtime

    • @anon_y_mousse
      @anon_y_mousse 9 місяців тому

      @@belst_ Still insecure for the developer making use of it.

  • @berndeckenfels
    @berndeckenfels 5 місяців тому

    1:23:12 just put it in an input and display the Tokens for debugging

  • @Andrii-zc4dp
    @Andrii-zc4dp 9 місяців тому +3

    I think you can make this concept work! 1. Make a global vec commands, and then dont store state in the macro, just after every function generate an append call, with the structure. If you are scared of reallocations, you can initiate vec with_capacity, so the first allocation will fully contain everything

    • @Blubb3rbub
      @Blubb3rbub 9 місяців тому

      Where to generate the append call? Outside of any function body where the function is declared?

    • @stysner4580
      @stysner4580 9 місяців тому

      ​@@Blubb3rbubYou'd have to wrap all append calls into another function, then you have to call that in main. Something like init_commands();
      A bit sloppy though. You could do this concept with declarative macros instead so the order is guaranteed and you don't run into the parallel compilation issue.

    • @Blubb3rbub
      @Blubb3rbub 9 місяців тому

      @@stysner4580 But then you still need state in the macro to know which append calls to generate.

  • @stysner4580
    @stysner4580 9 місяців тому +2

    You could use declarative macros:
    commands_init!();
    def_command!("test", "print test", test_fn);
    fn test_fn() {}
    commands_finalize!();

  • @SuperPhilope
    @SuperPhilope 9 місяців тому

    wait until he finds out main() is actually not the entry point of the executable.

  • @kevinkkirimii
    @kevinkkirimii 9 місяців тому

    java annotations FTW

  • @bbq1423
    @bbq1423 9 місяців тому

    Hmm, parsing a literal to string and then back to literal along with unwrap.. Bet the rust devs are going to crazy about the error handling though

  • @andr6192
    @andr6192 9 місяців тому +1

    I solved the issue of having state in a proc macro by having the attribute macros not do anything, and then having the function macro load the entire file and parse it such that it could look for the items I had annotated with the attribute macro in a global way. I think that would really suck without the syn/quote/proc_macro2 crates though

  • @ariabk
    @ariabk 9 місяців тому

    ummm... just so you know, you can use String::into :p

  • @yds6268
    @yds6268 9 місяців тому +10

    First!
    And Rust ftw, of course

    • @elden8359
      @elden8359 9 місяців тому +1

      we are always last!

    • @flobuilds
      @flobuilds 9 місяців тому

      ​@@elden8359 fr man we really should start watching the streams but i always miss them

    • @RedstonekPL
      @RedstonekPL 9 місяців тому

      this man is using rust in 2023

    • @flobuilds
      @flobuilds 9 місяців тому

      @@RedstonekPL he's the choosen one

  • @Ansatz66
    @Ansatz66 9 місяців тому +2

    It is strange that Rust does not have a built-in way to get an actual AST. Obviously rustc is capable of parsing, so why not make that ability available to every macro?

    • @MadushanNishantha
      @MadushanNishantha 9 місяців тому +3

      It's because the code parsed by the compiler has to be syntactically correct. So just exposing the parser used by the compiler will not be that useful, they will have to expose APIs to modify the parser too. And I'm guessing they don't want to do that because it'll need to have an stable API. But I hope they will get around to exposing at least the parser generator they use so we don't have to use syn.

    • @RicardoSansores
      @RicardoSansores 9 місяців тому +3

      Its by design. This way you can implement crazy dsl's. If it is full AST libraries like leptos could not exist.

  • @sharithg9544
    @sharithg9544 9 місяців тому

    Why not use a LSP? Would save a lot of time on having to read documentation

    • @javierflores09
      @javierflores09 9 місяців тому +1

      I believe Tsoding doesn't have a powerful rig so streaming would bog down the speed of the LSP and a slow LSP is more of a setback than it is of help, besides that he is very much used to manually looking at the documentation, locally if possible because he'd often do offline coding (there are offline streams uploaded here) and prefers to approach coding that way.
      I believe there's value in doing that, since becoming too reliant on getting answers from the internet makes you lazy, instead of actually resolving problems you end up just relying on whatever the next stackoverflow post has to offer and at that point, you aren't much of a programmer anymore

    • @sharithg9544
      @sharithg9544 9 місяців тому

      If he indeed has a less pwerful rig, what you said makes sense (its crazy how much resources there LSP's take). However on the point of looking things up, I think for rust especially and how documentation inherently works (using commnets to generate docs), using a '.' on the function and getting all available functions is particularly useful, usually IDE's will either show you the docstring or you can click into the function and view the docstring + actual code. For example i want to know if string has uppercase function, i simply do "mystring". and get all available methods, vs spending 30s-1min searching that. Time is money, and it adds up. @@javierflores09

  • @Mrme-cn9je
    @Mrme-cn9je 9 місяців тому

    If you advise that Rust should be learnt as a programming language, Would you think of teaching Rust on here with a tutorial series?

  • @meanmole3212
    @meanmole3212 6 місяців тому

    *oof*

  • @ujjawalsinha8968
    @ujjawalsinha8968 9 місяців тому +1

    It would be cool to see this implemented in C

    • @anon_y_mousse
      @anon_y_mousse 9 місяців тому

      It'd be easier in C.

    • @monad_tcp
      @monad_tcp 9 місяців тому +1

      ​@@anon_y_mousse good luck trying to create a macro that acts like an annotation.
      I dare you .
      The rules of the game is that the main source of the function should be kept separated from the actual listing of the function pointers.
      Now go

    • @anon_y_mousse
      @anon_y_mousse 9 місяців тому +1

      @@monad_tcp I wouldn't need to use a macro to implement this in C, and he probably doesn't need to in Rust either. All I'd need to do is define a struct and assign everything to it just after the last function is defined.

    • @monad_tcp
      @monad_tcp 9 місяців тому

      @@anon_y_mousse but then its not statically compiled, but I know

    • @anon_y_mousse
      @anon_y_mousse 9 місяців тому

      @@monad_tcp I'm not sure what you meant to say there, but it would certainly be statically compiled.

  • @jppittman6067
    @jppittman6067 8 місяців тому

    Why not just create the vector of commands at the beginning in the proc_macro_atribute? Maybe using std::sync::Once? After that you can go about adding items to the vector in each subsequent invocation.

  • @brdevll
    @brdevll 9 місяців тому +1

    You should teach at university

  • @vellankiindeevar5530
    @vellankiindeevar5530 9 місяців тому

    man i wish i could these stuff

  • @Blubb3rbub
    @Blubb3rbub 9 місяців тому +1

    1:38:30 It would be great if you could do something like `match args_iter { [ Literal(first_lit), Punct(Comma), Literal(second_lit) ] => ... }`

  • @Service.NewerMind
    @Service.NewerMind 8 місяців тому

    main - 4.5M
    libcommand -6M
    Can your C do that? I don't think so.

  • @nage7447
    @nage7447 9 місяців тому

    it looks like a bad reflection )

  • @antdok9573
    @antdok9573 9 місяців тому

    Bro just discovered abstraction

  • @rebook0
    @rebook0 9 місяців тому +11

    Can you please go back to C? I thought this channel was about that.
    Rust is not production ready.
    It's community is toxic. Every Rust codebase is filled with unsafe blocks.. What is point of the language?

    • @Edw9n
      @Edw9n 9 місяців тому +26

      are u serious

    • @vestakk1550
      @vestakk1550 9 місяців тому +29

      let the guy code what he wants to code? This channel is just whatever he wants to code, when was it ever "just c"?

    • @weiSane
      @weiSane 9 місяців тому +16

      You gotta be trolling right ?

    • @apdo6028
      @apdo6028 9 місяців тому +1

      lmao

    • @cobbcoding
      @cobbcoding 9 місяців тому +22

      it was never just C, it's just recreational programming