giovannibajo1 | 7 years ago | on: Secure Secure Shell (2015)
giovannibajo1's comments
giovannibajo1 | 7 years ago | on: Announcing Rust 1.28
Not all partial borrows are safe, but a lot of them are. Most programmers know how to write safe code coming from different languages without borrow checker; they do put bugs sometimes -- that's true -- but most of the times the code I write is safe. It's just that there's no way to tell Rust that it is, and the workaround has a global impact on the code being affected (it forces to split structures, which greatly increases the cognitive load in reading and writing the code).
> * Rc/RefCell/Box > Yes, this is painful, but that's because shared ownership is painful.
But the point is that I do NOT want shared ownership. What I want is to have a single owner of a long-living object, and several long-living references to it in other objects. When I say "long-living", I mean that the liveness of those objects is not visible through the call stack, so I can't use borrowing references. The only way to model this today is with shared ownership, which implies more than I would be willing to imply.
The same problem is apparent when trying to implement the callback pattern (which I forgot to list in my OP). Callbacks are basically impossible to do in Rust, and I found out I must have used callbacks everywhere in my last many years of programming in different languages, because I feel helpless in Rust when structuring code without being able to register and use callbacks.
> This is perceived as a good thing; if you code changes later to use threads, you're not hosed.
This does not sound very Rustecean :) If Rust is not opinionated and gives me full power with zero cost overhead, why does it force me to pay for thread-safeness (overhead) so that I can use threads later (opinion)?
Notice also that code which is not thread-safe doesn't prevent me from using parallelism. It just prevents me from moving objects across threads. But I can surely leverage the power of multi-core with threads, as long as the thread-unsafe objects are created and used within a single thread. So I'm not sure why I should make them thread-safe... just because I want to use them in a non-const global.
> If you want something that's not for multi-threading, then don't use something that can be used with multiple threading! TLS is probably what you actually wanted here.
What I want is actually much simpler: let me initial globals with runtime code that the compiler schedules for me to run before main. C++ does that very well; Go does that optimally. Either approach is good enough.
PS: TLS is potentially overhead again: indirect reference on non-PIE binaries.
> Rust is pickier about numbers than many langauges; 1u32 + 1u8 doesn't compile either.
I love that "1u32 + 1u8" doesn't compile, I hate integer promotion. What I'm saying is that "1u32 + {integer}" compiles, while "Wrapping<u32> + {integer}" doesn't. I think it's been a bad tradeoff to force people to use generics for wrapping integers when generics are still not good enough to implement a type which behaves like a native integer on common operations like "+ {integer}" or "as <type>".
giovannibajo1 | 7 years ago | on: Announcing Rust 1.28
* Partial borrow. I can't borrow a field of a structure and then reference another field. I can't cite how many times in a few weeks I've been forced to rethink and split my structures just to work around this, making my code harder to read and write for no good reason than working around this limit of the borrow checker.
* The Rc/RefCell/Box dance is very verbose, when you just want to share a reference to some long-living object within other long-living objects. Worse than verbose, it also causes a runtime overhead because of the RefCell.
* No simple way to declare non-const global objects, like something as easy as a global HashMap of constants strings to constant integers. I'm a little spoiled from Go's excellent support of init functions (both compiler-generated and manually written), but this is something I really miss in Rust. lazy_static! is a workaround which is harder to use and forces the code to be thread-safe even if no threading support is necessary (that is, I can't use my non-thread-safe classes in a lazy_static).
* In generic code, there is no simple way to represent integer types. You need to use the "num" trait which breaks the "as" operator causing big pain and less readable code (as it's normal to covert between integer types).
* No integer generic parameters. We have to use the "typenum" crate which ends up causing less readable code and generates C++-like error messages.
* PhantomData is awkward, it absolutely sounds like something the compiler should handle, not the programmer.
* "Wrapping<u32> + 1" doesn't compile, but is there a good reason why it does not? I really wish Rust added wuNN/wiNN native wrapping types, or evolved in a way that I can write the same code with "u32" and "Wrapping<u32>" (another example: "as" doesn't work). Right now, it seems like the solution is half-baked: it tries to use the generic to avoid adding a native type, but the code that users must write is more bloated compared to native types.
giovannibajo1 | 7 years ago | on: Replacing Linux with a Database System
giovannibajo1 | 7 years ago | on: Performance patches in Go 1.11
giovannibajo1 | 7 years ago | on: Performance patches in Go 1.11
PS: I'm the author of those prove patches.
giovannibajo1 | 7 years ago | on: Mailing lists vs Github
giovannibajo1 | 8 years ago | on: Sublime Text 3.1 Released
giovannibajo1 | 8 years ago | on: New autoplay policy in Chrome
giovannibajo1 | 8 years ago | on: Ask HN: Have you lived abroad for an extended period of time? Was it valuable?
giovannibajo1 | 8 years ago | on: The Feds Can Now Probably Unlock Every iPhone Model
Previous iOS versions used to have some small window where you could race and power off after trying a passcode but before the enclave had incremented the counter, but that bug was fixed long ago. Maybe there are others unknown bugs of similar kind
giovannibajo1 | 8 years ago | on: Net Promoter Score Considered Harmful
Similar findings were made by Google with the YouTube rating system that was switched from 1 to 5 stars to a simple upvote/downvote after realizing that most users are polarizing towards the extremes: https://techcrunch.com/2009/09/22/youtube-comes-to-a-5-star-...
giovannibajo1 | 8 years ago | on: App with local notification will crash iOS Springboard on Dec. 2
giovannibajo1 | 8 years ago | on: Eight years of Go
I disagree with these. Go runtime/stdlib is architected to work around many many POSIX headaches and design bugs, hiding them completely from programmers, and to be fully portable. For instance:
* Concurrency is completely redesigned (goroutines). * Signal handling is redesigned and doesn't cause bugs when interacting with concurrency. * Forking/Exec'ing is redesigned not to cause fd leaks in subprocesses (all file descriptors are marked as O_CLOEXEC, in a race-free way), nor have races while interacting with concurrency * Sockets are exposed through a higher-level API (Dialer/Listener). * epoll is not exposed but transparently used by a single thread to handle all supported file descriptors without wasting OS threads, to improve performance
In fact, I think the only thing that is pretty much low-level is os.File and filesystem access in general, which tends to expose lower-level details.
giovannibajo1 | 8 years ago | on: Using Face ID to unlock brother’s iPhone X after entering PIN
Obviously the phone requires a pin after 5 failures, but that’s another matter.
giovannibajo1 | 8 years ago | on: Evio – Fast event-loop networking for Go
Semantically, a goroutine is a thread, within a shared memory model. But what makes Go unique (or let's say more unique) is that it offers programmers a thread-like programming approach (linear, blocking code) but internally turns it into an event-driven approach (epoll/kqueue) for networking.
Moreover, the fact that goroutines are much cheaper than OS-level threads enable a more pervasive approach to concurrency.
giovannibajo1 | 8 years ago | on: Evio – Fast event-loop networking for Go
The end result is much easier than Python/NodeJs because there is no explicit "async/await" or deferred-style programming. You simply write linear code and any blocking operation (at the syscall level) is transparently handled.
giovannibajo1 | 8 years ago | on: Screen sharing in Slack, made interactive via Screenhero acquisition (YC W13)
giovannibajo1 | 8 years ago | on: Gmail Launches Add-ons
On the other hand, your example is wrong on macOS where apple mail and safari are sandboxed. So desktop operating systems are trying to catch up security wise and go beyond the traditional Unix security model.
giovannibajo1 | 8 years ago | on: The trouble with text-only email