HNHacker News
TopNewBestAskShowJobs

cessor

321 karma · joined February 12, 2014

submissionscomments
cessor··on Writing good code: how to reduce the cognitive load of your code
> I think it's hard to prove/justify/qualify without some scientific evidence over a large population sample.

I agree with you, which is why I decided to gather some evidence about stuff like this. Here is a start - I have posted links to it before. Grab the preprint it will soon be ieee published:

https://brains-on-code.github.io/ (I am the first author of this piece).

Cognitive load in general is vague and hard to measure and thus difficult to find evidence for. However the effect of memory during program comprehension can be measured, as memory is well understood (tons of psych studies).

While memory surely plays a role to explain differences in program comprehension, it isn't enough to explain all differences. Experts in many experiments are often not impacted by bad code as much as novices, so experience also appears to play a role.

Memory is often said to be limited by its capacity, but most people ignore that the classic memory model explains linguistic encoding (e.g. there is not only long and short-term memory, but also a phonetic loop, an episodic buffer and a "visual/spacial clipboard"). This it is likely that code is influenced by language processing (thus, as my studie argues, one should use natural language words as identifier names), influenced by expectations (for example layout, style), etc.

But still that's not all. Some problems are difficult to decide. Imagine a short recursive algorithm for some problem, used appropriately. It might be an elegant solution, and could maybe replaced with a loop.

Does the fact that the solution is recursive, and thus builds a virtual tree, and maybe has a non-linear behavioral order, reduce cognitive load, or increase it? Should it be replaced with an equivalent loop?

What if we found out that the curly braces cause more cognitive load, when placed at the end of a function's signature, rather than on the next line?

cessor··on Design Patterns – A comprehensible guide
It's true that other languages often don't require certain patterns. Strategy and Visitor are often unnecessary when a programming language has functions as first class citizens.

I found that it often helps to remember that the GoF book was written about object oriented patterns with C++.

cessor··on Design Patterns – A comprehensible guide
> "Why don't you just add these patterns into your computer language as abstractions? Wouldn't that aid comprehension even more?"

I often asked myself this question! Why do I have to say

    public class DatabaseConnectionSingleton {
        public static DatabaseConnectionSingleton getInstance (){ ... };
    }
and then get an object using:

    var db = DatabaseConnectionSingleton.getInstance();
Why can't I say

    public singleton DatabaseConnection {...} 
and just go

    var db = new DatabaseConnection();
and let my runtime make sure that I get the appropriate instance? Left aside the discussion of how useful that pattern is, I would like my language to be more powerful. I am aware of alternatives (Borgs in Python) and that many people consider Singletons an antipattern, as it helps introduce globally shared state, etc. but then, why do I have to care about how instances are implemented?

After all, in C#, foreach interacts with iterators, why not push other mechanisms down into the language in the same way?

Ideas:

    // Unit of work, commits changes before the reference gets removed from stack
    public unit CustomerForm { } 

    // There can be only one.
    public singleton DatabaseConnectionHighlander {}

    // Any method called updates values in some way
    public builder QueryString {}
cessor··on Stop Disabling SELinux: A Real-World Guide
I ran a centos server for a while (ran= not my responsibility any longer) with SE Linux and a tomcat portal app, as well as other, custom web apps (ruby on rails with a mail queue and mysql backend, etc). I always left it in permissive, because I couldn't figure out how to properly configure it.

I tried understanding the principles behind it and configuring the different exceptions for several classes, but often, this didn't work (e.g. I had used wrong class, or enabled exceptions that were still blocked). The users of the rails app kept calling, asking me why this or that feature wouldn't work. It was impossible for me to configure all exceptions - to me this was not surprising, given the complexity of the software that we had installed. I simply deemed the apps too complex and too "feature rich" to configure all SELinux exceptions manually.

I then understood that there is a different way: To set it to permissive, keep it running for a while and then generate an installable permissions profile, allowing all occured violations as some kind of permissable exceptions.

This made sense to me, however it required downloading some dubious python script, that would create some dubious binary file. I got this to work, but then again, this or that feature was blocked. I finally kept it running on permissive. This is my individual story. The article makes it look as if it was really simple to configure it (When I started with SE I tried similar moves but never got it to work).

So, is it just me, or might it be that SELinux just has a major usability issue?

cessor··on A convenient untruth: Array notation in C is a lie
I agree.

Simply put, it would sense to provide

    #define CharPointer char*
and then declare

    char c = 'a';
    CharCointer p = &c;
To me this became clear when I did some C# interop, where IntPtr is a common class, such as:

    [DllImport("user32.dll")]
    static extern IntPtr CallWindowProc(WndProcDelegate lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
It's just an object oriented pointer interface. It looks different. I agree:

> It has different size and behavior.

cessor··on A convenient untruth: Array notation in C is a lie
Thank you for clarifying. I have never heard of "declaration mirrors use" (DMU) before. Also thank you for explaining it in a non-hateful way (which isn't always the tone when touching religious matters). Next up: Tabs vs. Spaces ;)

This sounds really odd to me. I can see, and others have pointed this out in the comments, too, that DMU might facilitate building a compiler for such a language and reuses several operators. However, I am not sure whether I like this goal from a person-centric perspective.

Experts might be used to matching declaration and use structures in their code, maybe to make it more 'symmetric', but I am sceptical whether this match is actually quite 'expensive' when developing code with many people of different skills.

Use and declaration are differnt concepts, and as such should have different representations (i.e., syntactically), otherwise you might introduce synonym defects (i.e., ambiguities, where it becomes hard to understand what somebody means). I found that some of my colleagues and students had a hard time to learn what pointers are about (and I believe this is a fairly common phenomenon, that people find pointers in C hard to grasp), because the asterisk is used both in declaration and in dereferencing. I found that some of my students got the concept more easily after I introduced a couple of macros:

    #include "stdio.h"

    #define IntPointer int*
    #define value_of(ptr) *ptr 
    #define address_of(v) &v

    int main() {
        int a = 42;
        IntPointer p = address_of(a);
        printf("%i\n", value_of(p));
        return 42;
    }
The above code has no other purpose than to separate the concepts verbally, so that they can be reasoned about explicitly. This can be achieved in other ways, for example, in C++ I tend to use templates or classes to abstract the pointer syntax away. Of course, I am aware that using classes introduces overhead and this technique is not necessarily feasible when you need as much performance as you can get.

This also underlines my original point to place the asterisk on the datatype rather than on the identifier, because the #define wouldn't make sense otherwise.

In summary, I was unaware that DMU was a design goal, but I suspect it to make the language more difficult to learn, code harder to read, altough this effect might not be an issue for experts.

I am not trying to convince anybody that DMU is "bad", but I am interested in the actual properties. Everybody making claims for readability owes the community an empirical evaluation. Disclaimer: I am currently working on a research project about program comprehension, including some eyetracking and FMRI work, providing exactly such evaluations. :)

cessor··on A convenient untruth: Array notation in C is a lie
I wouldn't agree to call it "wrong", since we're talking about languages that are trying to discourage you from doing your own memory management *(C#, that is, but I'd say this applies to any language running in a VM with gc, really). Thus, in such languages, there shouldn't be a conceptual or syntactical difference between values and references. The fact that C# allows to differentiate them from each other is a leaky abstraction imho, built in to satifsy people form a C/C++ background.

I believe that whether this is 'wrong' depends on the problem you're trying to solve. In my day to day work the difference usually doesn't matter, and I am totally happy passing around objects that others would call heavy. I am really happy that I don't have to care about references or values when doing scientific python stuff (pandas, numpy, etc), whereas I am also really happy that this stuff is important to people implementing these libraries.

cessor··on A convenient untruth: Array notation in C is a lie
The equivalent in C# always made more sense to me (not comparing memory or allocation model between the languages, but simply syntax in relation to a person reading it):

    int[] arr = new int[5]; // C#

    int arr[5]; // C

The fact that the brackets go on the datatype always made more sense to me, after all, I want to refer to memory of a certain cell size (as indicated by int). I realize that there is a lot of stuff going on when using new, but i believe even in C it should read, because you effectively change the datatype (to be of type pointer, rather than int).

    int[5] arr;
But then, I will now duck and get the hell out. This is the same reason why it feels wrong to write:

    int *arr;
You're not changing the identifier, you're trying to change the datatype.

In summary, I believe that the syntax to fiddling with pointers in C is very misleading, and this I fully agree with the article, but as many people are accustomed to this notation, I will now duck and get far away from the internet, in fear of all the hateful comments explaining to me how I am wrong, and apparently just don't understand the superior beauty of complicated C syntax. I will now go and check my garbage collected privilege.

cessor··on Ask HN: What's the best laptop for a programmer that isn't a MacBook Pro?
Here are some thoughts.

I have a Lenovo Thinkpad w510, which I bought in 2009. I work as a software developer, scientist and play games occasionally.

Pros:

- Extremely Powerful.

- i7, 4 Cores

- Came with 4 GB RAM

- GeForce Quatro Fx 880M

- 1920x1080 Color Calibrated Matte Touch Screen

- TrackPoint Style Pointer, see: https://xkcd.com/243/

- It's ugly and heavy, so less likely to be stolen

Cons:

- Heavy

- Battery lasts 30-40 mins, used to be 1.5 hrs.

- Loud after a couple of years of clogged up fan

- Price: I got a 30% academia discount, but it still was € 2600

- Screen is a little dim

My laptop is 7 years old now, but it is still running very well. I recently replaced the fan and it was quite easy to get replacement components. The old model came with 4GB RAM and a 500GB HDD, which I replaced with a 500GB SSD and 16GB RAM. It looks like it will last for another couple of years.

# Usabilty

Sturdy Keyboard. Good layout, F-Keys, and dedicated Power button, Volume controls, Home/End/Pg/Del button block. None of this "PRESS FN TO USE WINDOWS nonsense".

Touchscreen is nice, but I rarely use it as a primary input device. The touchscreen was unusable on Windows 7, but since Windows 8 it handles nicely. I didn't want it when I bought it, but it came piggybackriding the Full HD display, which I desparately wanted. Back then, most manufacturers were switching from 4:3 to a wide screen display layout and I didn't see myself using a 1388x<RandomNumber> display, especially because my old laptop had 1400x1050 resolution.

I can't stress enough how great the TrackPoint Stick mouse is on IBM Notebooks. Many people really hate it (please don't start a flamewar), but I love it, for it allows you to use the mouse without ever leaving the home row. It can be used quite precisely, but it takes some getting used to. I once played through the shooter "Return to Castle Wolfenstein" on a 4 hour train ride using only the track point mouse.

# Power

- During Software Development, I occasionally run several Windows / Ubuntu VMs at once, Visual Studio, IntelliJ, and it still handles nicely.

- I played Borderlands 2 for a long time on this machine. I had to reduce some graphic effects a little, but I could play it on full res (1080p).

- I run Photoshop and Lightroom, which can be resource hogs, but the machine can easily handle them

# Mobility

It is really heavy and also the power supply weighs a ton. The massive battery sticks out from the back. I bought it as a work horse, I got a work horse. Heavy, but reliable.

# Compatibility

I ran Windows 7, Windows 8, Windows 10, Arch Linux, Windows 10, each at least a year (except for my first Windows 10 install). Everything worked with arch, Windows 10 has all drivers and everything works fine. Just don't try to get into OpenGL programming when running nouveau drivers for the Nvidia Quatro FX on Arch Linux. They produce random system lockups (reported by others on the web) and don't support full sharder lang profiles. But other than that, you're going to be fine.

# Longevity

Getting replacement parts was really great, and I feel I made the right choice. My girlfriend as a MbP which she also bought around 2009/2010, which is running really slowly these days. She can't replace the harddrive, her battery is weak and she is stuck with 4GB RAM.

Being able to alter my hardware was a factor I didn't consider when I bought my laptop, but it turned out to be really handy. This is something you might want to look out for - how long the laptop will run and how you can extend its life.

Modern slim notebooks are very limited in this regard (it's nothing specific to the mbp), as it can be difficult to impossible to replace outdated components. However, a multicore system, SSD and decent amount of RAM should have you set up for the future.

# Other Recommendations

- I recently bought a new DELL XPS 13 for my mum, who travels a lot and still needs a bit of power. I would recommend it, but I can't say anything for its longevity. It's mobility is unmatched, the battery lasts an eternity, and it's quite powerfull, compared to its size.

- I have a Lenovo W (Workstation), but I heard Lenovo T are the best. I once used one during an internship, but its specs weren't that good, but it was robust and reliable. I wouldn't overgeneralize but most T users I have met were really happy with their laptops.

- I have worked with professionals, students, friends and relatives. One thing to me is clear: I will not buy a consumer class notebooks. These notebooks are usually between 300 - 900 Euros, and often cheaply made. Although there is nothing obviously wrong with them, there are odds and quirks that I find really confusing. It will be one or the other Wifi you can't connect to. Your bluetooth adapter will randomly switch on and off. The battery is dying for some reason. They break and fall apart. Keys get stuck or break off. Displays gets tinted and so on. Business line notebooks tend to do that less often, or at least later in their lifetime. I have been using my laptop for 7 years now and I won't (have to) replace it any time soon, given I don't drop it or it gets stolen. The people using consumer laptops tend to replace their notebooks every 3-4 years, which I believe is more expensive in the end.

- I would not just buy a modern Lenovo - or ANY other modern laptop for that matter - straight from the internet, but I would try to get my hands on it first (much like buying shoes: Try to put them on before buying). The manufacturers have been playing around with the keyboard layouts and other basic functionality, and some of these changes are a dealbreaker.

- Others in the comments have mentioned it: The quality and service got worse over the years. Try to get a decent service contract.

# Summary

- I believe I would buy a ThinkPad T series, if I had to decide now

- I value power & longevity, which is often limited to business class notebooks

- I'd rather pay for good quality once than for poor quality often

- Try it out before you buy

- Service is important

cessor··on Mocks Aren't Stubs (2007)
I often found that these terms are not very usefull when explaining the concepts of IoC in testing (which is essentially what they do) to colleagues who were unfamiliar with it. Programming in .NET I usually tried to use frameworks that avoided the terms, such as NSubstitute where you create an object by substitution:

var format = Substitute.For<IFormatCode>();

I haven't used it in a while but I remember that Rhino Mocks asked for ridiculous code like

var format = MockRepository.GenerateStub<IFormatCode>();

(Which one is it, a Mock or a Stub? And: Does it matter?)

I recommend Gerard Meszaros excellent book XUnit Test Patterns, he makes more fine grained distinctions between different aspects of testing. I liked his notion that you simply create objects that produce or react to "indirect input and output" (i.e. exceptions, opcodes, sideeffects) rather than "direct input and output" (which is what "arrange" and "assert" are checking). Mocks and stubs are only realizations of different patterns.

http://xunitpatterns.com/

cessor··on Ask HN: What is your favorite internet rabbit hole?
I enjoy rabbit holes with much less meaning, such as:

http://z0r.de/ or http://www.theuselessweb.com/

The last one is great. I once discovered this gem:

http://www.pointerpointer.com/

cessor··on Long Names are Long
Code using single letter variable names and abbreviations makes people up to 15% slower at understanding code [1, 2].

Of course it is possible to determine - bottom up - what a variable is supposed to do or that p is short for pointer, it still slows others down because it requires them to perform mental mapping. This effect, of course, depends on experience. If you write your vars like this all the time your penalty won't be as big.

[1] Influence of identifier length and semantics on the comprehensibility of source code, https://github.com/cessor/bachelor-thesis

[2] Much shorter version published in https://fg-sre.gi.de/fileadmin/gliederungen/fg-sre/wsre2016/...

cessor··on Elsevier Complaint Shuts Down Sci-Hub Domain Name
"We wish to set back society, because we want to make more money".

I use Sci-Hub all the time. I can access all papers via my library subscriptions so I actually DO have paid access to everything, but searching with and authenticating against my university library's services is slow and tedious and not feasible if I want to download many papers quickly.

cessor··on Guide to Sending Email Like a Startup
Following every step of this program is a very good way in making me avoid your product.
cessor··on Keep Out – WebGL Game Experiment
I enjoyed it. I would love if it was tougher though. Most enemies are vulnerable when you strafe away and attack them from the side. I found that out pretty quickly and for that reason didn't like the power sword, because the knockback distance makes their movements less predictable. I did the first couple of levels without buying anything and was dissapointed that I had to buy the L1 bow first.

I actually like the game for its simplicity. However, I got a little annoyed by the baby steps in the first level. I guess I can handle walking, slashing and bowing things if its not fed to me with a ridiculously tiny spoon.

The game reminds me a little of Wolfenstein. In relation to that I felt that collecting money ("loot") was cumbersome and boring. In Wolfenstein, a lot of weapons were just laying around and posed an incentive for curageous explorers. I would rather find them and be surprised, or receive them as a reward, instead of having to buy them in the same boring store behind each level.

Well done, anyway :)

cessor··on Ask HN: What do you use to draw graphs?
I use Seaborn [-> 0, 1] for both purposes from iPython notebook. I found it makes for good publishable graphics that can be fine-tuned. I usually use my own color palette.

[0, 1] http://stanford.edu/~mwaskom/software/seaborn/

cessor··on Ask HN: What would you want in an ideal web browser?
A content filter plugin, that allows me to block content semantically. Every year I feel the net gets swamped by certain events which affects my browsing experience. Halloween and the Superbowl are fairly regular, or the football world championship. People on facebook, imgur, twitter or 9gag and so on then just can't shut up about it. I would like to take notice of a new image of Pluto and then click "seen" and have the similar pictures blocked on imgur, twitter and news sites.

I would like to have this as a browser feature that I can control and easily change, rather than just a plugin. Adblock Plus would be a similar idea but I wish I could automatically teach it to block even more.

cessor··on Ask HN: Good Python codebases to read?
I would recommend reading about the Tornado WebServer. It features some nice stuff such as coroutines, async stuff.

https://github.com/tornadoweb/tornado/

cessor··on How to name things in programming
The author states:

"Most of the things programmers say about comments in code are excuses for not writing any comments at all"

This is true. Here is my excuse:

1. Follow all rules for writing good comments 2. Comment is now short, crisp and concise 3. Apply "Extract Function" refactoring, use comment as function name 4. Your comment is a compiled entity now 5. Write testcases for the function that explicitly explain corner cases and weird behavior 5. You have no comments in the code any more

This rule can be applied almost all the time, although it can be quite hard to use when global variables or wide scopes are used (e.g. 1000 line for-loops in C). Comments are either obvious or they're lying. Why would you write something that the compiler will ignore eventually?

cessor··on Ask HN: What are the books that changed the perspective of your life?
"On becoming a person" by Carl R. Rogers.

He defines Psychotherapy as merely a special case of any relationship, where the relationship will help you grow by allowing you to overcome built up incongruence. Many technical books made me change my perspective, but few were as valuable as this. Although it is easy to read, it can be quite hard to understand. It comes along as non-scientific, but many of his ideas and findings have been substantiated by empirical studies in the past.

cessor··on Yeah, it's a stopwatch
Nice one! I love a simple timer that does exactly one thing. I could do with the google analytics though.

Another example of a nice, simple timer is this app:

http://stopthismeeting.at/

A friend of mine wrote it some time ago. It shows a five minute timer that ticks unintrusively; filling a slice of the pie every five minutes. Upon being clicked it starts in the five minute segment of the current hour. Show this during a meeting, in order to track the time that you have spent discussing something that should have been in the invitation email for the meeting to begin with. :)

Maybe you too can add another view (I believe a modern term would be watchface) to your stopwatch?

cessor··on 404. PAGE Not FOUND
wild status 404 appeared: http://www.cessor.de/404
cessor··on A Quiet Defense of Patterns
The author suggests a common opinion on patterns, that I have seen violated a billion times:

> Two people with a common set of patterns find it easier to communicate [...] than those without one.

> [...] writing down our shared context lowers the barrier to entry.

In my experience this is often not the case. Patterns come along with labels and the labels will be put everywhere in a codebase. Assumptions get made and replace discussions, leading to a diluted codebase. For example Repositories will become synonyms for "thing that does database access", and will then be reduced to stupid GetByID wrappers [1]. Even worse, some patterns make entry really hard.

I used to work with C# and ASP.NET MVC. There, a view is the thing that contains markup, the thing controlling the input is the controller. Then I started using Flask and was utterly confused, since there the functions with the @app.route decorators, which are run on the server and then return markup rendered via jinja2 templates, are called view functions. In Django this is understanding is the same.

I was really baffeled. I could not reapply my understanding of the patterns across these domains. This is just one explicit example that I wrote about in my blog [2], but I really made the general experience that patterns replace or inhibit discussions, rather than improving communication and understanding.

[1] http://philcalcado.com/2010/12/23/how-to-write-a-repository/

[2] http://www.cessor.de/on-patterns

cessor··on A Quiet Defense of Patterns
I felt that your comment speaks to me - I had a similar understanding a couple of years ago. In their book "Growing Object Oriented Software, Guided by Tests", Nat Pryce and Steve Freeman describe values and objects, *(Values in the sense of Value Objects in Evans' DDD)

> The confusion is, that both concepts are implemented by the same language construct: Classes

This made me think. In C# this statement is somewhat untrue, since you have structs that have value semantics (value equality). But why are there no other concepts within the language that help you from reinventing the pattern wheel?

For example, I had seen the singleton pattern quite frequently in a codebase I worked on, with the label leaking into the class name. But why is it that you have to write:

    public class DatabaseConnectionSingleton { ... }
and then deal with all the static stuff (i.e. x.Instance()) rather than

    public singleton DatabaseConnection { ... }
Like this, you could easliy use standard stuff:

    new DatabaseConnection()
and the runtime would simply return the same instance. This would keep people from reinventing the mechanism. Like IoC / DI built into your language...

[1] http://www.amazon.co.uk/Growing-Object-Oriented-Software-Gui...

cessor··on Yalz77: an LZ77 compression algorithm designed for code simplicity and clarity
Sorry, but no cigar from me. I like the code and it is well written, but I think clarity means something different to me.

"Clarity" does not come from putting comments and blank lines in the code. Properly naming your variables and functions will clear things up. For example fnv32a is a pretty poor name for a function, as it is not even pronouncable.

A good rule of thumb is to move the explanations in the comments to become the names of your functions.

For example "fnv32a" could be named "compression_quality_hash" I doubt that this is really the perfect name, but at least it is what the comment says; you get the idea.

Even if the authors of an original paper used names like this in their definition of an algorithm (so an argument for the poor names would be to stick to the reference impl), your code and your contribution could be to make things clearer, rather than sticking to their poor, mathematical naming schemas.

However I really like the interface of the algorithm. While your code looks quite complicated on the inside, it is nicely usable from the outside; much like a wristwatch.

Random Examples of variables that I would rename:

https://bitbucket.org/tkatchev/yalz77/src/a9a8fab4ba706b5633...

https://bitbucket.org/tkatchev/yalz77/src/a9a8fab4ba706b5633...

cessor··on Predominantly
Really nice way to discover music. One problem though: The colorpicking works with my touchscreen, but not with my mouse, TP w510..., Chrome
cessor··on How to mod a toaster to control PC games [video]
I like how he pretends that Windows actually contains preinstalled toaster drivers (with the default device icon in Windows actually being a toaster)...

https://www.youtube.com/watch?v=vI7tWd7B3iI#t=92

    "The factories that manufacture the toasters also run windows."
http://superuser.com/questions/792607/why-does-windows-think...
cessor··on How to Send Email Like a Startup
I believe I had mentioned this before - and received a lot of downvotes for it: I, as a user, wish not to be bothered with emails.

I often just briefly want to see what the fuzz is all about. The app then "tricks me" into providing them with an email address, by pretending they need this as an identifier, most of the time in order to create an account. They then feel free to send me "Greg from blahblah app"-Emails.

To me, this is spam. It is an email I do not want. To me there is no difference between a random spammer who wants to sell fake viagra and Greg from blahblah app, who wants me to use his cloud-driven javascript thingy.

I believe there is a role missing, in the view on customer relationships. Just because I am looking at things in your store doesn't mean I want to be treated as a customer already. I believe there should be a differentiation between somebody who already bought something and somebody who is about to. Aggressively sending email at any chance isn't the way to make this transformation, imho.

cessor··on Show HN: Howm – A Vim-like tiling X11 window manager
Harvey, your code looks very nice and expressive with appropriate comments. There is some space for improvements on this matter (well, there always is) but I found it very good to read and easy to follow!

Really well done, keep up the good work!

cessor··on Ask HN: Bayesian Statistics – where do I start?
Thank you, I will give it a try, I enjoyed the think-x series for a while. You all have been helping me out in a great way, I will start here...
← PreviousPage 3 of 6Next →