Hacker Timesnew | past | comments | ask | show | jobs | submit | more devinus's commentslogin

This is interesting. Since it's hard to read, I've extracted the language statistics and I'll leave them here:

C# - 7.9% C - 7.2% Rust - 7.1% Visual - Basic - 6.6% Makefile - 6.5% Java - 5.8% Forth - 5.0% Go - 4.5% PostScript - 4.2% Haskell - 4.0% Shell - 3.8% Perl - 3.5% JavaScript - 3.4% Matlab - 3.2% Scala - 3.1% PHP - 3.1% OCaml - 3.0% Lua - 2.8% R - 2.7% Python - 2.7% CoffeeScript - 1.9% Ruby - 1.9% Clojure - 1.9% Scheme - 1.7% CSS - 1.4% Other - 1.1%

It seems you could extrapolate interesting theories regarding productivity using these numbers.

There's a jump between Ruby/CoffeeScript and Python, and I wonder why.


The fact that C# came out with 36% more lines than Java would make me doubt much extrapolation about productivity from these numbers. You can do a token for token substitution of Java and end up with close to compilable C# code; there are only a handful of things Java has that C# doesn't, while C# has many more abstraction tools.


This is just because Java is using `readline` and C# is reimplementing it AFAICT.


I'm willing to bet that most of the Java code could be made shorter with the use of more functional style code in Java 1.8 (which might be why he labeled it "Java 1.7")


Yep. Things like this:

https://github.com/kanaka/mal/blob/master/cs/core.cs#L272

Could easily be turned into one line ... not that any sane person would want to, though.


I was curious about this, so here is the result of my digging.

`core` has inline lambdas in Ruby:

    :prn =>       lambda {|*a| puts(a.map {|e| _pr_str(e, true)}.join(" "))},
but separately defined ones in Python

    def prn(*args):
        print(" ".join(map(lambda exp: printer._pr_str(exp, True), args)))
        return None

    ...

    'prn': prn,
Note that `return None` isn't needed - Ruby doesn't have it, so that's a "wasted" line. The function should also be more like

    def prn(*args):
        print(" ".join(printer._pr_str(exp, True) for exp in args))
or, if Python 2 support wasn't needed,

    def prn(*args):
        print(*(printer._pr_str(exp, True) for exp in args))
Defining these out-of-line is a good idea, though (it improves introspection in Python).

`mal_readline` has a bit of support for Python 2 which takes a few lines, but mostly it's code like

    try:
        with open(histfile, "r") as hf:
            for line in hf.readlines():
                pyreadline.add_history(line.rstrip("\r\n"))
                pass
    except IOError:
        print("Could not open %s" % histfile)
        pass
versus

    File.readlines($histfile).each {|l| Readline::HISTORY.push(l.chomp)}
The Python code handles errors but has two pointless `pass` statements and a couple of odd choices. It should better be:

    try:
        with open(histfile) as hf:
            for line in hf:
                pyreadline.add_history(line.rstrip("\n"))
    except IOError:
        print("Could not open %s" % histfile)
Note that the Python uses lazy reading which is why it needs explicit closing; Ruby likely would too if it read lazily.

I have no idea what's up with `mal_types`/`types`; Ruby does simple stuff and then Python does... something. I will say that the Python can be a lot simpler at minimum, although I'd need to grok what it does before I can say what. For example,

    elif _hash_map_Q(a):
        akeys = a.keys()
        akeys.sort()
        bkeys = b.keys()
        bkeys.sort()
        if len(akeys) != len(bkeys): return False
        for i in range(len(akeys)):
            if akeys[i] != bkeys[i]: return False
            if not equal_Q(a[akeys[i]], b[bkeys[i]]): return False
        return True
can be replaced with

    elif type(a) is Hash_Map:
        return a.keys() == b.keys() and all(equal_Q(val, b[key]) for key, val in a.items())
I think the `_Q` suffix is a the writer missing Ruby's `?`-suffixes on identifiers.

There's also a lot of mess that I think arises because the writer might not be aware that you can make callable objects in Python.

I think in the end it comes down to language experience. My Ruby would probably look as hacky as Joel Martin's Python. I doubt there would be as large a difference if they were both written with the same language familiarity.


I guess it's really hard to be idiomatic in 23 languages.


Python is one of the oldest implementations and I ought to do a another pass through to clean it up sometime.

I'm happy to take pull requests that make an implementation shorter and/or more idiomatic as long as it doesn't change the overall order/flow (and doesn't break any of the tests of course).


Several web services in production right now.


Three things that make the experience of developing in Elixir completely different from Erlang: Tooling, libraries, and actual language features (that aren't just skip deep).

Spend 5 minutes developing an app in Elixir and you'll realize why it's not just "only syntactically different" from Erlang.


I gave credit insofar as language features, hygienic macros and pipe ops are both wins in my book.

Which libraries and tools do you think set Elixir apart? Do you prefer it to erlang (I've seen you in #elixir-lang ;)?


The release can be downloaded from here: https://github.com/elixir-lang/elixir/releases/tag/v0.12.0


if is a macro.


Does Cassandra follow semver[1]?

[1]: http://semver.org/


Short answer: no.

Longer answer: the only guarantee that's carved in stone is that in X.Y.Z is backwards-compatible for all values of Z. Past that YMMV, e.g., typically X.Y+1 will be network-compatible for rolling upgrades, but we'll maintain disk-compatibility for longer.


I've just begun looking into and playing with CoreOS. Basically, it's a minimal Linux image with Docker, service discovery using the `etcd` daemon they've written in Go, and several interesting properties. The most interesting is their use of the ChromiumOS build tools, allowing them to one day update servers the same way e.g. ChromeOS is updated--using the Omaha protocol to push raw binary diffs of the new root FS.


Simple answer: you don't. Longer answer: It depends. Do you want to use yum or apt-get to install programs? If you like CentOS, create a CentOS container with Docker and begin installing programs using yum! Ubuntu? Spool up an Ubuntu container and apt-get away! CoreOS is just the cradle upon which you can run the userland of any distribution you please.


So CoreOS is the simple host OS, thank you for the clarification, i thought it was a minimal guest OS.


You just described the actual draw of CoreOS. CoreOS is just Linux. Instead of going the Xen route you just described, it can capitalize on being just Linux by supporting everything Linux already supports. At this point, you can view CoreOS, which is just Linux, as the "hypervisor." Containers don't have to replicate key subsystems in every paravirtualized instance, as containers share all the same subsystems like e.g. the TCP/IP stack. You're also not throwing away any distribution experience. Want CentOS? Create a CentOS container with Docker. Want Ubuntu? Create an Ubuntu container with Docker. These are incredibly powerful ideas I'm just now being exposed to.


Try telling your SAN vendor that you're running "just Linux" and can you have a driver and support package for that please, and let us know how you get on.

When you're done there, now try plugging your nice new machine into the corporate DC. Oh it seems it needs to support VLAN tagging. No problem, better just write some new code for that.

Time to migrate a bunch of performance sensitive services. Uh oh, no support for FusionIO PCI SSDs! Better write some more code.

Time to migrate your remote sites, only policy dictates certain services must be physically encrypted. No problem, better just cutpaste Debian's cryptsetup scripts and be done with it.

Oops, turns out we deployed 1000 machines with a duff BIOS setting. No problem, I'm sure the server vendor has a support package for CoreOS..

We could come up with examples until we've basically reinvented a modern Redhat/Debian initramdisk and boot environment.


There are certainly environments where enterprisey vendor testing and certification makes sense; mostly small or heterogeneous environments. But at large scale it's cheaper to do stuff yourself.

Also, CoreOS has more of a read-only stateless philosophy, so I think it'd still be interesting even if it ends up having to duplicate a lot of effort from mainstream distros.


That would have been a problem with every new distribution, including RHEL and Debian when they were brand new. In reality, your SAN should be able to accommodate a generic Linux kernel with any userland you can containerize.


Yes, and ideally Microsoft Windows should be open source and IBM OS/360 would have a build supporting Firefox running on my Nexus One, but that's not how the world operates..


Your sarcasm is tedious. If a SAN cannot support a generic Linux kernel, then it's the fault of the vendor for not allocating enough dev hours to the Linux kernel, and their product should not be chosen for a Linux environment.


I'm not sure how else to respond to "let's reinvent a complete Linux distribution because we've written a 20 line auto-updater".

This would have made sense to me a decade ago, but back then I just wouldn't have understood the amount of work involved. You simply cannot produce a fully generalized container OS without producing a fully generalized OS.

That aside, I actually like the central idea of a better approach to managing/updating a large group of host machines. I just don't think it warrants yet another bikeshedded support/security/certifiability nightmare (and lets face it, this is bikeshedding, there's absolutely no value in the core claim of "it's just Linux", but it gives unfettered license to reinvent the same old wheels all over yet again).


Just wanted to add something to this thread, which has not been mentioned yet. Sure, most (if not all) SANs are supported vie generic linux kernel drivers for HBAs, something like a QLogic card, or an exported iSCSI LUN. The issue is that you spent tons of money on the SAN and a truck load of money on hardware and software to hook up to that SAN. So you want to have a vender supported OS to go along with these items. If you have performance issues or stability issues, the first things a vender will ask is, what OS are you running, so they can direct you to the correct support group. The support group will want to debug the issue, so you have to generally run something like RHEL or Windows to get support. This might only be a mega corp issue though, since most startups don't have Oracle/Sybase, fiber channel SANs, etc. To sum this up, in the mega corp world, if you are not running a vender supported OS, you likely cannot get support for your device.


https://groups.google.com/forum/?fromgroups#!topic/elixir-la...

This was José Valim's rationale on the mailing list. Once you understand what's involved, f.() begins to look like a pretty good compromise.


That kind of variable shadowing is a smell. The compiler should warn about it, and/or re-bind the local method as expected (possibly shooting programmer in the foot, but hey... that's why it's a smell, Don't Do It). Forcing an inconsistent syntax to handle one corner case seems like another smell in itself.


Personally I would rather leave the syntax disambiguation to the programmer when relevant, rather than enforcing a single, awkward-looking syntax for all cases.


Its true, but Joe is also correct that this is going to be something people complain about for decades.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: