Live data from Hacker News

Make a Lisp

github.com

11–20 of 44 posts

Re: Make a Lisp

#14
post #6

The language statistics ribbon for this is beautiful.

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.

Re: Make a Lisp

#16
post #14
post #6

The language statistics ribbon for this is beautiful.

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.…

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.

Re: Make a Lisp

#17
post #16
post #14

Earlier quoted context omitted.

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.…

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.

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.

Re: Make a Lisp

#20
post #14
post #6

The language statistics ribbon for this is beautiful.

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.…

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.

Post reply on HN