Every language fixes something - a DiGraph - just for fun
solipsys.co.uk
solipsys.co.uk
Cut the guy some slack. He put the work in and the result is a pretty cool look at how he makes sense of the way various languages interrelate and borrow from each other. There are others showing the way other people think [1] and I hope some of you will try your hand at it.
[1] Personally, I really like the one O'Reilly did a few years back: http://oreilly.com/news/graphics/prog_lang_poster.pdf I suspect I tend to think more linearly than the OP
Still pretty awesome. Why did haskell come about? "Lazy evaluation is cool, yo."
Not the same thing at all.
Hah. I added that edge way back when I was back in college. The "extended" graph was actually crowdsourced on the C2 Wiki, circa 2004, and it's pretty cool to see it here now.
That it has lisp influences and was implemented in Prolog first speaks of the creators of the language, not what it attempted to fix in there. And I seriously doubt that fixing lisp syntax was an objective in the language, especially given Robert Virding, one of the original 3 creators of Erlang, now has his own lisp syntax on top of the BEAM VM as LFE (Lisp Flavored Erlang).
And it's just for fun.
Regardless, I'd be interested in knowing of any problems people have had with handling Japanese.
I'll go change it again to help try to make that clear.
I smell a troll under the bridge.
I mean, for e.g., if I don't care that Python's not OO enough, I don't need to know Ruby, right? Right?!
p.s: in case it's not apparent, I will be using these graphs to justify some laziness on my part :)
In my case, I've been surprised at how much less syntactic overhead Ruby imposes than Python (despite the explicit "end"!), and how much it matters. Compare:
def mouse_clicked
x = mouse_x / @cellsize
y = mouse_y / @cellsize
if @cells[x][y] == :empty
set x, y, :wire
elsif mouse_button == LEFT
set x, y, :empty
else
set x, y, :electron_head
end
end
def mouse_clicked(self):
x = processing.mouse_x() / self.cellsize
y = processing.mouse_y() / self.cellsize
if self.cells[x][y] is Empty:
self.set(x, y, Wire)
elif processing.mouse_button() == processing.LEFT:
self.set(x, y, Empty)
else:
self.set(x, y, ElectronHead)
(Here ElectronHead and the like are assumed to be top-level empty classes in the module; the Ruby equivalent is a Lisp-style atom that doesn't need to be declared.)To me, the Ruby version has a much higher signal-to-noise ratio.
Another thing: JRuby seems to be a lot more mainstream among Rubyists than Jython is among Pythonistas, which I think means it's a bit more solid.
Because they say the same thing, but the Python code is much longer, if you count tokens instead of lines. It has about 28-30 more tokens than the Ruby code does, about three per line. Those tokens don't convey any information. They're just redundancy, i.e. noise. And there are a lot of them; these redundant tokens are something like a third of the code.
Now, redundancy can be useful (see e.g. http://www.paulgraham.com/redund.html) but it is costly, so you should keep it to the minimum that achieves what you want the redundancy to achieve.
I wanted to translate the code to Haskell directly, but the idioms don't map that well (self.cellSize would becomes something else entirely, and the comparison would not be fair).
Here's Life in Dyalog APL, from http://dfns.dyalog.com/c_life.htm and http://news.ycombinator.com/item?id=1041500:
life←{ ⍝ John Conway's "Game of Life".
↑1 ⍵∨.^3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵ ⍝ Expression for next generation.
}
Unfortunately, my APL is pretty rusty, and Dyalog has added some major extensions to the language, so I'm not quite sure what that means, in particular the juxtaposition of 1 and ⍵ toward the beginning. I think it parses as vertically_rolled = outerproduct(⌽, [-1, 0, 1], ⊂(⍵))
horizontally_rolled = outerproduct(⊖, [-1, 0, 1], vertically_rolled)
neighbor_counts = sum(ravel(horizontally_rolled))
↑(⍵(1, innerproduct(and, or, ⍵,
[3, 4] == neighbor_counts)))
but I'm not even sure of that.The Life rule (which is pretty optimal for being expressed in APL, given its array orientation) is slightly simpler than the Wireworld rule:
def run_wireworld_rule
old_cells = @cells
@cells = fresh_cells
each_coord do |x,y|
# This could be optimized somewhat by only recalculating
# the neighbors of dirty cells.
case old_cells[x][y]
when :electron_head
set x, y, :electron_tail
when :electron_tail
set x, y, :wire
when :empty
# do nothing; fresh_cells are all :empty
when :wire
case electron_head_count old_cells, x, y
when 1, 2
set x, y, :electron_head
else
# Don’t call `set` in this case so as not to mark
# the cell dirty for redrawing.
@cells[x][y] = :wire
end
end
end
end
# This could perhaps be optimized somewhat with a sum table.
def electron_head_count(cells, base_x, base_y)
count = 0
([0, base_x-1].max..[base_x+1, @nx-1].min).each do |x|
([0, base_y-1].max..[base_y+1, @ny-1].min).each do |y|
count += 1 if cells[x][y] == :electron_head
end
end
return count
end
def each_coord
(0..@nx-1).each do |x|
(0..@ny-1).each do |y|
yield x, y
end
end
end
The APL people claim that their programs are more readable because they're shorter, but I'm not sure how much I believe their claim. It's certainly true that other kinds of mathematical notation benefit enormously from brevity and consistency that permits mechanical manipulation, and I don't see why algorithms should be different, but empirically I have a lot less trouble with Ruby or Python (or even C) than with plain-English descriptions of mathematical equations.Explicit is better than implicit.
Errors should never pass silently.
Namespaces are one honking great idea -- let's do more of those!
Maybe after I spend more time with Ruby, I'll see the dark side of DSLs, but so far I'm loving it :)
from processing import ... from processing import LEFT, mouse_x, mouse_y, mouse_button
Now you don't have to prefix things with `processing` just like you don't in your Ruby version.It does call fill from four call sites, but that was because there's no reasonable way to return a list of four arguments from a method in Ruby, as far as I can tell.
p, q, r, s = * method_that_returns_array_of_4_things
* aka "splat operator"
Where would it be in the chart? coming off of C or C++?
What problem were they trying to fix?
Everything -> not bundled -> PHP
Perl -> too weird -> PHP
It's hard to explain to a novice that in Perl 4/5, $x[42] dereferences @x, not $x (which are completely separate, except when they're not, due to *x). And PHP has a much more typical object system. I think we agree that most all of PHP's distinctive and non-mainstream design decisions have been bad ones, though.(I don't know how to protect the star from starting an emphasise block. Escaping it doesn't seem to work.)
Sorry to nit-pick, but these may be particularly hard to explain because they're not true.
$x[42] isn't a de-reference at all, but an indexing. (Granted, it's more than a little confusing that it's indexing @x. This is 'fixed' in Perl 6.) $x->[42] is a de-reference, but of $x, not of @x (which isn't a reference anyway (I think unlike in Ruby)). @x and $x are always completely separate; typeglobs allow you to say something like (star)x = \@y, whereupon @x and @y are the same (but still $x and @x are completely different). I suppose you could claim that $x and @x are no longer completely different if you say something like $x = \@x, whereupon $x->[42] and $x[42] mean the same thing.
You're right, "dereference" was a poor choice of words because it means something more specific in Perl. And I think a programmer would need at least a year of experience before they could possibly understand your main paragraph, while PHP was dumbed-down enough to be approachable by amateurs.
… but ends here.
However there is logic in the madness. Perhaps Larry Wall/linguistic logic but none the less it does work! The best explanation i've see is the comment by "Matt S Trout" on devolving-sigils blog post (http://blog.fogus.me/2009/02/26/devolving-sigils/).
Below is the key sentence from mst comment:
Actually, perl sigils don’t denote variable type
– they denote conjugation
– $ is ‘the’, @ is ‘these’, % is ‘map of’ or so
– variable type is denoted via [] or {}.It's been a long time since I listened to the interview, but I think he created PHP to create simple websites. Wikipedia even says the original acronym was "Personal Home Page".
(sorry, couldn't resist :-) )
It should be Turing machines -> Too awkward for modeling programming -> Lisp Lambda calculus -> No typing -> ML -> Not pure -> Haskell ML -> no objects/modules -> Ocaml
b. It's not talking about "developed to replace," it's talking about "was developed in response to a perceived problem."
It wasn't this either. https://secure.wikimedia.org/wikipedia/en/wiki/Javascript#Hi...
I'm just taking the piss anyway, the whole chart is silly. Cheers!
What problem was it trying to fix?
<grin>
Java -> D "But I liked manual memory management."
It's not where it drew it features from, or what its ancestor was, or what's it's most like. It's a question of what caused the developers to create a language, not where they got the new language's feature from.
http://james-iry.blogspot.com/2009/05/brief-incomplete-and-m...
Sensible?
Sensible or not, seems a reasonable interpretation. 8-)
COBOL -> not funny -> INTERCALJust curious - you seem really angry about this.
Let's be honest—some of the descendants are a bit off (Java->Javascript, anyone?), and some languages have multiple inspirations not listed.
It's an interesting idea, and perhaps the starting point of actual research, but isn't yet trustworthy or sensible enough to be taken as gospel.
The page explicitly notes that this is not an inheritance / 'paternity' graph, but rather a description of the (perceived) problems with one language that another language fixes (or tries to).
I don't think there's even any implication that any one language was created in response to any other, just that it shares certain aspects, and removes certain warts.
No, the given reason for Java -> JavaScript is completely wrong. I'd understand if the reason was "Java browser applets suck", but syntax?
In fact, I could have also mentioned myself that the link was taken off the second graph to further my case that it was just plain wrong. The only reason I did not was because I thought it was something so obvious it would not be necessary to state it.