Docker 0.7 runs on all Linux distributions - <AUTHOR> http://blog.docker.io/2013/11/docker-0-7-docker-now-runs-on-any-linux-distribution/ <comment><USER2> A few details on the "standard linux support" part.

To remove the hard dependency on the AUFS patches, we moved it to an optional storage driver, and shipped a second driver which uses thin LVM snapshots (via libdevmapper) for copy-on-write. The big advantage of devicemapper/lvm, of course, is that it's part of the mainline kernel.

If your system supports AUFS, Docker will continue to use the AUFS driver. Otherwise it will pick lvm. Either way, the image format is preserved and all images on the docker index ([http://index.docker.io](http://index.docker.io)) or any instance of the open-source registry will continue to work on all drivers.

It's pretty easy to develop new drivers, and there is a btrfs one on the way: [https://github.com/shykes/docker/pull/65](https://github.com/shykes/docker/pull/65)

If you want to hack your own driver, there are basically 4 methods you need to implement: Create, Get, Remove and Cleanup. Take a look at the graphdriver/ package: [https://github.com/dotcloud/docker/tree/master/graphdriver](https://github.com/dotcloud/docker/tree/master/graphdriver)

As usual don't hesitate to come ask questions on IRC! #docker/freenode for users, #docker-dev/freenode for aspiring contributors.

<comment><USER3> does this mean that docker will run on 32 bit systems ?

<comment><USER2> Not yet, but that's coming very soon. We've been artificially limiting the number of architectures supported to limit the headache of managing cross-arch container images. We're reaching the point where that will no longer be a problem - meanwhile the Docker on Raspberry Pi community is growing restless and we want to make them happy :)

<comment><USER4> So the software in a container runs on the host-OS and there is no extra OS installed in the container?

<comment><USER5> There's a sleight of hand going on here.

The boundary between "kernel" and "libraries like libc" is very stable and doesn't change often. That means that often, the kernel distributed by Arch can work reasonably well in an Ubuntu system, and vice versa.

With that in mind: The "ubuntu" image ships the "ubuntu-glibc" and "ubuntu- bash" and "ubuntu-coreutils" and so on, but they continue to work on your Arch host because the system calls don't ever change.

You can't link (say) ubuntu-glibc into arch-bash though, which is why containers are built off of a "base ubuntu image" in the first place.

<comment><USER4> ah, so only the host-kernel is used and I have to add (distribution specific) libraries to the container?

<comment><USER5> Pretty much.

Containers come with their libraries though; you don't have to "add" anything. You'd just apt-get it within the container and it would pull down its dependencies.

</comment></comment></comment></comment></comment></comment></comment><comment><USER6> Could someone explain the logistics of Docker in a distributed app development scenario? I feel like I am on the outskirts of understanding.

My goal is having a team of developers use Docker to have their local development environments match the production environment. The production environment should use the same Docker magic to define its environment.

Is the idea that developers define their Docker environment in the Dockerfile, and then on app deployment, the production environment builds its world from the same Dockerfile? How does docker push/pull of images factor into that, if at all?

Or is the idea that developers push a container, which contains the app code, up to production?

What happens when a developer makes changes to his/her environment from the shell rather than scripted in the Dockerfile?

What about dealing with differences in configuration between production and dev? (Eg. developers need a PostgreSQL server to develop, but on production, the Postgres host is separate from the app server - ideally running PG in a Docker container, but the point being multiple apps share a PG server rather than each running their own individual PG instance). Is the idea that in local dev, the app server and PG are in two separate Docker containers, and then in deployment, that separation allows for the segmentation of app server and PG instance?

I see the puzzle pieces but I am not quite fitting them together into a cohesive understanding. Or possibly I am misunderstanding entirely.

<comment><USER7> > Could someone explain the logistics of Docker in a distributed app > development scenario?

Docker lets you build an environment (read: put together a bunch of files) for you to run an app in. It also has other features, like reducing space if lots of your apps [on the same host] use the same docker images, and networking stuff.

> My goal is having a team of developers use Docker to have their local > development environments match the production environment

You run a container. You use images to distribute files. A Dockerfile is a loose set of instructions to build the images.

The basic idea is that, any single program that you want to be able to run anywhere, you make into a container. You can run it here, you can run it there, you can run it anywhere. The whole "running it anywhere" concept comes from the idea that all of your containers are created based on the same images, so no matter what kind of crazy mix of machines you have, your containers will just work - because you're literally shipping them a micro linux distribution in which to run your application. And since all the applications are running in isolated little identical containers, you can run as many of them as you want, independent of each other, in whatever configuration you want.

You'll have a PSQL container and an App container, and you'll manage them separately, even if they share images - the changes they make get saved off to a temp folder so they don't impact each other. Your environment stays the same only as long as the containers and images you're using are the same.

There will always be differences between development and production. You have to focus on managing those differences so you have confidence that what you're shipping to production actually works. The only thing Docker really does there is make sure the files are basically the same.

</comment></comment><comment><USER8> I looked at it several times but never really got it. Can I use Docker to isolate different servers (think http, xmpp, another http on another port) on a server so that if one of them was exploited, the attacker would be constrained to inside the container? Or is it "just" of a convenient way to put applications into self-contained packages?

<comment><USER2> It's both. Everyone using docker benefits from the "software distribution" feature. _Some_ people using docker also benefit from the security and isolation features - it depends on your needs and the security profile of your application. Because the underlying namespacing features of the kernel are still young, it's recommended to avoid running untrusted code as root inside a container on a shared machine. If you drop privileges inside the container, use an additional layer of security like SELinux, grsec, apparmor etc. then it is absolutely possible and viable in production.

It's only a matter of time before linux namespaces get more scrutiny and people grow more comfortable with them as a first-class security mechanism. It took a while for OpenVZ to get there, but not there are hosting providers using it for VPS offerings.

On top of namespacing, docker manages other aspects of the isolation including firewalling between containers and the outside world (currently optional but soon to be mandatory), whitelisting of traffic between certain containers, etc.

<comment><USER9> Which namespacing features are still young? Is it still possible to evade LXC as described in this post? [http://blog.bofh.it/debian/id_413](http://blog.bofh.it/debian/id_413)

<comment><USER10> Yes, it is trivial for a root user in an LXC container to break out. One can load a kernel module from within a container, for example. LXC containers do not provide security partitioning at all.

<comment><USER2> This is just totally wrong. Any decent container configuration (including the default docker configuration) will agressively drop capabilities, preventing you from doing this, and any other script-kiddie attack.

See my other comment in this thread for a more accurate answer.

<comment><USER11> Yes, you probably need a proper kernel vulnerability, which you can exploit in a reduced environment. Not trivial, but not impossible, scanning this years CVEs some would probably be sufficient (eg ones that only nees socket access).

<comment><USER12> Can't you take advantage of a kernel vulnerability on any reduced environment, regardless of LXC?

<comment><USER10> Not in certain container types such as a full VM.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER13> I see docker come around every now and then here. I'm a smalltime developer shop, small team, small webspps. What can docker do for me?

Can this reduce the time it takes me to put up and Ubuntu installation on Digital Ocean?

Is this more for larger companies ?

<comment><USER14> You will be able to have multiple Ubuntu servers running on one Ubuntu VPS on Digital Ocean. Each of them may have some initial state (installed some software, configuration) that you will be able to spawn as separate virtual machine. The "inside" machine will consume mnimal amount of memory (for running applications) and not for whole OS as in case of "real virtual machine". Also, you will be able to spawn and destroy new VMS very fast (under 1s).

<comment><USER15> What does the vm abstraction buy you vs processes? If one entity "owns" all the servers what is the draw in seperating the servers out in their own VM?

<comment><USER16> You don't have to think of them as VMs, that's just a simplification for the sake of the conversation. They're resource-isolated process groups. It's exactly the same idea as the original Unix-paradigm security approach of making each service run under a separate system-uid, but with a much more complete isolation.

</comment></comment></comment></comment><comment><USER17> EL6 users (RHEL, CentOS, SL), I've just learned Docker is now in EPEL (testing for now, but will hit release soon):

yum --enablerepo=epel-testing install docker-io

PS: make sure you have "cgconfig" service running

<comment><USER18> Very nice, I can stop updating my fork of the other rpm spec that's on github.

Any info on how it sets up networking? I see -b none in the startup... Is there some other tool that does it on EL6?

Do you know where devel talks for this rpm are happening? I did not see any mention of it in the EPEL list archives.

<comment><USER17> I am a newbie at this, but from what I'm reading you need to create a bridge called lxbr0, assign some IP on it and docker should be able to figure out IPs to use for the containers.

</comment></comment></comment><comment><USER19> Does anyone know if it is possible to set a disk quota on a container?

<comment><USER20> Interested in that too.

<comment><USER21> Me 3.

</comment></comment></comment><comment><USER22> Can anyone please tell about the overhead of Docker, compared to no-container scenario (not against a fat vm scenario)? I am a "dev" not "ops", but we might make use of Docker in our rapidly growing service oriented backend... Thanks

<comment><USER2> For process isolation, the overhead is approximately zero. It adds a few milliseconds to initial execution time, then CPU and memory consumption of your process should be undistinguishable from a no-container scenario.

For disk IO, as long as you use data volumes [1] for performance-critical directories (typically the database files), then overhead is also zero. For other directories, you incur the overhead of the underlying copy-on-write driver. That overhead varies from negligible (aufs) to very small (devicemapper). Either way that overhead ends up not mattering in production because those files are typically read/written very unfrequently (otherwise they would be in volumes).

[1] [http://docs.docker.io/en/master/use/working_with_volumes/](http://docs.docker.io/en/master/use/working_with_volumes/)

<comment><USER22> VEry good answer, thank you. So in my scenario, I was thinking of packaging our service apps (which run on JVM) and if I make sure that the OS has jvm and all the needed stuff ready. Shipping a package and deploying the service, is just transferring the Docker container and run it. Which happens to be using the same process models as the OS itself. So in other terms, Docker is a convenience layer (a glorified FS abstraction). I am not saying this to undermine the utility, just trying to figure out if it solves more problems then the complexity it brings (which is one more moving part in your toolchain)

</comment></comment></comment><comment><USER23> Will it be possible to run Docker containers on Android? I may be asking this incorrectly. So correct me if I have a mistake. My question might be "Will it be possible to run Docker containers on Dalvik VM?" or "Can I run an Android in Docker container?"

<comment><USER2> I have not tried personally, but I think it should be possible. People already do crazy things with Docker :) For example: [http://resin.io/docker-on- raspberry-pi/](http://resin.io/docker-on-raspberry-pi/)

</comment></comment><comment> T-zex Is it possible to have multiple instances of the same app running in Docker containers and having readonly access to a "global" memory linked file? What I'm trying to achieve is having sand-boxed consumers having access to some shared resource.

<comment><USER24> Have you try to use the mount option/instruction to do so?

<comment> T-zex Haven't tried anything yet. Just wondering if this is an idiomatic use case to grant container access to global resources.

<comment><USER2> Yes, it's idiomatic, but typically you will use shared filesystem access rather than shared memory. By default nothing is shared, and you can specify exceptions using shared directories called "volumes": [http://docs.docker.io/en/master/use/working_with_volumes/](http://docs.docker.io/en/master/use/working_with_volumes/)

</comment></comment></comment></comment><comment><USER25> Hey,

docker newb here. Can I easily put my own software in it? I've got this c++ program that has a few dependencies in ubuntu.

<comment><USER2> The easiest way is to add a Dockerfile to your source repository, and use 'docker build' to create a container image from it.

Documentation link: [http://docs.docker.io/en/master/use/builder/](http://docs.docker.io/en/master/use/builder/)

<comment><USER25> Hmm. this is good. but my build environment is kind of wonky.

Can I just hand it a .tar.gz and say, put it in /usr/asdf and let it run? What about python scripts? Maybe I just give it a location to an RPM? like in this document?

[http://docs.docker.io/en/master/examples/python_web_app/](http://docs.docker.io/en/master/examples/python_web_app/)

<comment><USER2> You can use the ADD build instruction in the Dockerfile to upload any part of your source repo into the container. Then more RUN instructions to manipulate that, for example compile the code etc.

Here are 2 examples:

[https://github.com/steeve/docker-opencv](https://github.com/steeve/docker- opencv) [https://github.com/shykes/docker- znc](https://github.com/shykes/docker-znc)

</comment></comment></comment></comment><comment><USER26> This is crazy talk of course, but I wonder if there'd be some way to use rsync or git to support distributed development of images the way git does with code?

I mean, it'd be neat to be able to do a "pull" of diffs from one image into another related image. Merge branches and so on. I don't know, possibly this would be just too unreliable, but I would have previously thought that what docker is doing right now would be too unreliable for production use, and lo and behold we have it and it's awesome.

<comment><USER2> It wouldn't be the craziest thing people do with docker:

[http://blog.bittorrent.com/2013/10/22/sync-hacks-deploy- bitt...](http://blog.bittorrent.com/2013/10/22/sync-hacks-deploy-bittorrent- sync-with-docker/)

[http://blog.docker.io/2013/07/docker-desktop-your-desktop- ov...](http://blog.docker.io/2013/07/docker-desktop-your-desktop-over-ssh- running-inside-of-a-docker-container/)

There has been discussion of taking the git analogy further. We actually experimented with a lot of that early on ([https://github.com/dotcloud/cloudlets](https://github.com/dotcloud/cloudlets)) and I can tell you it's definitely possible to take the scm analogy _too_ far :)

I do think we can still borrow a few interesting things from git. Including, potentially, their packfile format and cryptographic signatures of each diff. We'll see!

Here's a relevant discussion thread: [https://groups.google.com/forum/#!msg/docker- user/CWc5HB6kAN...](https://groups.google.com/forum/#!msg/docker- user/CWc5HB6kANA/oHyw-rgjJoYJ)

</comment></comment><comment><USER27> Unfortunately it looks like the documentation has not been updated yet...

So much for feature #7. Documentation should be part of the development/release process

<comment><USER2> Documentation is definitely part of the process :) Apparently the documentation service triggered an incorrect build overnight. Until we fix that you can browse the latest version of the docs from the master branch: [http://docs.docker.io/en/master](http://docs.docker.io/en/master)

<comment><USER2> Quick update: until we figure out what broke the build on our ReadTheDocs.org setup, we switched the default branch to master. So if you visit [http://docs.docker.io](http://docs.docker.io) you will get the bleeding edge build of the documentation, which happens to be accurate since we released it this morning :)

Sorry about that. One more lesson learned on our quest to ultimate quality!

<comment><USER28> The Arch Linux instructions are still wrong; they say that aufs3 is required but it isn't anymore. [http://docs.docker.io/en/master/installation/archlinux/](http://docs.docker.io/en/master/installation/archlinux/)

Is the warning "This is a community contributed installation path. The only 'official' installation is using the Ubuntu installation path. This version may be out of date because it depends on some binaries to be updated and published." still true? Fedora also has this warning (and no instructions). The "Look for your favorite distro in our installation docs!" link does not give me up-to-date instructions for any of my favorite Linux distros. I can't even see where in that installation documentation it says how to install from source code on generic Linux. What am I missing? (Of course I can get the source code and build it, but I want the documentation to be great :-D)

<comment><USER2> You're right, the arch docs need some updating. Pushing that to the queue. Thanks!

<comment><USER28> Yay! You should have have a section on installing from source too. This is part of doing open-source well.

<comment><USER2> We explain how to setup a dev and build environment here: [http://docs.docker.io/en/latest/contributing/devenvironment/](http://docs.docker.io/en/latest/contributing/devenvironment/)

I guess we could reference that it the install docs.

</comment></comment></comment></comment></comment></comment></comment><comment><USER29> Nice to see Docker 0.7 hit with some very useful changes.

I see lots of people are getting some generic Docker questions answered in here, and want to ask one I have been wondering about.

What is the easiest way to use dockers like I would virtual machines? I want to boot an instance, make some changes e.g. apt-get install or edit config files, shutdown the instance, and have the changes available next time I boot that instance. Unless I misunderstand something, Docker requires me to take snapshots of the running instance before I shut it down, which takes an additional terminal window if I started into the instance with something like docker run -i -t ubuntu /bin/bash. I know there are volumes that I can attach/detach to instances, but this doesn't help for editing something like /etc/ssh/sshd_config.

<comment><USER30> There's no need to manually take snapshots, docker does this automatically every time you run a process inside a container. In your example of running /bin/bash, after you exit bash and return to the host machine docker will give you the id for the container which has your changes. You can restart the container or run a new command inside it and your changes will still be there. If you want to access it more easily later, you can run 'docker commit' which will create an image from the container with a name you can reference. You can also use that new image as a base for other containers.

This is great for development or playing around with something new, but the best practice for creating a reusable image with your custom changes would be to write a Dockerfile which describes the steps necessary to build the image: [http://docs.docker.io/en/latest/use/builder/](http://docs.docker.io/en/latest/use/builder/)

<comment><USER29> Yes, my goal here is ease of playing around with something new. I would setup a dockerfile after I knew exactly what setup I wanted.

You're right, I misunderstood what docker was doing when shutting down the container. Seems like I can start and reattach just fine. Here is an example workflow for anyone curious:

        root@chris-VM:~# docker run -i -t ubuntu /bin/bash
        root@0a8f96822140:/# cd /root
        root@0a8f96822140:/root# ls
        root@0a8f96822140:/root# vim shouldStayHere
        bash: vim: command not found
        root@0a8f96822140:/root# apt-get install -qq vim
        ...<snipped>...
        Setting up vim (2:7.3.429-2ubuntu2) ...
        root@0a8f96822140:/root# vim shouldStayHere
        ...Not exactly necessary, but I added a line to the file so I could identify it...
        root@0a8f96822140:/root# exit
        root@chris-VM:~# docker ps
        ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS
        root@chris-VM:~# docker ps -a
        ID                  IMAGE               COMMAND                CREATED              STATUS              PORTS
        0a8f96822140        ubuntu:12.04        /bin/bash              About a minute ago   Exit 0
        root@chris-VM:~# docker attach 0a8f96822140
        2013/11/26 10:29:41 Impossible to attach to a stopped container, start it first
        root@chris-VM:~# docker start 0a8f96822140
        0a8f96822140
        root@chris-VM:~# docker attach 0a8f96822140
        ls
        bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  selinux  srv  sys  tmp  usr  var
        root@0a8f96822140:/# cd /root
        root@0a8f96822140:/root# ls
        shouldStayHere
        root@0a8f96822140:/root# cat shouldStayHere
        Hello World!
        root@0a8f96822140:/root#

So, if I did some heavylifting to set something up and wanted to keep this as a base for later work, now I would do e.g. docker commit a8f96822140 <some identifier>

<comment><USER31> Yes, I wrote a long wordy response and neglected to mention "docker start" which is a perfectly good way to come back to a stopped container after the first "docker run".

I prefer to never keep anything important in a stopped container (for very long) without committing it back to an image, and I don't like dealing with numeric ids.

Recently (it looks like you don't have this change yet) docker added the automatic naming scheme giving every container a random name of some "color_animal" pair which I think reinforces the point, stopped containers are not a place to store meaningful/persistent state information for very long.

This mishmash gets run almost every day on my docker hosts to clean up after terminated experiments:

docker ps -a|egrep -v 'ID|Up'|awk '{print $1}'|xargs docker rm

Beware, it will delete all of the stray containers you've ever created before that are now stopped!

<comment><USER29> Indeed, if I had done anything important I would certainly commit the changes to the container. It's great to have some version control for my playful discovery.

The changes you mention sound nice. It's no surprise I don't have them:

        root@chris-VM:~# docker version
        Client version: 0.5.3
        Server version: 0.5.3
        Go version: go1.1

It was the easiest VM I had access to at the moment of posting. I should update the docker in there.

I have used docker ps -a | awk '{print $1}' | xargs docker rm a couple times to clean up after playing around. I was slightly annoyed that it tried to docker rm a (nonexistent) container with the id ID. Thanks for reminding me to throw a egrep -v 'ID|Up' in front of awk.

<comment><USER31> If you hadn't heard, the new release of docker no longer uses "color_animal" but "mood_inventor"... "the most important new feature of docker 0.7"

[https://github.com/dotcloud/docker/pull/2837](https://github.com/dotcloud/docker/pull/2837)

tl;dr They are going to pick a new pair of things for every major release of Docker. This is meant to let you keep track of more containers over a long time. Apparently you are in fact meant to keep them around if they're still in working order, and remember them "by ID" or by name.

</comment></comment></comment></comment></comment></comment><comment><USER32> So, I assume that if you aren't using AUFS then you don't have to deal with potentially bumping up against the 42 layer limit? Or does this update also address the issue with AUFS?

<comment><USER2> The 42 layer limit is still there... But not for long! There is a fix underway to remove the limitation from all drivers, including aufs.

Instead of lifting the limit for some drivers first (which would mean some images on the index could only be used by certain drivers - something we really want to avoid), we're artificially enforcing the limit on all drivers until it can be lifted altogether.

If you want to follow the progress of the fix: [https://github.com/shykes/docker/pull/66](https://github.com/shykes/docker/pull/66)

(This pull request is on my personal fork because that's where the storage driver feature branch lived until it was merged. Most of the action is usually on the main repo).

<comment><USER33> One thing I've been wondering is whether the 42 limit was related to performance considerations. If yes, I actually somewhat like it - I'm a proponent to making systems behave in a way that they won't come around and bite you. Will a container based on, say, 200 layers still load and run with reasonable performance?

<comment><USER34> That depends on the backend a bit i guess. devicemapper "flattens" each layer, so the depth should have zero effect on the performance.

For aufs, I have no real data, but I assume that a 42 layer image is somewhat slower than a 1 layer image.

The fix for going to > 42 layers is to recreate a full image snapshot (using hard links to share file data) every N layers, so the performance would be somewhere between the performance between 1 and 42 layers depending on how many AUFS layers you got.

<comment><USER33> Doesn't 'flatten' mean that there's going to be a tradeoff between IO performance and storage size? If that's the case I'd like to have some control over what happens, at least with one of the implementations. Say, during development of a Dockerfile just use the layers as before, potentially without any depth limits, but when an image is ready being able to call 'flatten' manually.

Some background: Using 0.65 it took me several days to develop a Docker image with manually compiled versions of V8, PyV8, CouchDB, Flask, Bootstrap and some JS Libraries[1]. With no 42 limit it wouldn't have taken so long since I would have had way more caching points - however I'd also be afraid about performance.

[1] the image is available on the repository as ategra/xforge-dependencies. I can upload the Dockerfile to github if anyone is interested.

<comment><USER34> "flatten" is a simplification, what I mean is that the devicemapper thin provisioning module uses a data structure on disk that has a complexity that is independent of the snapshot depth. I did not mean that the Docker image itself is somehow flattened.

I don't think there will be any performance problems with deep layering of images, either on dm or ads.

<comment><USER33> That's some great news, thanks a lot for the heads up and the great work you guys are doing! I'm really looking forward to what Docker and its ecosystem is becoming - I think it's already quite obvious that it will revolutionize the way people think about linux application rollout - both from the user- as well as the application developer's perspective. It might even make 2014 _the year of the linux desktop_ ;-).

</comment></comment></comment></comment></comment></comment></comment><comment><USER35> The links feature will make deploying sites a million times easier.

</comment><comment><USER36> You guys are awesome, just awesome!

I was pretty sure that the requirement for AUFS would stick for a long time -- I was resigned to use a special kernel. But again, you folks surprise me!

You guys just rock!

</comment><comment><USER37> Hmm, not sure I'm understanding #1 correct. Can I install it on, let's say, Debian without Vagrant/Virtualbox now?

I can't find the info in the docs.

<comment><USER38> They don't have a package repository for Debian yet, but I think you should just be able to make/install it.

</comment></comment><comment><USER39> For local development, I use Vagrant + Chef cookbooks to setup my environment. The same Chef cookbooks are used to provision the production servers.

It's not clear to me how I can benefit from Docker given my setup above. Any comments?

<comment><USER40> Docker really replaces the need for Chef in a sense. You don't need Chef for configuration of your container, because ideally your container should be saved in an image which you use to deploy. This keeps things consistent between your dev environment, staging and production.

Chef is based on re-running the same commands with various different options depending on the environment, and even without any thing in the cookbooks/attributes/environments changing, Chef still cannot guarantee that this run will produce the same results as a run that happened yesterday, simply because it isn't like an image.

<comment><USER41> I'm new to these tools. Given your explanation, how does Docker replace a packaged Vagrant machine[0] with all the software already pre-installed (without using Chef)?

[0] [http://docs.vagrantup.com/v2/cli/package.html](http://docs.vagrantup.com/v2/cli/package.html)

<comment><USER42> Much lighter weight. Instead of hosting an entire operating system you just host the application.

Imagine spinning up your db instance vm, your web tier vm, your load balancer vm... etc.

Unless you have a ton of ram it isn't going to happen. With docker you can run containers that mimick a very very large infrastructure on your laptop.

<comment><USER43> What about using Vagrant with the [vagrant-lxc plugin]([http://fabiorehm.com/blog/2013/04/28/lxc-provider-for- vagran...](http://fabiorehm.com/blog/2013/04/28/lxc-provider-for-vagrant/))?

</comment></comment></comment></comment></comment><comment><USER44> Can someone please explain what docker does and brings to the table, what all the fuss seems to be about? I've looked into it several times and really can't tell from any of what I've found.

</comment><comment><USER45> I have heard / read about docker for quite some time, yet it is unclear still how this is useful.

Let me ask a direct need I have, would docker allow me to use newer c++ compilers on redhat so I can code in c++11?

</comment><comment><USER46> Annoying typo in the submission's title, it would be awesome if someone could fix that.

It's just s/distrubtions/distributions/, obviously.

<comment><AUTHOR> Fixed. Sorry about that.

<comment><USER47> Also, when writing about -p option (e.g. -p 8080:8080), you could choose different port numbers for container and host, so we know the latter is for the host and former is for container.

<comment><USER2> That's a good point, thanks. _Note: the author and HN poster are 2 different people, but evidently we both check comments :)_

</comment></comment></comment></comment><comment><USER48> It doesn't run on a typical OpenVZ VPS.

Is there any alternative for separating apps on a single VPS?

<comment><USER40> Thats because you can't really use the tools the kernel provides which docker uses while in an OpenVZ container.

</comment></comment><comment><USER49> It looks like the Ubuntu packages are not there? (apt-get cannot find them)

</comment><comment><USER50> getting excited about docker and lxc in general..

</comment><comment><USER51> i like docker \o/</comment>


Gut bacteria regulate nerve fibre insulation - <AUTHOR> https://www.theguardian.com/science/neurophilosophy/2016/apr/05/gut-bacteria-brain-myelin <comment><USER2> I love that science is catching up to the intuitive understanding of "you are what you eat". The western diet often takes a reductionist mentality that food can be reduced into macronutrients and micronutrients, and recombined in whatever form to generate "nutritious food". In this approach, a carb = a carb (plus/minus some fiber). However, now that we are exploring the microbiome, we are beginning to understand things like fiber playing a huge role in shaping our gut colonies, which can very heavily affect our lifestyle. I hope to see more of this science enter the mainstream!

</comment><comment><USER3> [http://www.nature.com/tp/journal/v6/n4/full/tp201642a.html](http://www.nature.com/tp/journal/v6/n4/full/tp201642a.html)

</comment><comment><USER4> The genetics lab I used to work for spent a lot of time focusing on the microbiome and microbiota, You would be amazed at how much they affect, and I will not be surprised to see more papers similar to this one coming out as sequencing costs drop.

In bioinformatics though, it's going to become about sifting through tons of data more than the sequencing tech. (imho: just a sysadmin)</comment>


Utah gets a Startup Incubator - BoomStartup - <AUTHOR> http://boomstartup.com/

<comment><AUTHOR> I just found out about this last night at Launch Up (launchup.org) and it seems pretty interesting. I'll probably check out their first "Meet the Mentors" meeting this Friday.</comment>


Heart Attacks are Common Amongst Silicon Valley Workers - <AUTHOR> https://terminalhorror.blogspot.com/2019/06/heart-attack-common-disease-among.html <comment><USER2> I wish this headline was retitled because the article is so much more about how detached we've become from instinctive necessity. Drinking up to a gallon of water a day and all these crazy things we do.

</comment><comment><USER3> Pretty sure that heart attacks are 'common' amongst pretty much everyone, except possibly a few non-western sub-poverty people who never get old enough to worry about heart attacks.

<comment><USER4> Not common among extreme-low-carb diet people.

</comment></comment><comment><USER5> I see an assertion, but no numbers.</comment>


How do you act on all that product feedback? - <AUTHOR> http://www.gabrielweinberg.com/blog/2011/06/how-do-you-act-on-all-that-product-feedback.html

<comment><USER2> Brilliant. The gem for me is the statement that a ton of small decisions creates a defensible moat perhaps even more formidable than adding features. (Biased opinion: After 20,000+ hours of work, Stormpulse is an example of this.)

<comment><USER3> Yeah.

When I built delicious there were literally hundreds of competitors, many starting as literal clones. Because they didn't understand the reasoning, they couldn't make the same decisions that I could.

</comment></comment><comment><USER4> I think that every successful product requires a strong vision. Start out small (MVP) and build on that vision. If you follow that path implementing "small" user requested features will most of the time be straightforward and will actually build on your initial vision of the final product.

However, sometimes you have to ignore some requests (big or small) if they aren't in line with what you want the product to eventually be.

One last thought is pivoting - which only select companies have managed to pull off - and have profited incredibly (Flickr, Groupon, PayPal). While it's not necessarily on topic, it's important to listen to user feedback and look for potential in every single idea (no matter how silly they might be).

<comment><USER2> What if no one ever asks for the most important feature? We get a lot of feature requests, but the number one feature we focused on: "When the map loads, is it easy to know where the nasty weather is?" No one ever asked for that, but it's the killer feature.

<comment><USER5> "If I'd asked my customers what they wanted, they'd have said a faster horse" - Henry Ford

</comment></comment></comment><comment><USER6> Chris Anderson (Wired editor) in his book "Free" had one strategy - to never write any feedback down on paper. By never writing it down, you only remember the things that get repeated by your customers frequently, and you just forget everything else.

It's kind of like a high pass filter for feedback, with a very cheap implementation cost ;)

Obviously this tip won't suit everyone all of the time so don't flame me. I thought it was an interesting idea though. It's a really good book, btw; some good advice and stories if you are building freemium web apps.</comment>


Show HN: Simple hint – a new and improved CSS-only tooltip - <AUTHOR> http://catc.github.io/simple-hint/

<comment><USER2> Nit-pickey feedback: "a lot" is 2 words.</comment>


Signs that you're a bad programmer (2012) - <AUTHOR> http://www.yacoset.com/Home/signs-that-you-re-a-bad-programmer <comment><USER3> One of the unstated, or subliminal purposes of these kinds of ideas is to act as an emotional "vent." Its social purpose in the programmer community is to present a target for the release of "justified" emotional aggression.

Other fields and other kinds of social groups have them in their own contexts.

One of the things that such sets of ideas produce, in sufficiently large populations and sufficiently complicated contexts, are _false positives_. That is to say, you will tend to hastily pattern match your object of justified scorn. You will tend to detect more of them than actually exist. (This is how human beings are wired up.) What's more, you will conflate highly salient attributes with actual symptoms of such. Being female, or a member of a certain ethnic group, or being "too old" then becomes a sign of the insidious danger.

The thing to remember, is that extraordinary situations require extraordinary causation. Such individuals do exist, but there must be something or someone very powerful propping them up. They could be very good at manipulating people. They could have been granted a sinecure by someone very powerful. Most often, they are the unwitting beneficiaries of pathological organizational policies.

So how is a diligent rationalist supposed to approach this? Remember that you are wired up to produce false positives. Be self aware of your social animal instincts that will tend to have you use the subject of your suspicions as an object of scorn. Look diligently for "extraordinary" causation.

Most of all, don't judge prematurely.

<comment><USER4> Yep, agreed. There's an abundance of this kind of scornful thinking in the tech world. I figure it's mostly a subliminal attempt by programmers to convince themselves that they're smarter than other people.

That being said, the article seems to be pretty well-written and does have some good info about anti-patterns once you get past its title. Also, it proposes remedies to these anti-patterns and bad habits which are useful.

<comment><USER3> _I figure it 's mostly a subliminal attempt by programmers to convince themselves that they're smarter than other people._

That's when you've let your social animal instincts get the better of you as a sentient lover of knowledge. What will truly distinguish one as an exceptional programmer is an ability to shed prejudices, analyze, and listen well, not being on top in the geeky version of the primate dominance game.

</comment></comment></comment><comment><USER5> One time, I was helping a friend of mine work on Javascript (js) skills. We cycled through all the basic sorting algorithms to practice js best practices and help with understanding computation complexity issues.

On one sorting algorithm, Can't remember which one ATM, involved recursion. It was pretty simple. My friend couldn't understand the nature of the problem because he didn't have a instinctual comprehension of recursion. I threw together a Visio of the process and walked him through the blocks one by one. He still couldn't wrap his mind around it. He started to berate himself and I could tell he was giving up on his dream. I told him to keep trying. To keep spending the time on places like HackerRank. He did.

8 months later, he landed a job as a js full stack programmer. Not a senior level position, but a damn good one. I'd seen his work before his interview and it was good. He had a command of all the major frameworks and he was observing all major js design patterns while avoiding idiotic anti-patterns. His code was clean and easy to read.

IMO Pointing out that someone APPEARS to code like a loser is a petty playground tactic of someone who has a serious ego issue. Taking someone by the hand and helping them through the hurdles so they can become a better programmer is the solution. I can't imagine how my friend would have reacted if he had read this petty article while he was trying so hard to become a decent programmer. He may very well have given up. That's not acceptable.

There are only people who give up and people who refuse to concede defeat. Ranting on a website about bad programmers is giving up.

<comment><USER6> I find the article really helpful, to be honest. I am not a good programmer (it's not my job, I am a physicist); my code runs and does all I need such as automatically control my instruments so I can do someting else, evaluate my data and make plots. I can also use other people's code, though I sometimes code by google.

Since code quality is by no means a qualifier for our work and most people don't really care, it's hard to become better beyond just knowing the languages better. Programming patterns? Ha, I just use all languages the same way. This article tells me where my weaknesses lie, which helps a lot, because I can only google things I have some notion of.

It's not just ranting, there are detailed lists of what could be not-good and how to fix it. The only thing potentially offputting is the title, really. (Might help that it's not my job to be good at coding, just a bonus.)

</comment></comment><comment><USER7> I'm not a big fan of the language used, w.r.t. the dichotomies between a "good" programmer and a "bad" programmer. There are certainly challenges for junior developers that are mentioned in this article (and I agree with most of it), but I wouldn't consider those people who do it "bad", rather "inexperienced". This may be a mere nuance, but it's not something that should be perpetuated. We all have our challenges and we are all learning to do better in our work.

In reading this article, I don't think any developer purposely does any of these things and if they do, they aren't "bad programmers", but just developers who are still learning.

It seems that the intent of the article is good-natured in that it's pointing out certain issues with code and how to remedy them, but calling people bad at their craft so that they read the article is a bit strong.

<comment><USER8> I would prefer to "inexperienced" as well.

Some junior engineers are apparently talented. They would make some of the mistakes. Even if people point out the mistake to them, they might not fully get the reasoning behind the better approaches. It is intrinsically part of the growth, to experience, to learn from mistake, to understand deeper.

Some junior engineers are lack of potential. It is a fact, in every profession. They are not good at programming, but might be good at other things. If one can afford, one can help them to gradually transit to other positions, like product managers, data analysts, etc. It could sound stunning. Some of them are actually good materials to be managers.

One of the best product managers I worked with was an engineer before. He said he was simply not good at it, and not interested, either. His contribution as a product manager was much much higher than as an engineer.

<comment><USER9> My team leader doesn't think in sets, and it gets a bit frustrating when he describes queries like and imperative program with lots of ifs, and no order to them.

</comment></comment></comment><comment><USER10> Congratulations on fomenting that impostor syndrome.

While the the text contains valid anti-patterns its style is non-helpful. People should not be put down but encouraged. People will notice sooner or later if they are not fit for a field by themselves. The only benefit of berating someone for lack of skills is a temporary catharsis for the one doing the berating while the person at the other end pays a psychological cost of a kind or another unless he's really mindful.

Berating command-voice is excusable in a heated argument but maintaining this voice throughout a long writing is stylistically a very poor choice, IMO. This just discredits the authors voice as that of an infantile jerk.

<comment><USER11> The problem is the article contains actually useful advice for newbie/intermediate programmers, but it is framed in such a way it mostly appeals to experienced programmers with a superiority complex.

<comment><USER12> If you're experienced but not superior, you haven't been learning anything from your mistakes along the way. I thought the article was extremely nostalgic. An experienced programmer who can't spin up a funny story about the time he learned his lesson about bounds checking or implementing regexs the hard way is either not really an experienced programmer, or what is known as a "liar", or most politely has an extremely bad memory.

As a concrete example of #2 poor understanding of the programming model, in the old days we had a saying that you can write fortran in any language, and it was not exactly a compliment. I guess a modern politically correct analogy would be the ability to write perl in any language. Any programmer who hasn't made the mistake of writing code style from their language X in their new language X+1 is either inexperienced or outright lying or at best is merely forgetful of doing it.

The article is poorly formed in that the phases explanation from the second "programming model" discussion actually applies to the entire article, with most of the article being examples of "phase 1". If you're at "phase 0" it could be helpful to see a roadmap, and if you're at a higher phase its going to be somewhat nostalgic.

</comment></comment></comment><comment><USER13> In short this article looks at aspects of programming and says if you're bad at each aspect you're probably bad at the sum of them. I'm not sure what the purpose is... you can figure out more directly whether you're a bad programmer by comparing the code you produce to that of your peers.

Aside from that the made up terms are annoying. It would be more readable if he used

      voodoo code => dead code
      bulldozer code => high cohesion subroutines
      pinball programming => unreliable code

I can't think of anything good to say about this article.

<comment><USER14> > I can't think of anything good to say about this article.

Yeah, it certainly reads as very smug (at least to me). I think it's an attempt at humour that just comes off as condescending; after all, we've all been beginners at some point. I don't think it's very useful for 'bad' programmers either, because it doesn't go into much depth or explanation, so really what's the point? To make us all feel good that we don't do these things? (some of which are debatable anyway)

</comment></comment><comment><USER15> > 5\. Difficulty seeing through recursion

It may be a function of the code I work on but I generally avoid recursion unless I'm _really_ sure about the bounds of my input, which is rare. Few other things can take a smoothly operating service and hard crash it because the input got just a touch too big. Worse yet, there is usually no warning as the problem approaches.

Yea, some languages have tail call optimization, but I've found it to be picky even in languages that have it. i.e. an otherwise innocuous refactoring to a method to make it look a bit cleaner, but logically identical, can all of a sudden crash the process due to TCO not recognizing it anymore. This is also the type of thing that doesn't show up in testing, but shows up immediately under production load. Recursion can make some algorithms easier to follow, but I'll take a slightly more complicated algorithm over being woken in the middle of the night due to a 'stack level too deep' exception.

<comment><USER16> I _really_ want an IDE that puts a little yellow warning thingy on the screen whenever the compiler can't TCO a function.

<comment><USER17> Clojure has a form of this in that the 'recur' special form is used for tail- calls and self-calls are used otherwise. Using 'recur' from other than the tail position is a compile-time error.

[http://clojure.org/special_forms#Special%20Forms--%28recur%2...](http://clojure.org/special_forms#Special%20Forms--%28recur%20exprs*%29)

<comment><USER18> As someone who does not (yet) do recursion and looping-by-recursion in his sleep, I deeply appreciate Clojure's hand-holding to make TC situations completely explicit.

</comment></comment></comment></comment><comment><USER19> I agree with other's statements about not judging prematurely. I feel like every software engineer I have ever run into (including and especially myself) has done some or all of these things at one point or another. We all have bad days, we all have poor judgment sometimes. Giving people the benefit of the doubt in cases of lapsed judgment seems like it would create a far less hostile work environment. If it's systemic, it's one thing... but let's try to avoid a witch hunt mentality. Everyone's going to have off days.

The only one whose legitimacy as an antipattern I would question however would be this one:

>"Bulldozer code" that gives the appearance of refactoring by breaking out chunks into subroutines, but that are impossible to reuse in another context (very high cohesion)

I think it is useful to break up complex logic into discrete methods that represent some logical step in the overall algorithm. If they're private methods, I feel like that can add to the readability of the algorithm rather than having it be in one monolithic chunk. I've seen two camps on this - <USER2> it inline vs. make private methods for discrete steps, and I find the latter to be more readable when I look through code (my own or someone else's).

There is a limit to that, of course. If you end up with a tangled tree of methods, that could work against readability... but even then, if you took that tangled tree and made it a single monolithic method, how often would that actually end up being more readable?

<comment><USER9> It depends. If the code doesn't not end up indented and reads like a script, I prefer to read one long method, rather than jumping around a hundred small methods and trying to keep the overall context in my head. I think this preference applies more to higher level scripting languages and not all the time.

</comment></comment><comment><USER20> Not sure about the article, since it doesn't seem to say anything useful, but one problem I'm having with beginners is that beginners are extremely superficial in analyzing a problem and extremely superficial in coming up with solutions and have to be told what to do in very precise words and even if you give them a list of things to do, you still have to review their work because they might have missed some of the bullet points.

This happens, I believe, primarily due to lack of experience - they haven't suffered from superficial understanding of a problem with clients rejecting their solutions, they haven't stayed too many times at 2 a.m. fixing production issues, the haven't witnessed the proverbial big ball of mud coming to life because of patched up solutions and they haven't had a project that had to be rebooted in part because of technical debt created by them. We as humans, only find out that fire burns badly once we get burnt a couple of times.

And as a senior I'm completely out of my league when it comes to educating other people - I'm totally incapable of compressing 5 or 10 years of experience into a couple of months worth of education. And for example I have initiatives, like lets do presentations on Fridays, lets do code reviews and so on. And we do them for a couple of weeks, but then we observe that nothing changes and that our productivity dropped, because communication represents points of concurrency in the development process and concurrency represents the death of parallelization, which is incompatible with really harsh deadlines. And because these deadlines are a never ending story and the seniors are overwhelmed, management kicks in to "solve the problem" and they start thinking of hiring more people, which really means even more rookies to train, because good people that have the required experience are rare. And the problem to be solved by our project is so complex, that only seniors with a deep understanding of the problem can come up with working solutions for the core pieces, the number of seniors isn't growing and these seniors also have to train people and to continuously fix the mistakes that rookies did. It's enough to say that it's turning into a nightmare.

<comment><USER9> And I bet management have no thoughts about giving you a pay rise....

<comment><USER20> Heh, that's an interesting discussion - management never has any thoughts about giving pay raises, you have to ask for it, sometimes brutally.

Developers should learn a bit about marketing, have a couple of valuable things on GitHub, have a blog, have an up to date LinkedIn, etc... then you end up being contacted by recruiters, which is cool for an ego boost and as a safety net. It's then much easier to go in and say "Hey Bob, I'm producing twice the value you expect for this salary, work conditions have changed, so I want a significant pay raise".

And sometimes you have to threaten with resignation, which doesn't really work in big companies, because there you have the "cog in the machine" mentality, with developers often being the bottom of the food-chain. But in smaller companies or when working as a consultant or in general when the "stock holders" have good visibility in the value that you bring, it's a very effective tactic.

It's also very healthy getting a pay raise especially when the stress levels are going through the roof, as it keeps you sane, because what's worse than being stressed about deadlines is being stressed while you're not being payed enough, i.e. compensation is a hygienic issue and when working in unhygienic conditions, there's nowhere to go but down. But you know, fortunately we live in times in which the supply and demand ratio is favoring us :-)

</comment></comment></comment><comment><USER21> My list is a lot shorter than this screed. A bad programmer is one who is passionless. No concern over how poor his work is, who doesn't want or care to improve.

For me, defining a bad programmer is as simple as this.

<comment><USER22> If you're good and work for a reasonably large organization, you'll be thrown into a bunch of projects. It's reasonable to be passionate for some and completely dispassionate for others.

Any project that spans over multiple stages (requirements gathering, design and architecture, coding, testing, release, bug fixing, maintenance, support) has some exciting stages (mainly design and coding) and some less exciting, especially when you're brought in to fix somebody else's bugs or work on somebody else's mess. It's also reasonable to not be super-passionate about such "opportunities".

</comment></comment><comment><USER23> If anyone hasn't read it I highly recommend the book "Antipatterns" ([http://www.amazon.com/AntiPatterns-Refactoring-Software- Arch...](http://www.amazon.com/AntiPatterns-Refactoring-Software- Architectures-Projects/dp/0471197130=)

... or just google antipatterns.

My personal pet peeve is that many programmers don't refactor nearly often nor thorougly enough. It should be natural part of the developing process. Especially with large programs you reach certain points where all encompassing refactoring is needed to simplify the code, yet many power through leading to a bloated mess.

I've found its not uncommon that even decent complex code can be shrunk 70%-80% using refactoring, code generation and config files.

<comment><USER24> Or you could just code correctly the first time...

<comment><USER23> That's like writing a book "correctly" the first time without drafting (there are a few authors that does that, but not many). Or drawing a picture without sketching.

Much of the coding process is gaining knowledge of the problem you're trying to solve and discovering patterns as you go along.

Also typically features are tacked on over time, and it reaches a point where new patterns are needed that wasn't needed before.

I agree with you in some sense though, some patterns are low-cost and high- reward in versatility & maintainability. Like using events rather than explicit references, and you should use them from the start as a matter of "good habits".

Some more overreaching patterns like factories, modules, plug-ins etc etc only make sense when the code reaches a certain scope.

<comment><USER25> William Deming famously said that when focus is on quality, quality rises and costs fall. And that when focus is cost, costs rise and quality falls.

We live in a time where we're encouraged to make mistakes. Refactoring, fail fast and often... I get the impression sometimes that we can go on failing forever and its ok. Everything is awesome. Because its fun writing code right? Just jumping in there and not giving a thought to the step after the next. Managing complexity? JAGNI. My tests passed, didn't they? And we can always refactor.

Getting it right takes discipline, research and experience. I prefer to get it right first time. Doesn't always work out as planned, but to me the need to refactor is a sign to stop and reassess what brought me to that point. And its always a result of having cut a corner somewhere.

Refactoring costs. And upfront design is about as fashionable as leg warmers.

<comment><USER23> I feel like we're talking about different things...

Continuous refactoring IS focusing on quality, it IS managing complexity. I think you've seriously misunderstood Deming if you think he stood for "Do it perfect from the start". The whole Kaizen philosophy is built on continuous improvement and elimination of waste (redundant code)

I'm not saying do a week/month/year of crappy coding and then "fix it later". Refactor continuously and as often as needed. Writing code is research.

The cost of refactoring is the greatest when you've done it too seldom. Otherwise with the right tools it's pretty efficient these days.

I see larger dangers in doing up front architect astronauting and make decisions before you've internalized all the problems.

For complex project it's of course appropriate to gather requirements, limitations etc and make a _rough_ design, but going into too much detail is setting the cart before the horse... IMHO of course.

<comment><USER25> One of the coolest things I've learnt after over 20 years in this industry is to seek first to understand, and then to be understood.

We're talking about the same thing.

</comment></comment></comment></comment></comment></comment><comment><USER26> > _" Yo-Yo code" that converts a value into a different representation, then > converts it back to where it started (eg: converting a decimal into a string > and then back into a decimal, or padding a string and then trimming it)_

I would add: "you designed a language that does these conversions implicitly as part of its evaluation semantics, and thought it was a marvellous idea."

</comment><comment><USER27> 5.3 is actually _not_ bad code, if it refers to what I think it does. Basically:

"Recursive subroutines that concatenate/sum to [...] a carry-along output variable"

Is an accumulator pattern, which is useful in converting certain types of recursive algorithms into tail recursive algorithms with can be handled much better by most compilers (and unrolled into iteration behind the scenes, which means you get clean recursive code that still won't ever run out of stack memory).

<comment><USER28> Initially this was the reason and I still do this, but it should be noted that Racket, for example, will treat the following examples exactly the same and will do just fine with the non-tail recursive example (as far as I can tell):

        (define (sum/recursive/opt lst [sum 0])
          (if (null? lst)
              sum
              (sum/recursive/opt (rest lst)
                                 (+ sum (first lst)))))

        (define (sum/recursive/non-opt lst)
          (if (null? lst)
              0
              (+ (first lst)
                 (sum/recursive/non-opt (rest lst)))))

I don't use any other variants of Scheme with any meaningful frequency, but I still use the uppermost variant because I'm just used to it.

</comment></comment><comment><USER29> signs you're too good of a programmer -

you use monads in object-oriented languages (like Python)

instead of the standard library, you get your algorithms from PDF's you have to pay a journal access fee for.

you believe in good test coverage: so do the ten thousand people who have downloaded your test suite from github.

you leave comments highlighting incorrect behavior... by the standard compiler.

you don't always formally verify that your program is optimal- sometimes you only formally verify correctness.

you're a full-stack developer, but wrote some of the layers yourself.

investors want to meet the rest of the team

<comment><USER30> > signs you're too good of a programmer - > you use monads in object-oriented > languages (like Python)

Are monads a natural fit to Python, or is this a case of "when all you've got is a hammer"...?

<comment><USER31> Python borrows list comprehensions from Haskell, but the syntax is used in a less powerful way. I wouldn't want to use non-builtin monads in a language without a compile-time type system (one of the usual advantages of monads is they save you a lot of effort testing, but this wouldn't be true in Python), but there's no reason you couldn't.

(If you want an object-oriented language with proper monads then use Scala)

</comment></comment></comment><comment><USER32> _" To get over this deficiency a programmer can practice by using the IDE's own debugger as an aide,"_

sign of bad programmer: relying on the IDE?

      'always have a security professional review the
       design and implementation.'

At first glance it reads like a list a hypothetical programmer should do, rather than what happens. For a dose of reality, read this article by Joel about the job of the SDETs at MS. [0] I don't hold MS as an example of security but Joel paints a picture of serious programmers trying to code then verify commercial software used by millions. [1]

Commerce and software demand another set of skills beyond this article. Read the counter-point: 'What Makes a Good Programmer' [http://www.southsearepublic.org/article/2024/read/what_makes...](http://www.southsearepublic.org/article/2024/read/what_makes_a_good_programmer/)

ps: Is there a way to prove the output of complex regular expressions?

[0] Joel Spolsky, 'Talk at Yale: Part 1 of 3', [http://www.joelonsoftware.com/items/2007/12/03.html](http://www.joelonsoftware.com/items/2007/12/03.html)

[1] Then there's the open-source way. How many in the OS systems community really have _' security professionals'_ review their code? OpenBSD and who else?

(various edits)

<comment><USER33> Using the tools available to you to their fullest extent, rather than doing things the hard way on purpose just to be more "hardcore", is not a sign of a bad programmer

<comment><USER34> Definitely agree, however I can also see the shortcomings of the "IDE languages". One of the nice things about non-auto-completable scripting languages is that they force you to write code that you can reason about yourself. IDEs let you write really inelegant code that you can still continue to slog through because of autocomplete.

Another big downside of IDEs is that they constrain your choice of tooling to only the IDE. There's a rich ecosystem of editors, preprocessors, templating, etc. for JS, but (for example) in iOS development you only get xcode's half- working gee-whiz features like the interface builder. In my experience, the more IDE features there are, the more of your program moves into hidden, IDE- specific automagical stuff.

So resistance that you may see to IDE's is not because someone wants to be "hardcore", but because they recognize that it is desirable for code to be able to stand on its own and be understood by a human no matter the editor used.

<comment><USER35> I especially hate IDE features that don't have a corresponding plaintext representation that you can edit. For example, a graphical layout editor which saves data into a binary blob that then requires a special merge tool which is only available in the IDE.

</comment></comment></comment></comment><comment><USER36> > 1.4 "Yo-Yo code" that converts a value into a different representation, then > converts it back to where it started (eg: converting a decimal into a string > and then back into a decimal, or padding a string and then trimming it)

An important exception: many abstractions for data passing end up creating exactly this, but are good practice if you can afford them because it means one side of the yo-yo can be changed without breaking the other.

<comment><USER37> Likewise, 1.5 "Bulldozer" aka breaking up a function into subfunctions that aren't "useable everywhere".

I can't claim I'm the best programmer, but I've used this to "simplify" programs and reduce nesting to great success.

Add to that Aspect Oriented Programming in C# by using Attributes to add/remove logging to functions is easier if stuff is broking down into parts.

Subroutines shouldn't simply be about reuse. I think that narrows their purpose too much. There is a place for code reuse. There is also a place for functions that only get called from one location.

<comment><USER38> > There is also a place for functions that only get called from one location

Do it inline. If you need it to look separate from the other context try an immediately invoked function or at worst some comment demarcation. No need to spray functionality across a file(s) when you can do it all inline, especially if it is only called from one place. I'll admit I didn't come up with this 100% myself, but having tried both ways, I really like inlining.

[http://number- none.com/blow/john_carmack_on_inlined_code.htm...](http://number- none.com/blow/john_carmack_on_inlined_code.html)

<comment><USER37> Looking at that, and considering A/B/C, I've seen myself using B most often - but I've not been afraid to use any of those.

I'm not a fan of A, because I want to see the "bigger picture" first and then dive into details (minor 1/2/3/...) as needed.

The reason for doing B vs C, in my experience with C#:

* Logging. I can add, via PostSharp ( [https://www.postsharp.net/features](https://www.postsharp.net/features) ) ( or similar extension/addons ) something as simple as `[LogDebug]` to a function and get logging goodness without having to mess with lines inside the code. PostSharp and Log4Net are my goto's.

* Simplification - Partially included above (no need for a lot of logging code with the right tools).

* Mental Gymnastics - its easier to see Step 1, 2, 3 when they are next to each other instead of pages apart.

* Scope - only the parts that get sent in via parameters are worried about, and only a single return is normally needed.

* Nesting - I've used minor functions to remove 3-4-5 levels of nesting before.

<comment><USER39> Aside from logging (and games don't typically do a lot of logging), everything you mention is covered, and argued against, in the article.

</comment></comment></comment></comment></comment><comment><USER40> Neither the good programmer nor the bad programmer portrayed here would make a good employee/consultant, the former b/c things will break while the latter b/c things will never get delivered. They say software is eating the world and I believe this is true but not b/c genius/geek programmers abound but b/c there are hordes of smart good-enough 'programmers' out there putting good enough solutions, and yes, most will not be able to write a recursive function but who cares: the solutions run and solve real problems. That being said, we must thank the gurus who put up the layers that make it posible for the makers to bring out such solutions.

<comment><USER19> I agree. It is similar to that old phrase "perfect is the enemy of good." Sometimes what an idea needs is something minimal that gets the product out there and tested, shipping and selling in the real world. Sometimes the most financially effective programming isn't elegant, but rather something quick and dirty, transitory and ugly: something meant to be used and improved on or discarded for something better if and when time allots for it in the future.

</comment></comment><comment><USER41> > 5.1 You don't use any ergonomic model when designing user interfaces, nor do > you have any interest in usability studies

Oops - _almost guilty_. Any suggested reading?

<comment><USER42> I'm guilty and somewhat afraid of going there because of what I see. Most websites and web-apps are the _opposite_ of ergonomics and I sometimes wonder if that isn't the result of the current state of UX field, that focuses on shiny things that you can sell easily instead of building tools that work. The trend I see in UX is that of dumbing-down your software and enforcing one, carefully-drawn user flow, that is pretty but not ergonomic.

I don't want to demonize the entire field - it's just a worry I have, from observation.

<comment><USER43> In my small amount of experience, reasoned application of Fitt's Law goes a very long way for ui design.

</comment></comment></comment><comment><USER44> >Incompetence with Regular Expressions

Well, method acting here I come!

<comment><USER45> I hope "being able to use an online tool" counts as competence...

</comment></comment><comment><USER46> My take on the opposite - what makes a good programmer: [http://henrikwarne.com/2014/06/30/what-makes-a-good- programm...](http://henrikwarne.com/2014/06/30/what-makes-a-good-programmer/)

</comment><comment> FLUX-YOU These articles always make me feel insecure and for some reason I continue to read them.

</comment><comment><USER47> _6\. Distrust of code_

PHP/C++/Javascript

 _4\. Dysfunctional sense of causality

Symptoms

When called on to fix a bug in a deployed program, you try prayer Your debugging repertoire includes rituals like shining your lucky golf ball, twisting your wedding ring, and tapping the nodding-dog toy on your monitor. And when the debugging doesn't work, you think it might be because you missed one or didn't do them in the right order_

Once again php ...

So it seems I am a bad programmer after all.

</comment><comment><USER48> My definition of a bad programmer is one who does not want to learn and progress. Everything else is just levels of experience.

</comment><comment><USER49> > Credit card numbers or passwords that are stored in an unsalted hash

What's the purpose of _hashing_ a credit card number? For passwords, please use a proper KDF instead of reinventing salted password hashing. While it's widely known not to build your own crypto, most people still write stuff like sha256(sha256(password) + salt).

</comment><comment><USER50> A lot of comments here take it on a political level, even if the discussed considerations are (mostly) technical. (I am personally touched by a few points in there and I understand the temptation to go that way myself.) The reasoning behind these "signs" however, is worth its weight in gold and I only hope people will remember and come back to it with cooler heads. Critique (and especially that kind performed on oneself) is almost always necessary in order to get better, even if it hurts. Seeing the objections raised, I was tempted to recommend such kind of critique only if there wouldn't be any chance of breaking you, but I can't anymore. If you are to fail - fail early, fail often.

</comment><comment><USER26> > _Using whatever syntax is necessary to break out of the model, then writing > the remainder of the program in their familiar language 's style_

Depending what you're breaking out of and into, and what your work looks like, this could be idiocy or genius. :)

</comment><comment><USER51> Previous discussions:

[https://news.ycombinator.com/item?id=3131439](https://news.ycombinator.com/item?id=3131439)

[https://news.ycombinator.com/item?id=746873](https://news.ycombinator.com/item?id=746873)

</comment><comment><USER52> Working with HTML/CSS has made me feel like I've got a Chronically poor knowledge of the platform's features. In 6 years I've not been able to form a coherent mental model of how it works that lets me actually go "oh, I need to do Foo? I'll just do Bar and Baz."

Is this a sign that I should stick to working with scheme, Python, Go, JS and other actually Turing-complete tools and my mind isn't made for layout languages? (I have the same problem with Tex.) Or is there something I can read that will finally help this make sense? Or do I just need another 4 years?

<comment><USER11> I think you should teach yourself the fundamentals of HTML and CSS. It is not magic and its not even that complicated. But if you have worked in frontend development for years, with frameworks, browsers specific workarounds and so on, you tend to miss the forest for trees. If you can program, you can definitely learn to understand layout languages.

The problem is perhaps that we are aware that programming is challenging, while layout languages are considered "easy" so never really studied in depth.

<comment><USER52> Right, that is what I'm getting at: How does one actually teach oneself the fundamentals of HTML/CSS though? Off the top of my head, I know I've read through

\- [http://learnlayout.com/](http://learnlayout.com/)

\- [http://www.html5rocks.com/en/tutorials/internals/howbrowsers...](http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/)

\- [http://htmldog.com/guides/html/beginner/](http://htmldog.com/guides/html/beginner/)

\- [http://htmldog.com/guides/html/intermediate/](http://htmldog.com/guides/html/intermediate/)

And long ago did the same with w3cschools.

But it feels like the box model only accurately describes how browsers work about 70% of the time. How do I learn to be able to predict at least 95%? I have suspected that the right approach is actually to take 50 or so layouts sketched on paper and do them. Is that actually reasonable?

</comment></comment></comment><comment><USER53> "Using whatever syntax is necessary to break out of the model, then writing the remainder of the program in their familiar language's style"

This one really rang home with me, having previously dealt with developers who worked in both .Net and PHP with frameworks that handled models very differently.

</comment><comment><USER54> What's up with 5.5?

>Your program produces output to be read by another (eg: a browser)

This is a problem?

<comment><USER55> > Your program produces output to be read by another (eg: a browser), or > implements a network protocol, and relies on the other party's software to > be significantly tolerant to spec violations

The problem isn't producing output for another program, but relying on that other problem to catch your mistakes

<comment><USER54> Ah. I parsed that sentence incorrectly.

I read it like this:

> Your program produces output to be read by another (eg: a browser), or > (implements a network protocol, and relies on the other party's software to > be significantly tolerant to spec violations)

instead of like this:

> (Your program produces output to be read by another (eg: a browser), or > implements a network protocol), and relies on the other party's software to > be significantly tolerant to spec violations

</comment></comment></comment><comment><USER56> There's a difference between being a bad programmer and bad programming.

</comment><comment><USER57> _Inability to comprehend pointers_

 _Inability to determine the order of program execution_

I don't think that pointers or mutable variables are important, when you are a pure functional or logic programmer.

</comment><comment><USER58> I'm just nitpicking here, but

> Recursive functions that don't test for a base condition

Base conditions are not necessary in lazy languages.

Example in Haskell:

        fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

<comment><USER59> Ah but that's not recursion, it's corecursion ;)

<comment><USER58> You are right. I had heard of corecursion before but never thought of it in this context. Thanks to your comment I feel like I have finally groked it :)

</comment></comment></comment><comment><USER60> The author of this piece should not fret. Soon enough computers will program themselves, and they will be vastly superior in this task to their human counterparts. Perhaps then the author will bask in the glory of programming perfection while waiting to be processed in the unemployment line.

Seriously, get over yourself. If the programmers you hire fail at their task, blame your lack of leadership, mentor ship, or hiring skills. They can't all be the A-team, can they? Learn to win with the B-team.

</comment><comment><USER61> What does homebrew "business rule engines" mean? Are there a bunch of them already made? What would be an example of this?

</comment><comment><USER62> Call me overly sure of myself, but it is painful reading this since I can relate a lot of it to my co-workers.

</comment><comment><USER63> A bad programmer is one that has worked for many years in the field and fails to help those less experienced.

</comment><comment><USER64> Still fun to read. Could anyone shed some light on author's background that led to this piece?

</comment><comment><USER65> (eg: calling the save() function multiple times "just to be sure")

Who else does this for apps with a UI?

</comment><comment><USER66> Bonus points for including remedies.

</comment><comment><USER67> Symptom: fears that the AI will (in the near future) be writing programs for us, so why bother...

Remedy: ?

</comment><comment><USER68> Ok, time to give up my career. I just realized that I'm a useless programmer.

</comment><comment><USER69> Surprisingly good. I got a good chuckle recognizing myself in some of these.

</comment><comment><USER70> _> >4\. Inability to comprehend pointers_

I love C, it's my favorite language.... but there is no way that pointers are important enough that not knowing them == bad programmer. There are plenty of good developers who've never even had to deal with pointers, even in 2012.

<comment><USER71> Well, it's necessary to the small extent that you need to know whether something is passed by value or passed by reference. And in order to understand that, you need to at least know what a pointer _is_. I don't think it's fair to say that "plenty of good developers" haven't ever needed to think about pointers. Maybe in newer languages they won't fall victim to a few of those "symptoms", but they at least need to know what they are.

<comment><USER70> Ah, so the pass-by-value vs pass-by-reference is a different topic IMHO than int *x or &x. The implementation of both I'm sure are extremely similar if not exactly the same, but I agree that if a developer doesn't understand pass-by- value vs pass-by-reference then that's a serious problem.

I'm probably showing my age that I consider the pass-by-reference concept in modern languages something that hides the concept of pointers rather than something that indicates the understanding of them. Get off my lawn, etc.

</comment></comment></comment><comment><USER72> These posts are ironic.

</comment><comment><USER73> Fantastic!

</comment><comment><USER74> yup...and this is why I stopped. because of this kind of tone that I found toxic in actual job settings but then again it's points are fairly valid to filter only the strongest programmers.

Tell engineers to come up with their expected salary in a room and they will fight and compete with each other to work for free. The rationale ones, or the 'bad' engineers seemingly walk out because they still have the sanity intact.

Interestingly enough, companies and employers know this about engineers, and would be more than happy to screw you over what you actually deserve. All they have to do is sit aside and watch the professionals sabatoge each other. They are the perfect employee. Fire them once they build the pyramid, and find slaves overseas to maintain it.

This is what I realized at the end of the day. All I care is that I turning ideas into real products that work. If these are product that I can sell on my own, even better. If my skill and experience allows me to do this over and over, then it is good enough of a skill for me. Might not be a 10x engineer but neither do I want to be involved in a gladiator matches anytime we have to build something but end up arguing over irrelevant things, and end up delivering late.

<comment><USER19> Yes, that is the worst part to me. I worked at a place once, many years ago, where a Lead software engineer came in and started what I could only equate to a turf war. He'd set people up to get them fired, call competent engineers who made a mistake out as being idiots, etc.

One time, he assigned me work - and never mentioned that someone on another team had been assigned the exact same work. He wanted to see me do it faster than the other guy so that he could fire the other guy. So when I completed it, and he used it as ammunition against the other guy (even though the other guy had done a perfectly good job it turned out). I stood there helpless and ashamed that I'd been used as a weapon for someone to tear another good programmer down.

A couple of months later, the company began to lay people off and that lead bolted for the door. I did too, but I was just glad to not have to work in such a hostile environment anymore. So much anxiety.

<comment><USER74> That is revolting. I hear a lot of nightmare stories like this. Unfortunately, I think as engineers, we are forever doomed to be treated like peasants, unless you know how to play politics, kiss ass, and move up into a manager position.

The concept of manager seems so old fashioned and backwards especially when we are now dealing with a manufacturing industry that produces nothing physical, where the concept of a product is actually just a vote of minds of all the stakeholders, engineers, customers. Having traditional managerial that were suitable for overseeing factories and suppress workers from rioting and maximizing labor output in an information based product is nothing short of censorship.

My idea of a dream team of software engineers is one where we have as little technical and business censorship as possible. It would be sort of like how day trading desks operate but we end up building one product that reflects the demands of the customers, the future market. Instead of having a manager telling you what to do or what to build, you act on information from a customer directly. This might be a tougher hybrid to find but I reckon we'll see more and more entreprengineers as traditional manufacturing corporate structures lose their appeal.

Wishful thinking but I hope some people share the same ideas and values.

</comment></comment></comment><comment><USER75> > _" Bulldozer code" that gives the appearance of refactoring by breaking out > chunks into subroutines, but that are impossible to reuse in another context > (very high cohesion)_

> _3\. Difficulty writing functions with low cohesion_

Is there some definition of cohesion I don't know, or is the author confusing cohesion and coupling?

<comment><USER76> From Wikipedia: "In computer programming, cohesion refers to the degree to which the elements of a module belong together.[1]", where [1] is Yourdon & Constantine 1979.

It appears that author uses cohesion and coupling - and rightly so, by the above definition - as synonyms.

<comment><USER77> Cohesion and coupling certainly are not synonyms.

Cohesion is about how much the code within a _single_ module deals with the same or closely related concerns, so that behaviour "belongs together". High cohesion is usually considered desirable.

Coupling is about how much _multiple_ modules depend on each other. For example, do they communicate only via a clearly defined interface, or do they have implicit dependencies like sharing memory or resources? Loose (i.e., low) coupling is usually considered desirable.

</comment></comment></comment><comment><USER78> Point number 9: "using HN for programming advice or guidance" \- relying on HN with it's fixation on the latest shiny (are we still hyping Go and React today?) and it's endless pursuit of academically useless tools (big shout to Haskell, any meta language built upon yet another interpreted and JITd language).

<comment><USER79> Why would you say Haskell is academically useless?

<comment><USER80> Why would you respond to a troll?

<comment><USER78> They were willing to debate my statements, it seems you prefer to throw labels around in place of a single argument or rebuttal.

<comment><USER42> You're saying things that are not even wrong, from an account created one hour ago with a name clearly tied to the topic. I'd say obvious troll is obvious.

<comment><USER57> A troll you can argue with isn't a troll. Its just too easy to exclude people because of there non-conformism ...

</comment></comment></comment></comment></comment></comment><comment><USER81> > _Using cut-n-paste code from someone else 's program to deal with I/O and > Monads_

> _Failure to implement a linked list, or write code that inserts /deletes > nodes from linked list or tree without losing data_

> _Difficulty seeing through recursion_

I would argue that using monads, implementing your own linked list or using recursion is sign of bad programming... But I am just Java cowboy, so thanks for the enlightenment!

<comment><USER82> > implementing your own linked list or using recursion

I believe I can salvage this piece of the comment, and make it into an intelligent thing to say.

Implementing your own linked lists? Not good unless your language is stone- knives-and-bear-skins land. You need to know what libraries are out there and available to you, and if CS undergrad stuff is unknown to the libraries in your language, pick a different one if you possibly can.

Recursion is an important skill, but implementing your own recursive functions is low-level. It's error-prone and it's boring in precisely the ways that cause errors.

Implementing your own map function is worse than implementing your own linked lists; it's more like implementing your own while loops out of labels and goto statements. It's an invitation to have bugs in your program's flow control, which is the worst possible place for them to be.

Sometimes you need to write your own recursive function, because none of the basic recursive patterns your libraries give you can fit. Sometimes you need to implement your own foundational data structures, too. Both of these should be done with skepticism, primarily of your own code, but also of the very idea that you'd actually _need_ to do it in the first place.</comment></comment>


When They Are Throwing Money At You - <AUTHOR> http://www.avc.com/a_vc/2011/01/when-they-are-throwing-money-at-you.html

<comment><USER2> Awesome post. Sure wish some of that easy VC money existed in Canada. But maybe 3 years from now another bubble will pop and Canada will again fail to notice anything happened.

<comment><USER3> "I have not seen a better time to raise money for web startups since the late 90s."

oh boy...

<comment><USER4> The difference is that it is so cheap to do your own startup that you can do it with or without other people's money. That was not the case 12 years ago.

The second thing is that the rest of the country is in the worst recession in 70 years - if you are not going to put your money in tech, where are you going to put them?

When the recession ends, money will flow out of tech and into the general market, but that is going to take time and is unlikely to be a sudden rush, more of a slow stream.

<comment><USER5> 1.) Price of starting a startup has nothing to do with overvaluation of companies and the corresponding investment into those companies, which defines a bubble. Such as "oh I'm sure that those photo-sharing apps will find a revenue model eventually", etc.

2.) We're in a great depression. Not a run-of-a-mill recession. And "if you are not going to put your money in tech, where are you going to put them?" is precisely what a bubble mentality is.

<comment><USER4> 1) Price has a lot to do with how softly we land. The reason the bubble became as infamous as it did was the aftermath, not so much the bubble.

I am not an economists, but it doesn't seem to be a depression from where I am sitting - people don't walk in thread-bare clothing, nor are there "no help wanted signs".

</comment></comment></comment></comment></comment><comment><USER6> How many people are in the position where they are getting money thrown at them, vs. people who are looking for funding but can't get any?

What does that say about the perspective of the funder vs the perspective of the fundee

<comment><USER7> Do you know how to start a poll?

</comment></comment><comment><USER8> "I've come to believe that entrepreneurs putting away some money to protect the downside is largely a good thing. It allows them to take bigger risks and play for more upside."

One of the best rationales I've encountered to support the recent trend of entrepreneurs selling some of their shares in later funding rounds.

</comment><comment><USER9> Great post. I sometimes (especially recently) get the impression that startups have been playing up overblown valuations as some sort of marketing tactic.</comment>


Adding Extension Methods to PHP - <AUTHOR> http://cdmckay.org/blog/2010/04/23/adding-extension-methods-to-php/

<comment><USER2> As he points out in the article, unlike .NET extension methods, this (clever) technique requires classes to inherit from a special superclass before you can add extension methods to them. If you're able to change a class' inheritance that way, why not add the methods directly to it?

This falls squarely into my "neat idea, no practical use" category, unless someone can enlighten me with a use case...

<comment><USER3> One practical use: you want the core files to be easily upgradable by overwriting over old files, without loosing the customizations.

EDIT: Which means it's useful technique for app developers to allow easy customizations by others.

EDIT2: By example: Magento's framework is able to add or CHANGE existing methods without updating core files, which was one of the strongest reasons for its great success despite various shortcomings.

<comment><USER2> Interesting. Thanks!</comment></comment></comment>


Is It Time To Get Rid Of The Linux OS Model In The Cloud? (2012) - <AUTHOR> http://highscalability.com/blog/2012/1/19/is-it-time-to-get-rid-of-the-linux-os-model-in-the-cloud.html

<comment><USER2> Its certainly worthwhile to experiment with alternatives, but the various levels solve a wide array of problems -- perhaps not in the most efficient way for the cloud, to be sure -- and its not going to be time to get rid of the current model until there's a new model that adequately solves all of those problems that remain relevant in the cloud _and_ provides performance benefits sufficient to outweight the costs of the model _not_ be consistent with the model used elsewhere in computing (reducing, e.g., the utility of shared tooling and experience.)

I think that will probably happen fairly quickly for specialized alternative models for narrow domains (it probably already has -- I think I've seen that there are some in use now, and I'm sure there's more that I haven't heard about that are being used internally in private clouds by actors that don't talk much about what they do inside), but a general purpose replacement for the status quo style of OS stack for the cloud environment seems farther off.

</comment><comment><USER3> Sounds a lot like the direction Erlang on Xen (<http://erlangonxen.org/>) is taking.</comment>


New ceramic with highest melting point of any known substance synthesized - <AUTHOR> https://www.sciencedirect.com/science/article/pii/S0272884220307793?via%3Dihub <comment><USER2> I assume that glass is considered to be a ceramic, and that glass melts. But is it a property of all ceramics that they melt? I would have thought that your typical coffee mug would burn, rather than melt, given high enough temperature. Or is part of the point here that this new ceramic belongs to the subset of ceramics that do in fact melt?</comment>


Create your own chat bot for Facebook and Slack today. No coding required - <AUTHOR> Use Rebotify to create chat bot for Facebook, Slack, WeChat & more. 5 minutes to build and launch your bot. No coding required. Build once, publish anywhere. Your bots work with Facebook, WeChat and Slack simultaneously. Create your own bot today, https://www.rebotify.com. It is free. <comment><USER2> If it is free, how do you sustain your company?

How can I, as a business which integrates with you solution, be sure you are around in 6 months? Why should I spend my time on integrating with that?

<comment><AUTHOR> If your user conversations will hit more than 100,000 per month, please contact us at email@example.com. We have a premium service for you.</comment></comment>


You Cannot Regulate Guns Unless You Know How to Use One - <AUTHOR> https://medium.com/@yishan/you-cannot-regulate-guns-unless-you-know-how-to-use-one-d129d0a82974 <comment><USER2> By that logic, you need to smoke crack before you can make it illegal.

<comment><USER3> You should definitely know how crack is used, it's effects, and how other legal derivatives are used before trying to regulate it, yes.

Otherwise, you may end up banning a large number of cocaine-based anesthetics. Or worse, ban rubbing cocaine in your hair while leaving it legal to smoke it.

This is the state of gun regulation right now -- many of the people trying to ban guns don't seem to know the first thing about guns, making the regulation likely to be ineffective.

<comment><USER4> A better argument would be that you need to know how guns are purchased before trying to regulate them.

<comment><USER3> And how would that work to prevent legislators from banning one of the least dangerous forms of firearms?

<comment><USER4> How does firing a gun tell you how dangerous it is?

The danger of a firearm is most likely a function of its rate of fire, the likelihood that it will kill someone it hits, and not much else. The rate of fire is a simple fact and can be learned without firing the weapon. The deadliness of the gun is probably difficult to know for sure, and it certainly wouldn't be obvious just from shooting it.

For example, is a low-power firearm with hollow-point bullets more dangerous than a high-power firearm? Is a weapon that's easier to aim significantly more deadly, or is that effect irrelevant once rate of fire is considered? I don't know, and shooting guns wouldn't tell me.

<comment><USER3> Firing or handling a gun isn't critical, but it does make it clear the kind of damage different kinds of guns will do to targets. Assembling and disassembling them makes it clear how easy a crude gun is to make at home with a machine shop. Handling it will help you judge how easy it is to conceal it.

And firing a police issue revolver will make it obvious how much harder it is to fire accurately than a regular, civilian issued one (and possibly lead to fixing the policy that ensures officers end up with guns handicapped to endanger bystanders; I'm against police being armed with lethal weapons, but if it's going to happen, I'd like them to at least hit their targets).

> For example, is a low-power firearm with hollow-point bullets more dangerous > than a high-power firearm?

How does knowing how a gun is purchased tell you this? This seems to be another argument _for_ teaching regulators against guns, and not against it.

The simple fact of the matter is that to effectively regulate guns, you need to know about them. The legislation proposed to curb gun violence is (almost invariably) written by people who are very obviously flying blind, and as a result, the laws proposed are the equivalent of banning rubbing cocaine in one's hair while leaving crack smoking legal.

<comment><USER4> To be clear, I don't think either of these arguments (the original, or the one I proposed as "better") are good arguments.

Like cocaine, guns are not that complicated. If lawmakers aren't experts, they can easily have experts review their proposals and inform them.

The core problem with gun-related legislation is that we don't actually know much about gun violence in the US in an epidemiological context. The CDC hasn't been able to keep track of gun violence, and there isn't a good centralized database for it. It could be that everyone having a gun would be safer, and it could be that no one having a gun would be safer. We don't have conclusive data to support either position definitively.</comment></comment></comment></comment></comment></comment></comment>


Ten Ways to Avoid Disaster When Your Web Services Disappear on You - <AUTHOR> http://technologizer.com/2008/10/30/10-ways-to-avoid-emergency-when-your-web-services-disappear-on-you/

<comment><USER2> What would some of the best ways be to go about making an automatic backup system for web services? Are there currently backup systems on the market?</comment>