Why don't I metaprogram more?
github.com
github.com
foo.somefield
Versus: foo["somefield"]
And variations on that theme. While it's cute, I guess (you're not type checking anyways so nothing lost, I suppose), I don't really get it.There's a chapter in pg's "On Lisp" about continuation-passing-style transformation (from sequential code to CPS) done with meta-programming. Worth reading, too.
If you're an Emacs user, the source code of EIEIO is a good read. It's an object system implemented on top of Elisp using it's meta-programming capabilities.
In Smalltalk-land the most impressive example of meta-programming is certainly a debugger. You get to inspect the state of objects while they are running, you can modify it, and you can modify method bodies while they are running. Scary stuff.
In Python some nice meta-programming code lives in Django ORM, in Model metaclass, and in Fields. This is the code which allows you to declaratively define your models as classes. Similar code is used in Django Forms.
The talk "Five years of bad ideas" by Armin Ronacher is a 40-minuted tour of some of the most advanced meta-programming available in Python.
In JavaScript every library which implements "classical classes" on top of objects and prototypes uses meta-programming. You can read about it more in depth in Raganwald "the art of javascript meta-object protocol" and his other talks and posts.
Angular.js dependency injection framework is based on meta-programming; actually I had a mixed reaction when I saw the code for this, where they rewrite a user supplied function as a string and compile a new function out of this string. It's a good example of meta-programming, but it's also very crude compared to hygienic macros in Schemes for example. It lives here: https://github.com/angular/angular.js/blob/master/src/auto/i...
Generally, meta-programming is a vast and varied set of techniques. It's worth knowing about them, because most of the time you don't need them, but when you do, you really, really need them very much.
The LISP macros make me jealous. What non-LISP-like languages have macros? Nemerle does and looks fairly neat. It'd seem like somehow passing the AST to user-defined modules would get ya pretty far, but there must be a ton of complications, otherwise more languages would offer it.
I suppose we can consider converting quoted code to another target (like GPU, or database) as metaprogramming. I guess I had filed that under "just reflection".
1. super-easy development of new parsers/compilers (lisp macros)
2. shenanigans with dynamicism and first class functions.
Both of those are cool! But I can't figure out what they have to do with each other, other than that you don't get much of that sort of thing in Java/C.
One nice example of modifying code on the fly I just remembered is goto decorator in Python: http://code.activestate.com/recipes/576944-the-goto-decorato... As for code generation, if I recall correctly, Salt (http://docs.saltstack.com/en/latest/) uses YAML and Jinja2 to generate shell scripts. These are very different techniques, but the thing they have in common is that they manipulate code, which makes them both examples of meta-programming.
At least that's how I understand the term :)
- corporate sponsorship dried up
- it wasn't open source, and by the time squeak came around, usage had dried up considerably
- it was actually too hard to learn
Although, it's unfair to judge it by today's standards. The sheer number of open source programmers just didn't exist when Smalltalk was popular.
You see some vestigial remnants of smalltalk in modern languages (in ruby, everything is an object, dart allows you to snapshot the object memory, the idea of a virtual machine, etc, etc) but having all of them together made smalltalk quite groundbreaking. We haven't really learned all the lessons quite yet, either. (Just my opinion). One of the biggest misunderstandings was that object oriented programming is really about message passing, not about encapsulation.
For more: http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html
Anyway, Smalltalk still exists and not only as an inspiration for Ruby. Pharo and Squeak are very nice image-based environments, VisualWorks has "enterprise grade" support, GNU Smalltalk is small and lightweight and works well for scripts. There is Amber, which tries to recreate Smalltalk image inside the browser and there's (forgot the name) which tries to implement ST on JVM (it was on kickstarter I think). There's also Newspeak, which is highly experimental, and LivelyKernel (by Dan Ingals) which again transplants some of the more important ST ideas into the browser. And all that on top of mainstream languages gaining more and more features which Smalltalkers are used to. It's certainly an interesting time to be a part of Smalltalk community.
class CarsController < ActionController::Base
load_resource
def index
# @cars is defined
end
def show
# @car is defined
end
endA smattering:
http://hackage.haskell.org/package/accelerate https://github.com/mainland/nikola http://hackage.haskell.org/package/esqueleto http://hackage.haskell.org/package/api-tools http://hackage.haskell.org/package/atom http://hackage.haskell.org/package/diagrams http://hackage.haskell.org/package/c-dsl https://hackage.haskell.org/package/js-good-parts http://hackage.haskell.org/package/Bang http://hackage.haskell.org/package/orc
And if you buy that definition, then there is some ungodly metaprogramming available in dependently typed languages.
https://github.com/pigworker/MetaprogAgda/blob/master/notes....
Though, to be clear, there are few who can follows those notes today.
If everything is checked dynamically, does it really make a difference beyond the 3 characters? Sure find_by_userid looks somewhat nicer, for sure. But is that really it? Any examples that aren't trivially replaced by a string param (or two)?
I guess my question is better phased as "Ruby goes on a lot about metaprogramming. I've used .NET reflection quite a bit. What does Ruby's metaprogramming really enable that I'm missing out on?"
And the methods themselves, while verbose and clumsy, are actually fairly transparent and intention-revealing. I understood perfectly what the article author was trying to do and why.
Ruby is expressive enough that you usually don't need it, and when you do need it, the stark stylistic difference between the normal methods and the meta-programming code feels safe and comforting. You see `define_method` or `Class.new` and your brain instantly reads it as magic and start wondering what the hell caused the programmer to start delving into the hard stuff.
You almost never see meta-programming in Ruby where it wasn't needed, and it's almost always limited to solving one or two problems.
In my own brief foray into C#, it wasn't long before I found a problem that, when brought to a more experienced coworker, he solved with reflection. I couldn't remember the details, but I knew that had I had to solve it in Ruby, I'd never need anything like that.
When you're writing code in a vacuum, you can fill it with all the metaprogramming you want. You probably have some preferred style, and your metaprogramming will reflect that. In something like lisp, this gets taken to the extreme -- code can look very different from what traditional lisp looks like when there are macros involved.
While this is great for developing solo, or with a small group, it becomes too much to handle as more people onboard. Every new contributor needs to learn your particular style, and how your macros work, and then how to apply them effectively. Its much easier when new functionality and expressiveness is added through a common format (like adding a new method).
As a lisp fan, those methods feel clumsy to me. But if you want to do something that's so big you need more contributors, it's worth the tradeoff.
template htmlTag(tag: expr) {.immediate.} =
proc tag(): string = "<" & astToStr(tag) & ">"
htmlTag(br)
htmlTag(html)
echo br()
produces: <br>
http://nimrod-lang.org/talk01/slides.htmlThe macros run at compile-time, and emit code by use of the <[ ]> blocks -- those get turned into ASTs at compile-time and get filled with the proper data.
http://docs.julialang.org/en/release-0.2/manual/metaprogramm...
You end up being able to reify the entire Haskell syntax tree from "quoted" fragments, manipulate and generate a modified tree, and then "print" it back into program flow.
Totally capable, but not terrifically fun. It also has some compilation restrictions which are annoying if necessary.
https://github.com/dlthomas/snowdrift/compare/5094b1ca0e5002...
I'm a "mort" line of business apps dev (well not just that, I do lots of other things, but hey). Do I really need to care about metaprogramming, my gut instinct says no because our business and customer requirements change all the time, and unpredictably. And if I was spending time thinking about "meta programming", nothing would get done.
Problem is, once you get it; it's unfathomable that you might not understand it.
But you're right, you don't need to learn anything. Facebook is doing well and it was written in PHP. I hear many popular books were written on typewriters, or even with pen and paper.
http://infraruby.com/blog/ruby-metaprogramming-with-s-expres...