Meh, what’s a factor 10 when you’re still under a request per second? Does this actually matter?
I’m curious whether any attempt was made to contact the Bing team before the change & post.
Seems very unnecessarily frequent. If you had multiple search engines checking in this frequently it’d add up quickly
On laptops, I use knuckles for modifier keys. On other keyboards, I just use my palm for the control key. Save caps lock for the escape key.
I like having a tap on caps mapped to esc, and a press mapped to ctrl.
Actual ctrl key I map to ctrl+opt+cmd and press with the palm for custom combos.
The main problem with front end development was never the browser, but rather the endless layers/kilobytes of abstraction meant to make everything automatic.
As soon as something other than a print statement is imported, you can be pretty sure that monads won’t be explained simply.
A monad is a type m for which the following functions may be implemented:
(>>=) :: forall a b. m a -> (a -> m b) -> m b
return :: a -> m a
Subject to the following rules:
-- Rule 1
return a >>= k = k a
-- Rule 2
m >>= return = m
-- Rule 3
m >>= (\x -> k x >>= h) = (m >>= k) >>= h
That’s it. That is what a monad is (there are equivalent definitions that some people prefer over this one, but all of them give the same result). Monads get some special treatment in Haskell (do notation requires a monad), but other than that there’s nothing magical about them. Monads aren’t magical things. “Monad” is a name for a common pattern: a type whose definition permits the functions defined above.
It’s been 9 hours and nobody has mentioned C++!
I’m not suggesting you jump off the C++ cliff. Don’t use the STL. Don’t use RAII. Don’t follow “everything has value semantics and a = b does massive allocations and copies”. Don’t use the STL. Don’t use smart pointers. Don’t use exceptions - you can disable them at compile time. Maybe use the STL if you can’t be bothered to implement things yourself, but measure your build times before and after.
Start with C, and introduce C++ features when they let you write the same C code but more concisely/safely. Use operator overloading for mathsy types. Add an array class that doesn’t own its data, just acts as a wrapper around T* and size_t (and give it bounds checking). Make a string class that wraps char buf[ N ]; and snprintf (_snprintf on Windows does not behave exactly like posix snprintf FYI). Use the SCOPE_EXIT trick for resource cleanup. Use casts that explode if you smash values by accident.
Some examples of code I have that I think is neat and shouldn’t upset C programmers, starting with a better printf:
stuct v3 { float x, y, z; };
void format( FormatBuffer * fb, const v3 & v, const FormatOpts & opts ) {
format( fb, "v3(" );
format( fb, v.x, opts );
format( fb, ", " );
format( fb, v.y, opts );
format( fb, ", " );
format( fb, v.z, opts );
format( fb, ")" );
}
ggprint( "{.2}\n", v3( 1.2345, 2.3456, 3.4567 ) ); // "v3(1.23, 2.35, 3.46)"
a better string class (no allocations):
str< 256 > buf( "{.2}", v3( 1.2345, 2.3456, 3.4567 ) );
buf += v3( 1, 2, 3 );
buf += 123; // "v3(1.23, 2.35, 3.46)v3(1.0000, 2.0000, 3.0000)123"
a wrapper around Lua’s string matching code (no allocations!):
for( array< array< const char > > matches : gmatch( "test1 test2 test3 test4", "(test)(%d)" ) ) {
// matches.n = 2
// matches[ 0 ] = { elems = "test...", n = 4 }
// matches[ 1 ] = { elems = "1 te...", n = 1 }
ggprint( "{}_{}\n", matches[ 0 ], matches[ 1 ] ); // "test_X"
// trying to access matches[ 2 ] asserts
}
It’s hard to give specific examples of the problems in action but 1) you can pigeonhole yourself into writing code that’s ugly/inefficient, 2) it encourages managing resources in the leaves of your code which can be inefficient and difficult to follow 3) it’s viral - any structs containing RAII types become RAII types themselves, and 4) once classes start having meaningful constructors and destructors it forces a lot of complexity everywhere else. Your allocators have to start calling constructors and destructors, you have to be careful with memcpys and memsets, and not having to worry about that 100% of the time is a big win.
I didn’t mean you should never use it, but I think it’s rarely actually a win.
I’m not following you at all. From your submission history you seem to do mostly graphics programming, and I can buy that there may not be much use for destructors when you avoid dynamic allocation inside loops.
Statements like “allocators have to start calling constructors and destructors” and “you have to be careful with memcpys and memsets” reinforce that you’re using C++ in some highly niche way. I don’t write allocators often enough that the amount of effort going into them is a data point for the language. And yes you certainly don’t want to be using memcpy in the presence of destructors.
I went looking around the internet for critiques of RAII (because in 20 years of C++ programming I’ve never encountered criticism of RAII before), and found very few:
http://coliveira.net/software/raii-is-overrated (2011)
https://en.sfml-dev.org/forums/index.php?topic=9359.0 (2012) https://en.sfml-dev.org/forums/index.php?topic=19788.0 (2016)
None of these is very compelling at all.. So I’m still flummoxed. RAII is one of two reasons I use C++. My code samples there show that I don’t even use the class keyword when given the choice. But you’ll prise destructors from my cold dead hands.
From your submission history you seem to do mostly graphics programming, and I can buy that there may not be much use for destructors when you avoid dynamic allocation inside loops.
You’re right with that, but even in random glue code I find that RAII can be annoying sometimes. It’s hard to explain without having specific code examples, and I don’t run into it in my home code so I don’t have anything to share. I also expect that std::move helps with some of them, but solving problems with language features with more language features seems iffy to me and we don’t use C++11 at work.
you’re using C++ in some highly niche way.
I’ve been writing C for longer than C++, so I mostly write C and add C++ where I think it makes sense. So I guess you’re right there too.
I’ve been writing C for longer than C++, so I mostly write C and add C++ where I think it makes sense.
Same here, so I totally feel you.
I don’t use C++11 either[1]. So I don’t think that’s an issue here.
[1] On a tangent, my policy lately has been to move to a standard only when it’s the default for the version of the compiler shipped with the newest version of Linux and OS X (LTS in the case of Ubuntu). I often get questions from users on older versions of compilers, so this seems a reasonably conservative line in the sand. For small projects like mine, losing a single person who might have tried them out is a big loss. Ubuntu 16.04 and OS X Sierra (both released in 2016) neither enable C++11 by default. So I’m still on C++03. In a year or three I’ll migrate Mu to C++11 and start using auto and range loops.
As you say, to get by as “readable” you have to avoid a lot…
If you need a language that is fast as can be and type safe, D is much nicer and more readable than C++.
It’s like C++ but you can ask the compiler what it knows about any symbol and act on that knowledge at compile time.
Template meta programming in C++ is a complete nightmare… You can even ask the guy who invented template meta-programming and wrote The Book on it.
He went off and joined D instead since template meta-programming is simple, readable and straightforward in D.
“Don’t use the STL. Don’t use RAII. Don’t follow “everything has value semantics and a = b does massive allocations and copies”. Don’t use the STL. Don’t use smart pointers. … Maybe use the STL if you can’t be bothered to implement things yourself, but measure your build times before and after.”
Yes, definitely avoid exceptions if possible :)
database_connection db;
if (db.open("127.0.0.1", port)) {
...
}
// Don't worry about closing the connection no matter how we return from this function it will close
RAII should be exactly the same performance as the same code in C. The only time it should differ is if the C code avoided calling the “destructor” function before some of the return statements. You might have been confusing RAII with garbage collection or shared_ptr etc.?
A better printf, use either of these:
With streams you can do this type safely:
my_log<<"x="<<x<<", y="<<y<<std::endl;
With var args templates in C++11 you can do this also with type safety:
my_log_function("x=", x, ", y=", y);
if( !db.open() ) return;
SCOPE_EXIT( db.close() );
I added iostream/string/vector/map to every file in my project (80k LOC) with gcc -include and my debug build went from 2.7 to 4.7 seconds. Less bad than I was expecting but still not great.
unique_ptr is good but I find shared_ptr is a symptom of doing resource management in leaf code and losing track of/not caring what their lifetimes/owners are.
Not such a big deal if it takes 2 hours vs 1 IMO.
Format specifiers in streams are very very bad. They’re unreadable and they’re kept around as state on the stream to screw up your prints everywhere else when you forget to reset them.
Writing my_log_function like that is good and better than C’s printf because you can add your own types to it, but I prefer the printf format + args style. If you’re feeling ambitious you can actually write a monster print that combines both styles, see autoprintf.
Edit: if you do actually implement printing with templates it’s a big win to always disable optimisations to keep compile times down. If you want to do it cross-platform you need something like this.
SCOPE_EXIT is definitely better than normal C goto or while/break.
Yes shared_ptr can be a sign you are doing the wrong thing, especially if every single pointer in your application is a shared_ptr. In my code I find myself mostly using std::array, stack objects + references and occasionally unique_ptr which I am basically using as an “optional” return instead of returning a raw “null or object*” depending on if something was created or not.
Yes format specifiers with state are the worst. You could possibly do something like:
my_log_function("x=", FloatFmt(2, x), ", y=", FloatFmt(2, y));
Or:
my_log_fmt fmt;
fmt.set_float_precision(2);
my_log_function(fmt, "x=", x, ", y=", y);
my_log_function(fmt, "z=", z, ", w=", w);
I think I prefer the second one.
Thanks for the optimisation pragma tips!
While I do mostly agree. It could be argued that the resulting code is readable but not writable or maintainable unless the next coder is already a capable C(or worse, C++) programmer anyway.
I myself ignore these concerns and write Objective-C++ on occasions when I think the performance boost is worth it.
Chrome won just like IE won. Maybe it’ll last longer. But proposing standards, implementing them, and pushing them before they are actually standard is no different from what we used to hate MS for.
(For the record, I prefer Safari because battery life and accessibility are more important to me than ..webrtc?)
I think that “indexes” should start at 1 and “offsets” should start at 0. That is, I think a simple name change could fix the whole argument.
[EDIT: This comment is largely wrong. Collections are 1-based, Streams are 0-based. It’d been so long that I’d forgotten. The point in general stands, but the code as-presented below will not work as expected; even when doing a range copy on a SequenceableCollection, it works 1-based with inclusive upper bounds. Doing a PositionableStream on the underlying collection will work as presented here. Sorry about that.]
That’s exactly what Smalltalk does.
c := #(a b c d e f). "Declare a five-element array."
c at: 1. "a"
c at: 5. "f"
c at: 6. "throws an error"
c copyFrom: 0 to: 1. "#(a) EDIT: Nope, wrong!"
c copyFrom: 0 to: 5. "#(a b c d e f) EDIT: nope, wrong!"
This made instant and intuitive sense to me when I learned it as a kid in a way that 0-based indexing definitely did not, so I’m definitely on board with it. But I’d also note that in Smalltalk, as in many other modern languages, I barely ever even type the array index in the first place; doing things like first, last, allButFirst: 2, etc. are much more common. So I can’t honestly say it made a huge difference either way. (When I picked up Smalltalk’s successor, Self, I programmed in it for several days before I realized that its indices did in fact start with 0. And I only realized that because I thought I found a bug in the debugger.)
If you see everything as an offset from the beginning of an array, you can stop using the word index, and the confusion should stop.
If you see everything as an offset from the beginning of an array, you’re thinking in terms of pointers and RAM blocks instead of thinking in terms of arrays. That abstraction slip will cause you problems.
I agree with his opinions on all but the search example, a big magnifying glass is just as easy, if not easier to see than the smaller “Search” blurb. The icon color in the case he chose could’ve contrasted more with the the background however.
Part of the point was that the icon is completely unparseable to a screen reader. Some users have limited sight, for which better visibility is relevant. Some users have no sight.
I would suggest trying this in a screen reader (ChromeVox and Apple’s VoiceOver are both free), with your monitor turned off. Most web designers have no intention of doing that, so if they think about it at all they’re guessing how users will hear their UI, and then users are having to guess what the designer was thinking.
Using labels is a simple rule that is maximally explicit about what fields do what. Testing designs in screen readers would also work.
Alt text in this situation turns out not to be ideal, since the image is merely “near” the field in the structural layout, and not associated with it in a way that’s programmatically detectable. But the way to know is to try it, not to guess.
Can you create a label that says “Search Query” for the search input, and hide it using “overflow: hidden” or something, and use alt text for the magnifying glass submit button that also says “Search”?
You can use ARIA to add a lot of the hints needed. I’ve not seen a lot of front end developers make use of this.
Sometimes compilers aren’t very good.
How much time would you have to invest in learning Assembly until you start to find inefficiencies in compiler performance?
Also, keep in mind that the abstractions you write for the compiler to work with could be a horrible solution to solving a particular problem.
It’s usually not too complicated to spot, problem is the compiler generates an awful lot of assembly and you have to look in the right place(most of the output is optimal already).
[Comment removed by author]
Clang has the __nullable and __nonnull annotations, don’t know if the optimizer takes them into account however.
I mean, I use both telegram and whatsapp and I have to say I prefer whatsapp.
I really don’t understand why telegram doesn’t use encryption by default. That’s a bit silly.
[Comment removed by author]
[Comment removed by author]
Previously you’d be able to install the f.lux app using sideloading via Xcode (see https://justgetflux.com/sideload/#sideloading-flux-on-ios-with-xcode-7) vs. the previous requirement of a jailbroken phone. That ability was short-lived because it violated the iOS developer agreement. They’ve been having conversations with Apple for over 5 years asking for those APIs to be documented.
Even though Apple will now include this feature natively, it seems that the APIs f.lux needs will remain undocumented, and therefore unusable in a 3rd-party app.
That command does not work because the redirection is performed by the shell which does not have the permission to write to /dev/fb0. The redirection of the output is not performed by sudo.
How to do it here
You can use
teeas well:It’s quite funny that person who don’t know how shell and
sudo(nb: usedoasorsuinstead) tells us a lengthy story about writing to framebuffers in LinuxThe frame buffer is arguably a lot simpler than a *nix shell
You better don’t, it’s vulnerable to the ages-old TIOCSTI trick::
(in
.bashrcor so)This can be deterred by using
su -P, but it’s marked as experimental (according to the manpage), and I haven’t seen anyone using it.more info here, as I haven’t heard of it previously https://ruderich.org/simon/notes/su-sudo-from-root-tty-hijacking
This probably works for the author if they’re in the
videogroup:EDIT: I’m stupid, didn’t see that part of the article.