Tom Stuart, a Ruby programmer and author, writes and speaks about functional programming, monads, compilers and declarative programming.
HN commenters recommend his talks as a great way to understand monads and building programs from nothing, and link his posts on logic programming and static typing in Ruby.
To add to other comments, things the author could have expanded upon:
* vararg keyword arguments (kwargs)
* Keyword-only arguments (Python 3)
* help, vars, a few other nice introspective builtins
* Assignment unpacking (multiple names as left-hand side of an assignment)
* The strangest "first blush" difference between Ruby and Python, or at least the one which I found oddest when I first started switching, is that a new Ruby class is defined from the `class {Name}` line, the whole body executes in the context of the already-created class. Not so in Python, the class object will only exist once the body has finished executing.
* No mention of generators? Also outer v inner iteration is a pretty big split between two otherwise similar languages.
Mistake-ish
* obj.__dict__ -> vars(obj)
* obj.__class__ -> type(obj)
* Python's lambdas are not one-line, they're one-expression. The reason you "can't do [this] in Python" is that if:elif:else: is a statement, so doesn't fit in lambdas. But you can have arbitrary complex code in lambdas aside from that, by following http://codon.com/programming-with-nothing. For instance you can (although you should not) write:
map(lambda num:
0 if num % 3 == 0 else
num * 2 if num % 4 == 0 else
num,
range(1, 6))
* Author talks about methods a lot. They're not methods, a method is part of an object. They're functions. Granular functions, inner functions, ...
* We generally don't say Python…
I have a degree in mathematics from the University of Chicago. Want to talk about self-adjoint algebras of compactly supported continuous functions? I'm your man.
I also think teaching this using mathematical notation would be a mistake. People only learn things when they relate in part to something they already know. The original lambda calculus syntax is not only abstract, it was invented before programmable computers existed.
Unless someone is either already comfortable with mathematical notation or has a background in a programming language with similar concepts (Lisp, Haskell, etc.), it's going to be a stretch to teach someone the lambda calculus -- really teach them -- unless it's framed in terms of a language they already know.
JavaScript is a great language to use for this because it has C-like syntax, which virtually all programmers understand, and first-class functions. You could use Ruby, too, but the syntax would be even more opaque.
Here's someone building the lambda calculus using only Procs in Ruby: http://codon.com/programming-with-nothing
Then using Ruby 1.9's "stabbby lambda syntax" you get
-> x { -> f { f[x] } }
Not sure that's any better. The key is explaining it in terms of something the ready already understands well.
If they're not already thinking mathematically a straight-forward introduction to the lambda calculus would be ineffective.
I have some bad news for you (and for Edsger W. Dijkstra, who you would probably be a fan of)- In the "real world" of programming work, you will likely rarely encounter most of those things. Real-world dev is NOT about "computer science proper". (Unless you're building a language from scratch. Which is like 0.01% of all programming work.) You should of course be aware of them and what they do, and when you think you need them you should Google them and learn them then (and of course be able to do so).
Sometimes you need to switch languages- Perhaps you want the "look and feel" of pencil art which you can't do with pen-driven art without A LOT of work.
You can implement immutable data structures in Ruby- for example, see the Hamster gem here https://github.com/hamstergem/hamster - but 1) it is much, much slower, 2) none of the other gem code you will call into will use Hamster 3) you actually have to code differently to Hamster data structures than to the built-in Ruby ones.
Just because you CAN make pencil-art with pens, doesn't mean that's the "happy path."
And just because you can represent every possible computer operation as a series of lambda functions (see "Programming With Nothing" here, great article: http://codon.com/programming-with-nothing) doesn't mean you should.
For me the best introduction to unification was creating a microKanren[1] implementation based on the "Hello, declarative world" article[2], but even just reading the article can help enormously to understand how unification works.
Basically if you have unification then you already have a simple query engine, which can handle simple equality constraints that is usually used in SQL WHERE clauses. For example "select * where pokemon = pikachu" can be simply achieved by such a system.
Of course this only gives a bare bones query engine, so if you want something more advanced then you will need to implement a constraint system on top of this base unification system. cKanren is a good example of such a system.
Few years ago I had the same kind a of curious question about the relationship between databases and logic programming languages like microKanren and as a result I created LogikalDB[3], which is an embedded query language for FoundationDB.
1: http://minikanren.org/
2: https://codon.com/hello-declarative-world
3: https://github.com/MechaRex/logikaldb
I don't think looser typing is the current trend at all. I think the opposite is true: there's a movement towards more typing, particularly among the languages that have traditionally been the most dynamically typed.
- Type hinting is a significant new feature in PHP 7.x: http://php.net/manual/en/migration70.new-features.php
- Python 3.5 introduces type hinting: https://docs.python.org/3/library/typing.html
- Ruby is talking about possibly adding a static typing system to Ruby 3.x (this is very early stage, but there appears to be interest): https://codon.com/consider-static-typing. Also 24 days ago Matz talked about possibly adding type inference to Ruby3x3: https://bugs.ruby-lang.org/issues/9999
- Flow and TypeScript add types to JavaScript.
- JavaScript is adding more structure to its type system with ES6 classes.
- Newer languages such as Swift and Dart are certainly more typed than the Python/Ruby/JavaScript generation.
- Rust is typed to the max.
I guess what I'm saying is that if you like type systems, the future is bright. :)
> from CompSci
Maybe I'm missing something, but I don't see much that I would consider CS. This is an attempt at an engineering-style workaround.
> malware
They explicitly include support for spyware with the mouse{over,out} (etc) events.
> "ADsafe makes it possible to quickly and reliably determine that script is safe"
That's incredibly hard. It's easy to hide arbitrary code even if all you have is a lambda expression[1] ("function () {}" in JavaScript). There are so many sharp corners and inconsistent gotchas in JavaScript - multiplied by the variations between browsers - that identifying a "safe" subset of the language is extremely difficult (or maybe undecidable).
Douglas Crockford has been warned[2] almost a decade ago about the insecurity of mixing foreign JavaScript. The language simply wasn't designed with a security model sufficient for running untrusted code.
[1] https://codon.com/programming-with-nothing
[2] https://www.youtube.com/watch?v=qfBL2sc2zUU