|
I think my least favorite thing about refactoring so far has been trying to isolate parts of a chain of iterators. The result of a .map().filter().whatever() has a gnarly result type.
|
# ? Jan 3, 2017 19:47 |
|
|
# ? May 28, 2024 15:31 |
|
Asymmetrikon posted:I think my least favorite thing about refactoring so far has been trying to isolate parts of a chain of iterators. The result of a .map().filter().whatever() has a gnarly result type. Let the compiler help you! The following will give you a compiler error with what you need: code:
Workaday Wizard fucked around with this message at 21:02 on Jan 3, 2017 |
# ? Jan 3, 2017 20:57 |
|
Asymmetrikon posted:I think my least favorite thing about refactoring so far has been trying to isolate parts of a chain of iterators. The result of a .map().filter().whatever() has a gnarly result type. There's also inspect: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.inspect
|
# ? Jan 3, 2017 21:07 |
|
Filter is parameterized over a P: FnMut, which the compiler just represents as an anonymous closure, though. How do you express that kind of type concretely?
|
# ? Jan 3, 2017 21:10 |
|
Asymmetrikon posted:I think my least favorite thing about refactoring so far has been trying to isolate parts of a chain of iterators. The result of a .map().filter().whatever() has a gnarly result type. Will 'impl trait' help for this case?
|
# ? Jan 3, 2017 22:22 |
|
Asymmetrikon posted:Filter is parameterized over a P: FnMut, which the compiler just represents as an anonymous closure, though. How do you express that kind of type concretely?
|
# ? Jan 3, 2017 22:49 |
|
gonadic io posted:Will 'impl trait' help for this case? Yeah. Is that out of nightly yet?
|
# ? Jan 3, 2017 23:56 |
|
Asymmetrikon posted:Yeah. Is that out of nightly yet? Nope! And with good reason, there's still plenty of edge cases and bugs that are falling out. The main functionality works fine though. Dehumanise yourself and face to nightly. Or just make extensive use of type inference, either adding no explicit type sig, or use lots of underscores in it.
|
# ? Jan 5, 2017 12:20 |
|
So, I'm at a point with rust where I am comfortable with all of the syntax, but am still struggling with borrowing, lifetimes and references. This tutorial is tremendously helpful: http://cglab.ca/~abeinges/blah/too-many-lists/book/README.html It walks you through building a number of linked lists, gradually increasing in complexity. It specifically addresses things like Box, Rc, Arc, mem::Replace, &mut, *mut, *const, Copy, and how you'll need to use those things to build a simple data structure in Rust. It's really helped me. The format is a little annoying (probably too jokey for most people's taste) but the content is solid. DONT THREAD ON ME fucked around with this message at 19:01 on Jan 7, 2017 |
# ? Jan 7, 2017 18:59 |
|
Is there such a thing as a function composition or pipelining operator in Rust? I'm also interested in a macro to combine `fn` and `match` since all of my functions match anyway. Yes I come from Haskell and be glad you don't work with me.
|
# ? Jan 14, 2017 19:56 |
|
xtal posted:Is there such a thing as a function composition or pipelining operator in Rust? Rust is, to its credit, not a great language for point-free shenanigans. xtal posted:I'm also interested in a macro to combine `fn` and `match` since all of my functions match anyway. Yes I come from Haskell and be glad you don't work with me.
|
# ? Jan 23, 2017 11:33 |
|
On the plus side I got rust's cross-compiling intrinsics working. On the downside now I have this in my code:Rust code:
gonadic io fucked around with this message at 22:30 on Jan 28, 2017 |
# ? Jan 28, 2017 22:24 |
|
gonadic io posted:On the plus side I got rust's cross-compiling intrinsics working. On the downside now I have this in my code: &T and &mut T references will automatically coerce into *const T and *mut T pointers, respectively, so the "as (*const|*mut) usize" isn't necessary for the copy/write calls. Unfortunately, I don't know any shortcuts for getting pointer difference, though.
|
# ? Jan 29, 2017 06:16 |
|
gonadic io posted:On the plus side I got rust's cross-compiling intrinsics working. On the downside now I have this in my code: If those are symbols coming from your linker script, they shouldn't have the type "usize", by the way. "()" is way more appropriate, because there's no data backing them. In C or C++ you normally declare them like this: code:
This is to prevent you from accidentally trying to read or write a value (the only thing you can do to a variable of an incomplete type is take its address).
|
# ? Jan 29, 2017 06:37 |
|
ShoulderDaemon posted:If those are symbols coming from your linker script, they shouldn't have the type "usize", by the way. "()" is way more appropriate, because there's no data backing them. In the C code I'm looking at they're all defined "extern unsigned int" but I suppose that's just bad practice. I figured out a way to take advantage of the auto-coerce: code:
|
# ? Jan 29, 2017 09:23 |
|
"static mut __etext: ();" triggers code:
For now honestly I think that I'm just going to disable that warning for those definitions as, unlike other sizes of tuples, the memory layout of () is guaranteed. gonadic io fucked around with this message at 10:58 on Jan 29, 2017 |
# ? Jan 29, 2017 10:52 |
|
Oh cool! A Rust thread! I came over to TCoC to ask a question but this seems like the best place. I've been trying to get into programming in Rust. I like the idea behind it but grasping the weirdness has slowed me down. Beside the point for this question. What I'm after is an IDE, or even a decent text editor with Rust support. I really don't feel like going the vim or emacs route. Atom seems okay but it has a few things that bug me. * It feels clunky and ponderous. It shouldn't be like that! * It's a royal PITA to build, or at least get the dependencies set up for. * It seems to have that lovely blurry anti aliasing going on that makes me loathe Ubuntu OOTB. You know what I mean. Adding to those points I want to use it on an old netbook, a Raspberry Pi running Raspbian and an Orange Pi PC running Armbian. It might seem like a weird choice but I'm ADD as all hell and running on a more resource constrained system helps stop me from goofing off. Plus power has gotten so goddamn expensive I'd rather be burning less watts than a PC if I can. So what's out there that supports Rust syntax that isn't a poster child for bloat? Honestly if Rust had been ported to RISC OS I'd use it on that just so I could use Zap or StrongEd. Really nice text editors.
|
# ? Jan 31, 2017 22:28 |
|
I use Visual Studio Code and I like it a lot. It has support for auto-builds, syntax highlighting, error underlining, name lookup, autocomplete (some amount anyway), formatting code and stuff. No semantic rename yet though sadly. https://github.com/saviorisdead/RustyCode e: if you want something leaner and are willing to put up with 1) nagging to pay, and 2) much worse rust support (but still syntax highlighting and goto definition) then there's always sublime gonadic io fucked around with this message at 23:14 on Jan 31, 2017 |
# ? Jan 31, 2017 22:38 |
|
intellij-rust is a much more straightforward ide that doesn't require anything extra. makes development real easy.
|
# ? Jan 31, 2017 23:36 |
|
Thanks for the suggestions. Sublime seems pretty good but the closed source nature is problematic because I can't run it on what I want to. So IntelliJ rust is far enough along to be usable? Been meaning to try out VS core. Setting up toolchains in Windows is kind of obnoxious so I haven't. IIRC it has a Linux version too, right?
|
# ? Feb 1, 2017 06:24 |
|
General_Failure posted:So IntelliJ rust is far enough along to be usable? It's good enough for me, a terrible programmer. The most important feature for me, quick navigation between files and definitions, works really well even with stuff in the standard library. I also find the code outline feature really helpful especially when reading third party code with many trait implementations. You should try it anyway. It won't take much to set up (get intellij, install plugin, point plugin to rust toolkit, voila) and it works with regular old Cargo projects.
|
# ? Feb 1, 2017 11:35 |
|
Shinku ABOOKEN posted:It's good enough for me, a terrible programmer. Nice. Cargo projects are actually one of the things that made me want to learn Rust. Leagues ahead of makefiles. On par with a lot of other languages. Just popped in to say that i got VS Code to build and run on the Pi 3. It seems to have a lot in common with Atom. Is there common code? Haven't worked out how to add plugins yet. It seems to support Rust syntax. What else does it need? Most of my ham fisted fumbling trying to get Atom to compile came in handy because I'd almost got it right enough to build VS Code. Looks nice. I've been cursing the slow disappearance of decent syntax highlighting editors in Linux. I'm going to have a crack at IntelliJ Rust too. I've used IntelliJ for Java before. it was okay. I have a violent hatred for Eclipse, so when a new player came about I had another crack at it. Admittedly most of my Java experience was writing programs in vi on a remote Solaris server. My later attempts using Eclipse always ended badly because I got incredibly pissed off at pretty much every aspect of the UI design. It seems weird but Rust reminds me of Pascal in a way. A positive way. It's a shame it's a dying language these days. e: Google answered my question. VS Code is based off Atom. General_Failure fucked around with this message at 13:24 on Feb 1, 2017 |
# ? Feb 1, 2017 13:21 |
|
I did my first thing (a RPN parser/calculator) using Rust and would appreciate any pointers. https://gist.github.com/pollyzoid/f0a392949d6da38d2aa957d65c7d6587 I have no idea what I'm doing. First version was just a bunch of nested matches, which I rewrote into a recursive function by accessing the Vec<Token> directly with index. Then I rejiggered that into using a reversed iterator instead. It's shorter at least, but I don't know if it's more readable. Maybe I should've just kept the iterative + stack approach.
|
# ? Feb 22, 2017 21:52 |
|
Pollyzoid posted:I did my first thing (a RPN parser/calculator) using Rust and would appreciate any pointers. I know I personally prefer an iterative+stack approach, and even started writing a version before realizing that's what your second link was. Though honestly, with the refactoring you did when you did the reverse-iterator method, converting it back to an iterative method made it a little nicer. Here's the version I came up with. (I even put it on the i32 playground, which has the top crates available, including lazy_static.) Here are some tips that cleaned up the code a little:
I will admit that's still kinda deep nesting, though. You can take out one level by factoring the single-token processing into another function, but at that point that's refactoring for purely aesthetic reasons.
|
# ? Feb 23, 2017 02:56 |
|
I'm a complete newcomer to Rust, and I just ran through the matching game, and I have a question about some code:code:
Edit: After reading a little more of the book, is it that this is binding guess to a pattern? It's still confusing to me if anyone could go into a little more detail and describe what's happening here. mrbass21 fucked around with this message at 10:42 on Feb 27, 2017 |
# ? Feb 27, 2017 09:49 |
|
Yeah, the assignment never happens. It's just that a lot of things in Rust are expressions, so you're more flexibly with what goes where than in C or whatever. You can also write stupid poo poo like return (return (return (return continue))) because continue and return are just divergent expressions of type !. I don't think patterns are relevant at this point. It's like an .unwrap_or_else(|| continue) if you could magically use continue across closures. You can also write stuff like this: code:
|
# ? Feb 27, 2017 12:26 |
|
Why does this code:code:
code:
I also discovered that "if let" keeps borrows active through the else for some reason, but in other cases, adding the return and moving the "else if" into an "if" was a workaround.
|
# ? Mar 2, 2017 05:51 |
|
Ideally you just use the Entry based API for you lookup-or-insert thing, but I guess they're still arguing about how to design the API that doesn't require an up-front copy of the key. Lifetimes extending past where you'd except them to is a thing they've been posting about for ages, Niko Matsakis has been blogging about it recently so maybe things are happening there, search for non-lexical lifetimes. The if-let thing might be a bug that's fixed in nightly or something.
|
# ? Mar 2, 2017 11:28 |
|
IIRC the if let thing is because it's sugar for match.
|
# ? Mar 2, 2017 12:50 |
|
Shinku ABOOKEN posted:IIRC the if let thing is because it's sugar for match. This, basically. An "if let" renders the same under the hood as a "match" with one real pattern and one _ pattern. I might toss this snippet into IRC later today and see if this is a bug. The "if let" there shouldn't extend the borrow past that one block there, even with purely-lexical borrows. For the moment, I got it to work by changing the condition up: code:
EDIT: According to IRC, this is, in fact, a problem of lexical lifetimes, just one that defies initial understanding. The article linked in chat describes it better, but basically because the "if let" creates a borrow that extends outside the function, it's still treated as borrowed for the rest of the function. The solution suggested in the article (pre-non-lexical-lifetimes) is just like the one I put here: Make the initial branch not create a borrow, so that the rest of the function doesn't treat the map as being borrowed. QuietMisdreavus fucked around with this message at 19:23 on Mar 2, 2017 |
# ? Mar 2, 2017 15:11 |
|
https://github.com/rust-lang/rfcs/pull/1769 sometimes rust just feels like complete bullshit.
|
# ? Mar 2, 2017 23:34 |
|
You know what the tech community is really missing out on? Bureaucracy
|
# ? Mar 2, 2017 23:39 |
|
xtal posted:You know what the tech community is really missing out on? Bureaucracy I don't see how having a documented change process is bad vv Or are you referring to something specific?
|
# ? Mar 3, 2017 00:42 |
|
icesoldier posted:EDIT: According to IRC, this is, in fact, a problem of lexical lifetimes, just one that defies initial understanding. The article linked in chat describes it better, but basically because the "if let" creates a borrow that extends outside the function, it's still treated as borrowed for the rest of the function. The solution suggested in the article (pre-non-lexical-lifetimes) is just like the one I put here: Make the initial branch not create a borrow, so that the rest of the function doesn't treat the map as being borrowed. Thanks! In my case, cloning and returning by value is better than doing extra lookups, since I'd always need to do the clone later anyway.
|
# ? Mar 3, 2017 01:41 |
|
Hmm, I'm running into a problem that isn't complex in itself but I'm sure that my solution is really unidiomatic. I'm continuing with my rust-for-arduino project and my RTC alarm enum looks like thiscode:
Since Rust enums aren't fully-fledged objects that can have static members for each variant like Scala, and if-let blocks don't allow multiple patterns, and I don't really want to write and implement a HasSeconds/HasMinutes trait for this single method I went with this approach (which I don't really like): code:
Full snippet is here: https://gist.github.com/djmcgill/91556f58d1aedff2adc7428a6443aac2 Full code is here: https://github.com/djmcgill/to-the-moon/blob/master/src/component/rtc/mod.rs#L142
|
# ? Mar 9, 2017 15:03 |
|
If this is literally the only place the Alarm enum is being used this might be overkill, but you can implement methods on enums. I'd try implementing a kind of fn seconds(&self) -> Option<u8> that returns Some(second) if available and None if not, just to "hide away" the cumbersome pattern. Plus, you could double that same seconds() call as an OFF detector, since OFF is the only variant that doesn't have a seconds field. As-is, I wouldn't necessarily call that bad, just unfortunate.
|
# ? Mar 9, 2017 19:12 |
|
I was going to make the same suggestion, except with a macro https://gist.github.com/anonymous/81b4b2dde02467feb13bc8c2de671ded
|
# ? Mar 9, 2017 19:35 |
|
That is much better thanks, although making a new file and enum for every method is going to bloat my code somewhat... I went with the explicit approach over the recursive macro for maintenance /ease of understanding purposes. Next question: I need to be able to attach a callback to the alarm interrupt. The way this is done in the C is to have a global mutable function pointer. When the alarm goes off if the pointer isn't null then execute the function. I think I can use a static mut AtomicPtr<&'static Fn() > for this. I can't use Mutex or lazy_static because they both depend on std. Amy better ways present themselves? e: hmm, I could at least make the pointer private and the callback a parameter to the set_alarm method. gonadic io fucked around with this message at 12:45 on Mar 10, 2017 |
# ? Mar 10, 2017 12:26 |
|
I'd thought the static wouldn't need to be mut because all the loads/stores/swaps/etc only need a shared reference, but apparently there's no const AtomicPtr like there is for the other atomic types, so you'd need to initialize it somehow. Either way that probably works, though the type inside could probably be better served as a fn() or unsafe fn() if you're doing FFI and need the function to be blanket unsafe or whatever. Note the lowercase fn, that's directly a function pointer instead of one of the closure traits. EDIT: Also, I totally didn't realize the atomic types were in core, huh. QuietMisdreavus fucked around with this message at 03:23 on Mar 11, 2017 |
# ? Mar 11, 2017 03:21 |
|
|
# ? May 28, 2024 15:31 |
|
Is there a way to generate an identifier inside a macro? I have a macro that creates a struct that implements a trait (similar to closure structs implementing Fn) code:
code:
Full code is here. gonadic io fucked around with this message at 16:30 on Mar 22, 2017 |
# ? Mar 22, 2017 16:16 |