Tumgik
#i just wanted to come in and help clearify what I meant better
pretend-writer · 5 years
Text
Hello Goodbye (Klaus Hargreeves x platonic!reader)
Tumblr media
Requested
Summary: Klaus comes by in the middle of the night to Y/N’s place for comfort. 
Title Reference: Hello Goodbye x The Beatles
Word Count: 452 words
Warning: panic, mention of drugs
✤  ·  ✤  ·  ✤  ·  ✤  ·  ✤
A loud knock startled me as the noise echoed through my apartment. It was two in the morning and I didn't know who can possibly be visiting me at this time of night.
Quickly getting out of bed, I put my pants on as I walked toward my front door. I looked through the peep hole to see who was there but I couldn't see anyone.
Opening the door anyway just to make sure, revealed Klaus sitting on the ground with hands on his face.
'Klaus.' I blurted as I helped him stand up. 'Are yo-.'
'I'm sorry, Y/N. I just didn't know where to go and I'm spiraling. I don't know what to do.'
Tiptoeing to reach his height, I wrapped my arms around him and gave him a hug. 'Shh, don't worry. You can always come to me.'
His shortness of breath and his shaky hands made me worry for him even more. It's been a couple of weeks since I've seen him and checked up on my friend.
Inviting him into my apartment, I sat him on the couch. 'Do you want anything? Water, Tea?'
'No, just sit by me. Please.' Klaus said as his voice cracked.
I reached my hand for his back and rubbed it slowly, trying to calm him down. 'Do you want to talk about it?'
'I've be-' He clenched his fist, trying to fight his demons that were in his head. 'I stopped using and now I-I see them everywhere.'
Klaus didn't clearify in his sentence but I knew exactly what he meant. After using drugs to suppress his power to see the dead all these years, he was reliving his old nightmares again.
'You're okay Klaus, I'm here with you.' I scooted closer to him and held his hand. 'You're safe with me.'
He closed his eyes and breathed, squeezing my hand for comfort. "I'm okay, I'm okay", he repeated to himself over and over again.
'How do you feel?' I whispered to him.
'Y/N, I feel much better. Thank you.' Klaus opened his eyes and looked at me with a small smile on his face.
Slowly I stood up, tilting my head toward my room to signal him. 'Now come on, let's go lay down on my bed.'
'No, it's fine. I can go back to my place.' He stood up from the couch.
'I'm not letting you go, Klaus.' I smiled, 'Just in case you need me again, I'll be right next to you this time.'
He smiled back and hugged me tightly, 'I appreciate you so much, thank you for being a good friend.'
'Always.' I wrapped my arms around, hugging him back. 'Now for some cuddle time.'
282 notes · View notes
cainite-bite · 4 years
Text
nemiga-sims replied to your post: the real reason why RE1 isn’t getting remade like...
well hello there, resident evil 1 already have remake Resident Evil Remastered (2002).Never heard?
I have, and I’ve owned that too. I more meant remaking it in the current style that 2 and now 3 are currently being made in (along with dmc5) with the much more realistic look and basing the looks more closely after the models they’re hiring for likeness
0 notes
matthewjosephtaylor · 5 years
Text
Thoughts on Rustlang
My raw first impressions as I read the Rust Programming Language Book https://doc.rust-lang.org/book/
I reserve...no I demand the right to change my mind later about everything below (In fact, I'll be disappointed if I don't).
These are my unfiltered musings meant for historical and entertainment purposes only (Nothing more amusing in life, than seeing how 'wrong' one's past self was) :)
Cargo
Seems to be the law of the universe that every language has its own build and dependency management system
So far seems fairly clean/simple and straight-forward
Unfortunate that creating new project also includes SCM (let one thing be responsible for one thing not 'all the things')
since I like git it is handy, but feels a bit too opinionated and bloaty
semver
will be glad when semver dies as an idea of how to link dependencies
would have preferred identifier based on content (like a hash of the source) with option to use monotonic identifier like date for convenience
lock file should absolutely be based on content-hash not a label like semver (disappointed)
Rustlang Basics
variable shadowing (dangerous?)
dangerously useful feature
could see this being labeled as 'considered harmful'
immediate impression is that the danger > usefulness but time will tell, maybe the usefulness outweighs
clear integer types (awesome)
u32 is perfect name compared to something like 'int' or 'long', etc in other languages where the important size of the integer is obscure
usize is a bit of an odd/ugly name for architecture specific size. Something like iarch would prolly have been better IMHO
WTF different behavior on debug/release mode for overflow?
Broken design
Is this being fixed/worked on?!?!?!?
why the space in specifying type like 'foo: bool'?
seems that 'bool:foo' would have been a cleaner more easily cut/pastable and easier to follow syntax design (Rust syntax seems backwards and overly expansive)
built-in tuple type (cool)
possibly 'dangerously useful'...but for the moment all I see is the sexy and want to dance with this potential danger ;)
destructuring
return multiple auto destructuring?
arrays don't auto-expand/shrink
fair trade it seems to me (for the most part data-structures should be immutable anyway).
let a: [i32; 5] is really ugly syntax
would prefer let i32:a[5] as ideal or let a: i32[5] to remain consistent with variable type specification poor syntax design choice
feels like the poor syntax of variable typing lead to the train-wreck of array-typing
let a = [3; 5]; OMFG this is now getting ridiculous
Bad design leads to worse design leads to truly evil design
first 'thing' before the semicolon is either a type or a value...wonder how many arrays have been created with the value 32 when the the type i32 was intended?
zero is the only interesting value one would want to 'autofill' an array with, and would be the expected default. This entire syntax 'feature' should go away.
At this moment going to call the variable typing syntax 'broken'. Too late to change. This will be one of the 'broken' parts of Rust that everyone has to deal with via best-practices and lint-checking. Unfortunate but here we are.
Important lesson to learn: Syntax matters for a language design. If the syntax is bad there is really no way to recover until the next language.
Nice that runtime array out-of-bounds checking is done (honestly how could it be otherwise in the modern era?)
Would be better if compiler/checker was a bit smarter and able to compile-time check OOB errors when it has the info to do so
possibly there is already a linter/checker that does this? Is there more than one?
clear distinction made between expressions and statements
difference as defined is that expressions return values and statements don't.
{} is an expression that appears to evaluate to the implicit returned value of the last expression inside of it
does that understanding hold up?
is there a return keyword? or is this how returning works?
WTF expressions are defined syntactically by missing semicolons?
Expressions do not include ending semicolons. If you add a semicolon to the end of an expression, you turn it into a statement, which will then not return a value
Immediate impression is that this is the most dodgy error-prone way of 'returning' I've every come across. Maybe it makes sense in context, and there are other safeguards that make this not as crazy as it appears on first blush...but I'm going to demand some explanation...
return is a keyword that docs say work as expected but also the return value of the function is synonymous with the value of the final expression in the block of the body of a function.
using -> to specify return type seems a bit cute for the sake of cuteness and 'being different' (extra syntax for no real purpose)
Not getting the purpose of turning an expression into a statement by adding a semicolon. At least not yet.
I'm presently thinking that the 'missing semicolon' is the way the language designers chose to be able to differentiate an expression that is meant to be evaluated and assigned to a variable within a function body, from an expression that is meant to be returned. In other words the 'missing semicolon' is effectively just a 'cute trick' to make the language look a bit different by not having a return before the last expression.
First impression is that this 'odd' syntax decision perhaps won't lead errors since the function itself should have a return type defined in the method signature. So if one accidentally puts in the semicolon like one would do for every other fucking usage of this expression (preloading my anger here in anticipation of being tricked by this constantly)) it won't cause a runtime error because the compiler should catch what I suspect is a very likely and common mistake.
They should just have mandated a return statement at the end of a function that returns a value to make things clear. Fear that the missing syntax character as replacement for a keyword is just 'being different' for no good reason that will lead to errors, where clarity of syntax would have been a touch more verbose but consistent.
I do appreciate that they wanted to have a language where the last expression evaluated to the return, and wanted to avoid the pitfall of language-users accidentally returning a thing they didn't mean to. Feel that is a common mistake in languages with 'implicit return' and the language-designers were wise to differentiate 'expressions meant for return' with 'expressions meant for assignment' but that 'missing semicolon' is an un-intuitive/un-obvious way of doing that. If they wanted to be cute I would have suggested they use -> as their return keyword and 'skipped the syntax garbage' in the method signature (like all other c-like languages have managed to avoid doing by having the return type be the thing to the left of the function-name)
First time I've run across 'arms' and 'arm' to mean something like 'execution path'. Short and simple, I think I kind of like it. A thing that needed a name. Was this innovative of Rust or already existing name I was unaware of?
No parens around conditions for if statements...hmmm....
quick check says they are allowed but give compile warning as unnecessary.
might be OK with leaving off (maybe)
Absolutely NOT OK with the compiler warning (parens in conditionals usually lead to clearifying intent of code)
eh, only seems to warn if the parens are at the top level so will back off a bit but still disagree with compiler warnings for extra-verbose syntax on general principle
quick code check on returning from conditional leads to the conclusion that one can't return from inside a condition
initial impression is that I like this behavior quite a bit.
the error message of 'unexpected token' is crap (going to be a common thing people are going to attempt to do, would be better to have compiler print more helpful message).
book gives hint to a 'match' keyword while explaining else if (excited/hopeful...please Knuth let match be what I want it to be)
Like that if is an expression. Goodbye elvis.
Randomly in playing around I've noticed that string concatenation with + isn't a thing in Rust. Hopefully there is a replacement syntax that allows string concatenation.
feel that sprintf style strings are error-prone
Like for in but don't see an equiv to for(i=0;i<10;i++). That is a really handy for-loop construct.
Range might fill 80% need for 'real' for-loop but isn't a 100% replacement
Possible that the need for this style goes away with other constructs/usage paradigms in Rust
I note that as I've gotten more into functional programming this 'old' style of for-loop is generally nicely replaced with a Range.
If all else fails hopefully creating some form of 'iterable' is easy, and perhaps that is the 'right and true' answer in all cases anyway :)
perhaps 'old school' for-loop construct is just 'dangerous by design', that seems likely given the mutated counter.
Rustlang Ownership
The string example where s1 = s2 and then s1 is referenced later which creates a compile error
WTF
Not how I expected that to behave at all, which I suppose is the point of this chapter.
I suppose intuitively I was assuming some sort of fancy 'reference counting' or that s1 and s2 would share a reference to the same underlying 'object'.
Assignment instead seems to imply 'transfer of ownership'.
First blush the fact that s1 is still 'in scope' seems to imply some sort of language syntax design problem since s1 clearly should no longer be in scope, by how the runtime expects things to behave, but is in scope as a practical matter, and how the language-user expects things to behave.
'We changed the rules of scope pray we do not change them any further' seems like an evil trick to play on the language-user.
the compile error of 'no Copy trait' is better than blowing up at runtime, and I appreciate the safety, but the real problem is that I as a language-user would not expect s1 to somehow 'internally' go out of scope
Better it seems to me that variable 'renaming' (variable to variable assignment (no expression)) be made illegal.
This also seems to imply that variables are sort of 'one time use' sort of things. Quite a different way of looking at the world. Possible that c-like syntax is just not a good fit since language-user's expect scope to behave in a way that it clearly doesn't.
Thinking that the runtime designers just made a bad choice in how to interpret the semantics of the language (hinted by the fact that docs imply that x = y will copy data from y to x instead of just let x and y share pointer to same location in memory). Seems like they want variables to mean something like 'location in memory' where really the language-user doesn't care unless the location is mutable which should be the rare case. Thinking the runtime designers hadn't quite grokked the power of immutable data structures.
Copy but no Share?
Seems that Copy 'trait' is the escape hatch to distinguish stack-level from heap-level allocation.
First impression is that all this 'Copying' is wasteful and unneeded (hoping that the Copying is a lie and that 'under the hood' immutables really do share)
All-in-all feels like at the very least the distinction between a Copy-able variable and a Drop-able variable should be visible via language syntax.
clet x = 5 and dlet y = String::from("foo")
How do I know as a language-user what is Copy and what is Drop without reading all lines of code that go into the creation of the types???
References
Well duh...why isn't this the default behavior? Pass by reference isn't a new/unexpected thing in the universe. Feels like the default being pass-by-copy is a bit old-school.
Getting feeling this is the tension between systems and application programming languages. Systems expects mutable and so wants to copy stuff all over the place to prevent the hell mutability brings, Application should in the modern era expect immutable and so expects pass-by-reference to be safe.
Thinking there is a lot of pain here that could be solved by just assuming immutable, and then treating mutable as the rare-its-ok-to-have-wierd-rules-wear-special-gloves situation
Feels like syntax around references are sort of unnecessary if one assumes pass-by-reference. Languages-users never should need the actual pointer to the memory location which was why c-like & exists. From the language-user's perspective I can't think of a legit reason why there would need to be a reason to distinguish between 'the value' and 'the reference to the value'. Just assume that the variable one has access to is a reference and move on with life, let the runtime deal with dereferencing. If it is faster for there to be a copy (simple integer value where the pointer takes just as much room as the value) let the runtime deal with that decision transparently (I don't give a !@#% what the assembly code looks like as a high-level language user, just make it do the right thing so that my assumptions of behavior are respected).
all-in-all this feels like too much ceremony for no valid reason. Just remove & as a thing. No reason for that thing to exist in a language without pointer arithmetic (oh please let there be no pointer arithmetic in Rust...).
Slices
Neat idea and useful concept
First impression is that this should just be the default mechanism for dealing with list-like data-structures. (why have a separate thing when one thing can mean both and is more powerful?)
Feels like best-practice would just to be use slices and forget the other non-slice variants exist.
Rustlang Data Structures
Structs
Goodbye sexy tuples. I'll probably still flirt with you, but you will likely be a quick-n-dirty when I'm too lazy, not for 'production' use.
interesting constructor syntax. All-in-all I think I like it on first impression.
like the 'field init shorthand syntax' alternate
love the 'other instance shorthand syntax' alternate
Tuple Structs
Dangerously useful.
Language would probably be better served without this construct, to 'gently direct' users into explicit-naming vs ordering-as-naming.
Sexy but no substance
Hopefully destructuring of Structs works as one would expect with the definition order being the value-order
Oddity just noticed playing around: String literal can't be used in place of String type? String::from("foo") != "foo". What is the type of a string literal if not String?
First introduction of annotations
@ would have been more natural than # since it is more commonly used (different just to be different again?)
Methods
'self' instead of 'this' (I can live with 'self', but hopefully there is a reasoned argument why the non-c-family name was used)
Seems like the first argument should be assumed to be &self and drop it from method signature (remove the tedium)
Feels like it wasn't done this way just to give the option of pass-by-copy, which is just sort of a bad-idea anyway (shouldn't be default, OK if hard/weird/impossible syntax for that option) in most cases.
I've been willfully ignoring the ugly that is &mut as a syntax 'keyword/symbol'. Feels like that wants to be something more like &! (lesson: symbols and keywords don't really want to be mixed together)
Enums
Do what they say on the tin (work as expected).
Like that each enum can have specific values
Like the 'helper' methods
Love the allowing of comma on last value (consistent syntax ftw)
Match
Meh on the 'optional' curly brackets.
agree it is 'noisy' syntax
that 'noise' also adds clarity
since all cases must be accounted for I think I'm more willing to trust that the additional clarity likely isn't needed
Like the 'value binding'
Up in the air on the syntax. Feels like argument-order is a bad thing to rely on.
Good that Monads like Option are 'pattern matchable'. Will be interesting to see how deep this goes(is Option just a simple enum, or something more powerful happening?).
like _ as the 'placeholder' variable name.
like () as the 'unit value' name.
not sure how to get the value of the 'wildcard' match?
like 'if let' I think
docs are kind of crap on how to use this....testing.....
Syntax seems backwards with the assignment being on the right (wtf?)
Absolutely hate the = now that I see that it means something closer to 'associate with' for if let
let foo = if let Coin::Penny = coin {... reads let foo contain the value of the result of matching Penny on the coin variable containing a Coin enum
Like the idea hate the syntax
better would be: let foo = coin if Coin::Penny {...
Starting to feel that for some reason the Rust developers are intentionally attempting to create confusing syntax on purpose (just not sure why yet)
Packages, Crates, Modules
initial impression after reading the summary: Lots of new keywords. Hopefully they are used for good purposes...but I'm reserving judgement based on some of the poor naming/syntax choices I've seen so far.
src/bin is an ugly way to to distinguish multiple 'binaries' (think they mean executables).
would prefer something like src/mains and src/lib
feel 'binary' is a bad name for a 'command line executable' and 'executable' would have been better
Modules
Like the nesting
'crate' feels a bit odd for naming choice of 'root' module. Feel name like 'root' would likely serve better
Uneasy about the 'placeholder' functions inside of module definitions.
Burdensome typing
Serves a useful purpose if modules are 'closed'
Serves a useful purpose if modules are more 'interface' in nature
first impression pathing: Like the idea and love the attention to this important detail
liking 'crate' to mean 'root module' less and less as I see the name used in the pathing....
relative pathing seems like a 'dangerously useful' idea.
Feeling that relative pathing is less useful if IDE takes on burden of refactoring...liking relative pathing less...
Like the fact there is a simple private/public (finer grained is generally less useful IMHO)
Like private as default
Like child sees parent, and children are hidden from parent
Feeling more and more as I see documentation-reasons why relative paths are used that it is always in the context of moving code around
Don't like the idea of reducing the 'strength' of module paths if it is only useful for refactoring purposes
Feels a bit like the language-designers added an unneeded/dangerous syntax element strictly to aid less-powerful code-editors
Like as as a renaming syntax
Like module file names being defined by module names
Like module hierarchies being defined by directory structure
Rustlang Collections
Happy that have, Disappointed in how the Book presents
Looking based off of the Documentation looks like better would have been to start from concepts like sequence
RE: vec![1,2,3] not sure I like a macro for Vector construction
Perhaps just a getting used to thing but construction feels like a thing I would expect Type-constructor to be able to do.
The bang I want to mean that the macro is creating a mutable thing (hopefully that is the case)
Playing around it appears that vec[1,2,3] isn't legal
would hope to construct an immutable vector
perhaps a non-sensical thing to want?
Hopefully there is an immutable sequence that takes care of what I want that to be
further evidence of poor choice on references.
Elements are typed as &i32 instead of i32
Get that that needs to be a reference, disagree that there should be a 'language-syntax' level distinction (should be a detail compiler takes care of)
unfortunate that 'panic' is an expected situation user should expect to get into
Feel using &v[100] is 'considered dangerous' and suspect shouldn't be part of language
Prefer v[100] to be an alternate syntax for v.get(100) (and then maybe just drop the more verbose form)
Once again poor language-design choices have lead to normal usage patterns being taxed with the 'uglier' form of syntax
Like the 'trick' of using enum-values for creating a 'closed-universe of types'
That is a really good trick the more I think about it.
As I think on this some more: that 'trick' I feel was worth the price of admission to learning the language and is an 'aha'.
Going to take that with me. That is a deeply good idea.
Strings
The fact that "initial contents".to_string(); is a reasonable thing to type I think speaks for itself regarding poor choices in the language.
First google on Rust String concatenation leads to an involved discussion on various ways of doing what should be a simple thing like "hello" + "world"
Going to add 'String concatenation' to my language-evaluation litmus tests
If a language can't handle the basics with grace then that is a red-flag because it is going to kill adoption-rates which is death for any language
A String is a wrapper over a Vec<u8> WTF?
How in the @#%@#% is that a reasonable way to look at Strings in the modern era?
String wants to be something like Vec<CodePoint>
Understand that in 1970 'C' can expect a String to comprised of 8-byte 'characters' but that is totally unacceptable today
Perhaps the entire built-in 'String' is just DOA?
Do people actually use this garbage in practice?
Feel there must certainly be one or (unfortunately) more libraries that people must use to handle strings in Rust if this is the built-in
&hello[0] is illegal to 'avoid confusion' but in the same breath &hello[0..1] is legal
I don't know what to say....that is just horrible
Like the attempt at guarding users from evil and just plain wrong abstraction, but the guarding is incomplete (and just proves the point that String is just broken in its current state)
I could almost accept this if this language 'evolved' from an era when ASCII was a thing. But this language started in 2010. There is just no excuse.
Thinking that current String type should be named something like C_String_WRAPPER and only be used in cases where one is interfacing with an external c-like library (and intentionally named ugly to signal the pain and torture and danger found within)
HashMaps
Hash maps also have less support from the standard library; there’s no built-in macro to construct them, for example
appears that Rust wants to treat Type construction as an 'outside' 'macro' responsibility
Don't think I agree with this philosophy
Feels like creators of Types should also be expected to be responsible for providing type-constructors
Cool with having type-construction 'open' (allowing more) but feel that there should be a basic set of constructors that cover most cases as part of the 'contract' of creating a Type.
HashMap<_, _>
Not such a fan of using _ to mean 'any' here. (feel it is fine for variables NOT for types)
It's OK and there is a consistency argument (a weak one IMHO (any != ignore))
like the more 'in your face' 'you are probably doing it wrong, are you sure?' ?
No 'literal' constructors for either Map or Sequence that I've run across. Hopefully they exist...but starting to worry...
Rustlang Errors
Distinction made between 'Recoverable' and 'Unrecoverable' errors
Wants to use Result (enum? Monad hopefully (please let enums be Monadic...getting worried they aren't)) for 'Recoverable'
Wants to use so-called panic! macro for unrecoverable.
From what I've seen so far panic is way too common and 'expected' (I've noted that array accesses can result in a 'panic')
language-users IMHO should NEVER encounter a panic in a situation that they have control over (like array accessing)
such accesses that might not have results or have errorful results should be handled in a Monadic way (return an Option or Result)
'panic' IMHO wants be reserved for truly world-ending and unexpected situations like 'out of memory' or language-runtime-bug encountered.
We are already starting off badly since I'm not a fan of the implementation of the philosophy in some of the core library stuff I've already encountered.
Possible I can still live with this as long as it is possible to intelligently and easily avoid usage of the bad/evil language 'features'
Not a fan of backtrace not being the default
Don't like that backtraces don't appear to have column-numbers (is that an option?)
Doesn't appear to be but also appears an area of active development so willing to 'wait and see' on improvement
Feel that the 'backtrace' is a bit unreadable
Disappointing that not all lines have at least line numbers
Feel that the LHS row-numbers are not useful/helpful and just add noise
Examples in the book of where/why to use panic
Get the feeling either the book-writer or language-designers never programmed anything large/complex
Possible this is just bad-writing and 'simple' examples are being used, but feel this is going to lead to bad-practices and should be noted that this is NOT the way to run a ship (just doing here for purpose of explaining this feature).
Since there is no 'warning, this is bad style' I expect that the book-writer or possibly worse the language-designers, intend users to use panic! rather freely.
Feel strongly that since the core-library uses panic freely it this reflects poor choice of the language-designers.
Feeling like panic! is possibly going to be an Achilles heel of the language depending on how poorly the language-community reacts to this bad 'usage suggestion'.
Going to have to be very careful that any libraries are conservative with panic
perhaps might even be worth an linter-check to verify that there are no panics used in library or dependencies.
Might even be so bad that panic would have to be 'caught' (if that is possible)
Don't feel that 'catching' is a good idea generally (in cases where the 'panic' is legit like OOM they shouldn't be caught)
Might be forced into that bad situation due to poor guidance by language-designers on how to use panic
Nervous that Enums and/or Results are NOT Monads
Have not seen even a hint of a map() function or that there is 'another way' / style to handling
Possibly just being uber-conservative and not wanting to be off-putting to the non-functional crowd, but I'm starting to loose faith/patience
Feeling that expect(...) is quite the poor choice of naming since it is the opposite.
else_panic! would have been a better name
OMFG they created a special syntax structure of ? to avoid 'map' ?!?!?!??
Why?
Are they intentionally being dense or is there something I'm missing?
Does ? mean map or is it just for this one special case with Result?
The ? Operator Can Only Be Used in Functions That Return Result well I guess that answers that.
At the very least they've created a special 'hard mode' way of dealing with Results...and I fear there isn't an 'easy mode'.
Chapter 13 promises 'Functional Language Features'
Feeling it is ominous that this is the 13th chapter (what horrors does it contain?)
Error Chapter contains first hints of something called a 'Trait Object' that looks like Box<dyn Error> that is supposed to 'allow for values of different types'.
In my present state of mind I don't know how much more crazy I can take before I give up.
I'm sort of 'thrilled with dread' at how bad things are going to get, and feel this new horror is looming around the corner now.
Still hopeful there is light at the end of the tunnel, and that there will be 'salvageable' parts of the language that somehow manage to save it.
At the very least it promises not to be boring which is good enough to continue....how bad can it get? :)
Books idea of 'when to call panic'
Suggests that 'unwrap' is OK to use if the 'user knows better than the compiler'
Feel this is a bad practice.
User is almost never smarter thant the compiler
Code evolves over time so what might once have been sound reasoning might no longer be sound.
Rustlang Generics/Traits
Generics appear to work as expected
Due more I feel to simple lack of imagination, or perhaps this was designed later when saner heads were in the mix.
'Monomorphization' my what a fancy word for compile-time rewriting of code to be more concrete.
Funny how some 'magic' isn't so magical under the hood.
Interesting idea to have 'paritally defined' Generics, I think I like it.
Traits == Interface
Book notes there are 'some differences' to an Interface...what are they?
Liking the 'Partial based on Type' interface implementation
Novel? First I've seen. Wonder how it feels in practice?
'Closed traits' (can't implement a 'trait' outside of your 'crate')
Appears to be targeting the 'Ruby' problem.
Agree with no 'overwriting' of external type trait impls (what killed Ruby)
Want to disagree with 'adding' traits/impls to other types.
Need to think about that some more, feel the pendulum swung a bit too far.
Feels like adding could lead to some nice behavior naming-wise and scoping-wise
pub fn notify(item: impl Summary) {
ouch that 'impl' is an ugly way to specify an interface
Why is it needed, why isn't item: Summary sufficient?
Even if it is needed that 'impl' wants do mean implimentation not interface/trait
pub fn notify<T: Summary>(item: T) {
Good to know there is an even uglier form (so I suppose one should be thankful for the slightly prettier ugly form?)
Better: pub fn notify(item : Summary) {
See no purpose currently for all the extra-special-syntax care to distinguish interfaces and types
Feels like the phrase 'coding to the interface' would be a foreign idea to the language-designer (ignorance/spite or is there a solid reason?)
The + syntax for 'combining' interfaces feels a bit lazy at first glance but 'works'
Better would be to give a proper name to a combination of interfaces
Now I see the reason for the ugly: the where clause
Feeling this fits into 'create problem so I can show how clever I am at solving the problem I just created' idiom Rust seems to be enamoured with
Better to not have the problem in the first place
pub fn notify(t : DisplayClone, u: CloneDebug) is way easier to read, type, understand
pub fn notify(t: Display + Clone, u: Clone + Debug) also works for the lazy
Just like the problem with the unneeded Reference/Value distinction, the manufactured problem of Type/Interface distinction does not benefit language-users, and in fact is a detriment.
First 'crate' and now 'impl', I'm feeling that the language-designers where big fans of the smurfs and/or brainfuck
Perhaps should feel grateful that 'crate' and 'impl' are separate (would make about as much sense to combined them)
Rustlang Lifetimes
WTF?
Why is this needed?
Surely the compiler has enough information to determine lifetimes of all references or safe defaults?
Why not just use the function scope as the lifetime (as it seems to be able to do in most cases?)?
when a function has references to or from code outside that function, it becomes almost impossible for Rust to figure out the lifetimes of the parameters or return values on its own. The lifetimes might be different each time the function is called. This is why we need to annotate the lifetimes manually. is the explanation we are given.
Why not just default to `a for lifetime of all arguments?
aka if fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { is a 'reasonable' solution why not just have the compiler write it?
Feeling like the answer is because we might be able to release some resource just a tad sooner if we give user assembly-level access to the internals of reference counter/borrower.
The real answer I fear is that the language-runtime developers sort of 'gave up' when the counter/borrower logic got too much, and left burden of their failings on the language-user, so that code could be written for some benchmark to 'prove' that Rust was just as fast/efficient as C.
IF this is a 'good' feature and not a 'BS' feature as I suspect here is a better way:
the function signature syntax itself is crap (as I've come to expect now)
Better would be fn longest(x: &[a]str, y: &[b]str) -> &[a]str {
no reason to 'define' the names ahead of usage
IMHO using square brackets makes it feel a bit more like the lifetime name is a particular 'part' of the reference (which it is, a 'time' part instead of a 'value' part)
weird apostrophe syntax is just confusing and weird, that compounds the confusion and weirdness
if one is going to do something weird at least hit the language-user with one weird thing at a time not two at once
the type syntax is crap
're-using' <> to mean either 'lifetime name' OR 'type name' has that now-familiar 'smurfy' smell to it.
better would be struct ImportantExcerpt[a] { which would allow struct ImportantExcerpt[a]<a> {
name collision between generic-type-name and lifetime-name avoided since lifetimes would only be referenced inside []
to be clear feeling rather strongly now that this is a BS language 'non-feature' but if you're going to do it, at least make the syntax not as horrible
Feel Lifetimes are now the 3rd manufactured pain-point (No reason to have except to solve its own pain)
Lol! After writing a lot of Rust code, the Rust team found that Rust programmers were entering the same lifetime annotations over and over in particular situations. These situations were predictable and followed a few deterministic patterns. The developers programmed these patterns into the compiler’s code so the borrow checker could infer the lifetimes in these situations and wouldn’t need explicit annotations.
The explanation of 'lifetime elision' admits that it isn't needed, and is due to failings of compiler to determine lifetimes (can at least commend them on honesty)
Better would be to use safe default lifetimes (I feel there is always going to be a safe option that is reasonable (function scope if nothing else))
If someone needs extra performant code then let them break out the ugly syntax in those (no doubt super rare) instances where that is needed.
Automated Tests
Well done to include automated testing as a 'built-in' for the language
Doesn't seem to be a clear distinction between 'test' source and 'production' source
Feel a simple /tests directory would have solved
Basic functionality, no real depth at all
no built-in ability co 'compose' assertion conditions
no concept of 'test resources'
Rust seems to want unit tests to live next to code
Think I can be OK with this as long as it is possible to break test code out into separate files with easily distinguishable names
Ah...there is a tests directory but is for integration testing (no access to non-public code)
Intermission chapter building a grep command
Tedious to wade through but feel it is important to get a feel for style
Better if they weren't trying to teach programming AND Rust at the same time
little chance that the audience is new to programming
Note that they use clone as a work-around for the the poor reference handling
If it is too broken to use in THE example of how to write code, then what was the point?
Shockingly, at least the book author thinks a lambda is a closure
IMHO closure is something that 'closes over' a scope (doesn't necessarily have to be a lambda but usually is)
One forms a closure and it is possible that lambdas will create a closure if they reference a scoped variable
However, if the lambda doesn't reference any scoped variables then it isn't a 'closure'
I'm frightened that the language wants to refer to lambdas a closures....please...no....
calling a lambda a closure in this way, is like calling all refrigerators 'Kenmore's
Admit to skimming here. Life is short.
Feeling that Rust is at this point language with many built-in flaws and might not be worth the effort
Will continue as the meaty subjects like concurrency and functional programming are ahead and there is still a slim chance the language isn't a total loss
It took the book author 40 paragraphs and 695 words to say: eprintln! prints to stderr. FML, my patience is wearing thin....
Rustlang Functional Features
Closures
Annoying as mentioned earlier to refer to all lambdas as closures
Feeling that this ignorant way of speaking (not using 'ignorant' in a mean way, feeling language-designer just didn't know the distinction), speaks to the ignorance of the language-designers at this point and I think hints to all the troubles this language has.
Feel the |var| {} syntax is OK but that the | is a bit of a clunky character.
Prefer var -> {} style
Telling that they mention Ruby as a inspiration choice for this syntax
Iterators
OMFG 'Iterator' has a:
map
collect
filter
Book section does a crap job of explaining or env just listing the Functional features
flatmap? : Yes https://doc.rust-lang.org/std/iter/struct.FlatMap.html
Full Iterator docs: https://doc.rust-lang.org/std/iter/index.html
Option does have a map: https://doc.rust-lang.org/std/option/enum.Option.html#method.map
Result does have a map: https://doc.rust-lang.org/rust-by-example/error/result/result_map.html
Feeling will have to look elsewhere for reasonable explanation, but happy that Rust does indeed appear to have first-class functional language features.
Faith somewhat restored
Feeling at this moment that perhaps this language is possibly salvageable if one can ignore the bad parts.
Feeling relieved (Up until I saw map on Iterator the book/language had beaten me down almost to the point of quitting)
Rustlang Documentation
Love that documentation comments can be run as tests
Feel there is a strong synergy between tests and documentation in any language
Glad Rust recognizes the synergy
Feel there is room for more here, but will give credit for a useful innovation
Meh on the ///
Would prefer an open/close style syntax at least as an option
Crate.io
Unfortunate and odd that github account is only auth mechanism (would expect to see multiple oauths)
Like the balance that 'yank' provides for publishing and 'hiding' bad-publications from view.
Feel that Semantic versioning is a mistake but an understandable one
Simple monotonic like date or 1-up integer would be better
Like the use of a publisher-secret but needs to be a signing key (maybe it is?)
Workspaces
Meh on the name, that probably wants to be something like 'Project'
No a fan of the relative paths, those want to be unique names for sub-modules
cargo install
Not a fan of 'global' 'hidden' binary installation
Better would be to have some form of built-in packager/package manager instead of going the 'hacky' way
cargo-something named binaries as 'cargo commands'
Like the naming convention and the extensibility this offers
Not a fan of 'anything ing $PATH'
Needs to be a ~/.cargo/extensions and/or project-name/.cargo/extensions
Rustlang Smart Pointers
Just reading the name I already feel like I'm going ot be sick...but let's power through....
Box puts thing on the heap
Why not just have the runtime figure out what to box/unbox?
Oh joy (not) there is a * dereferencing syntax.
At least it isn't something weird, and behaves in a c-like fashion
Going to call this the 2nd great universal mistake after 'null'
Possibly even worse, prolly Trillion-dollar instead of Billion-dollar mistake.
Deref trait
Why aren't all values 'dereferencable' ?
Hints that this isn't a real memory-pointer kind of reference/dereference like in C
Rather purposefully built-in as a control mechanism for what is on/off heap but want to make it look a bit like C
All the pain and none of the real purpose?
Why not just have a 'HeapOnly' annotation if one wants to fetishize controlling where values are stored?
Why is there a different Deref(Mut)trait for immutable / mutable?
Drop trait
Dangerously Interesting that the language gives access to when things go out of scope
Neat for logging but feels unsafe
Whole point of Rust IMHO is that it deals with resource de-allocation for the language-user
Having a destructor kind of puts a lie to the safety if language-users can fiddle with the de-allocation process too much.
Sometimes non-language resources need to be cleaned up as well, so happy to have a mechanism for indicating when this happens
Feel strongly that this should NEVER be used for language-resources (memory)
Rc trait (Reference Counter)
First impression: Dangerous to the point of probably not being recommended for use
Expect the language compiler/runtime to deal with ALL reference counting
Feels like the sort of thing that exists purely for language-users to get into trouble with it
Good debug for Rust-language compiler writers but not seeing point for language-users
Feels like this wants to be an internal-language construct that is NOT visible to normal language-users
Except possibly for debug-purposes where read-only parts like counts are exposed
RefCell
Hard to imagine a legit scenario where the compiler wasn't able to correctly reference-count
Possible this is due to lack of imagination on my part....but at the moment I don't see it.
Reference Cycles
Interesting to note that Rust does not perform any detection of reference cycles
Disappointing but that is a hard problem...something to think about
Feel that having first-level language abstractions for references only makes the cycle problem worse
Easier for language-user to have 'hidden' cycles
Rustlang Concurrency
Threads
no green threads as built-in (hints to a separate library)
move keyword to move variables
why not just move on reference?
Message Passing
Channels behave as expected
Suspect would be better threads should just create by default (result of the spawn)
Nice that Rust protects against accessing mutable variables after sending
Better if only immutable were allowed to prevent the problem
what madman would send a mutable thing and expect it to work between threads?
again feels like a 'manufactured problem' that serves no purpose
Shared Memory
Dangerous but potentially useful
Mutexes work as expected
Atomic References via Arc work as expected
Sync and Send 'marker traits'
'Build Your Own Concurrency' seems like a bad idea
I trust language-designers barely to get concurrency right, not sure if trusting a library here is a good thing
Rustlang OO
If a language must have inheritance to be an object-oriented language, then Rust is not one
Happy to see this 'non feature'
Book recommends traits (interfaces) as means for one value to have multiple 'types'
Good practice, happy it recommends
Dynamic dispatch for traits?
Why?
The compiler doesn’t know all the types that might be used with the code that is using trait objects, so it doesn’t know which method implemented on which type to call
This doesn't seem correct
'Object Safety' of 'Trait Objects'
There are no generic type parameters
WTF, why?
once you’ve used a trait object, Rust no longer knows the concrete type that’s implementing that trait
Yes it should be able to
Feels like a huge miss on the compiler, is this going to be fixed?
Interesting to note that the book spends 4351 words and 263 paragraphs explaining how one might want to implement the OO 'state pattern'
compared to 2422/173 on how to use map/collect and doesn't even mention flatmap)
Feeling the book is not using my time/attention well
Rustlang Pattern Matching
Good that matching is exhaustive
let is defined as let PATTERN = EXPRESSION;
Can't quite put my finger on it but I'm seeing let used in ways that feel inconsistent weird
if let Some(x) = some_option_value {
Why isn't this if let x: Option::Some = some_option_value; ?
Function arguments are pattern-matching in nature
fn print_coordinates(&(x, y): &(i32, i32)) {
The above wants to be:
fn print_coordinates(i32:x, i32:y) {
Another good example of how poor choices (references and bad type specification syntax) make overly syntax-garbage-filled/unreadable code.
'irrefutable' and 'refutable' to distinguish between full and partial pattern matching
Seems like reasonable language, is this a Rustism or is this widely used terminology?
Good that destructuring is a thing in Rust
Match Guards
Some(x) if x < 5 => println!("less than five: {}", x),
Really neat idea. Similar to concept in TypeScript
Would love to see this as a 'first class' definition of a type (similar to TypeScript)
| as part of match-gaurd syntax to mean 'OR'
no corresponding AND ?
Can see it getting messy, possibly less is more here
@ binding operator
Like the idea
Seems a bit too verbose
Message::Hello { id: id_variable @ 3...7 } => {
better Message::Hello::id { 3...7 } => {
and then reference the 'bound' variable to id
Rustlang Advanced Features
Trait 'placeholder' types
Why?
From reading the explanation it appears to be a hack to get round some sort of 'Generic within a Generic' combinitorial implementation issue
How often is that a thing in practice?
Is that even bad to specify the implementation multiple times?
Supertrait
Lol inheritance is bad, lets have composition via interfaces...but lets let the interfaces inherit?!?!?!
Really dumb stupid idea. You know it is wrong and do it anyway. Bad Rust, no cookie.
Newtype Pattern
Delegation to create a new wrapper type
Type aliasing
type keyword
Possibly some interesting things to be done here...will have to play around to see.
! empty type
never return
Macros
Why the need to define before use?
Get that it would make the compiler harder to write but doesn't seem like it would be that much harder
OMFG entirely different syntax
macro_rules!
Syntax appears to be very specific and limited.
Feels like more of an afterthought of 'how can we handle vargs'...oh I have an idea...kinda thing
Procedureal Macros
Ah this was what I was expecting...
Rust doesn’t have reflection capabilities
Disappointing but good to know
TLDR appears one has full control over the AST...nice!
quote! macro...that could be interesting...can use outside in 'normal' code?
WOOHOO! it works. Can use quote in 'normal' code...{maniacal laughter}
#name nice, built-in templating
Why does the limited/wierd macro_rules! form exist? (just a stop-gap/hangover?)
stringify! works as expected. Nice!
Random Thoughts (Notes I made as reading/discovering that didn't fit in chapter context)
The fact that String literals like "foo" are references is annoying
consequence of poor reference/value defaults
just forget String exists and use &str
Better if language just removed idea of reference (like 'null' the idea of a value-reference is just dangerous and bad idea that needs to die)
In those rare instances where one needs to go down to 'assembly code level' have a special syntax for that don't burden 99.99% of language-user's
Hate &str as the type name of 'String reference'. Should be &String (or they should have named the type str)
Don't like from as value Type constructor/builder. Prefer shorter of
Don't like the documentation style where mut is used in examples. Feel it encourages bad practices.
Starting to despise the word 'crate' to mean 'module' and 'library' and 'executable' where one has to construct the meaning of 'crate' via context
Feeling 'crate' is a 'smurfism'
Stunningly short-sighted to have dependencies all route through a special name like https://crates.io
What happens to all the Rust code of the world when crates.io turns evil?
Better would be to have packages identified by secure public identifier (pub-key signed) and let user's choose where to get the binary representations
How does one control artifact dependencies in Rust 'for real'? (because the default appears to be broken by design)
Love the fact that line numbers AND column numbers are specified on compile errors
Starting to feel like the reasons for the bad-choices regarding reference 'exposure' is mostly in place so designers can 'show off' the fact that the compiler will detect when the language-user does the wrong thing. Sort of like putting down stumbling-blocks intentionally just so they can 'be the hero' and show off saving the user.
Better not have the intentional stumbling-blocks IMHO
WTF? Book suggests 'asking' the compiler for the return-type of a function by 'guessing' and then looking at the compile-error
Good that the compiler does this
Bad that the book suggests this as a reasonable practice to follow
Is there no language-server for Rust?
Surely any reasonable IDE would be able to suggest type
Why isn't this in the book?
Summary and Thoughts
There a lot of things I don't like about Rust
Unexpected how many things I didn't like
So many things wrong that I suspect Rust will be a stepping-stone language
Big things Rust got wrong:
References / Pointers
I get that Rust wants to be a systems programming language but there are better and worser ways of handling the 'dirty' details.
Feel that in the rare cases where References/Pointers are needed they should be abstracted from the language-user as types not syntax
Feel that the compiler should make decisions on how the stack/heap is controlled with the user hinting (via ugly syntax) for those rare instances where language-users want more control
Lifetimes / Ownership
Happy that Rust internally does the accounting for memory/resource accounting (The big draw for the language)
Sad that they are so proud of this feature that they burden the language-user with it
Feel strongly this should be a language-runtime concept that is hidden from language-user
In general, Rust syntax is too verbose and too unnecessarily ugly for the sake of being different
Types want to be defined in a c-like 'on the left side' ('C' won, deal with it)
In general following the lead of C/C++/C#/Java/Javascript aka mainstream is preferred unless there an obvious improvement to be made
Lots of NIH renaming that doesn't serve any purpose other than to be different
Trait = Interface
Crate = Module
Workspace = Project
The Good Parts
No nulls (Awesome!)
Pattern Matching well implemented
exhaustive
destructuring
Automatic Memory/Resource accounting (sort of)
Hard to call this a 'full win' due to the ugly syntax/semantics
The next language that uses Rust as inspiration will have this without all this ugliness
'Rust without the Lifetime garbage' will be the slogan
The 'half-baked' nature of the language-user-interface is what will compel the next language into existence
Obviously people want this or Rust wouldn't exist, shame that it was implemented so imperfectly
Entirely possible that I'm being too harsh and that while the book makes a big deal of Lifetimes, in practice they are never used.
Still bad/ugly they exist as a thing, but the degree to how often language-users are confronted with this mess, is the degree to which Rust will prove to be useful
Overall
I still want to like Rust and am not discouraged enough to give up on it entirely
But I am discouraged enough to look for alternatives before I spend any significant time with it
I note that Swift is also LLVM based which should give it similarly wide reach but is geared more for Apple platforms which makes it less attractive (narrows the language-community)
Feel that most of the heavy-lifting of the language is handled by LLMV, and it might be worth-while to spend time creating the better language vs trying to ignore the bad/ugly parts of Rust
0 notes